覆盖 Kotlin 类中的变量的 get 方法?

huangapple go评论110阅读模式
英文:

Overriding get method for variable in class kotlin?

问题

以下是你提供的代码翻译后的部分:

// 原始 Java 类
public class VideoAssets implements Serializable {
    @SerializedName("type")
    @Expose
    String type;

    // ...

    public String getHls() {
        hls = Macros.INSTANCE.replaceURl(hls);
        return hls;
    }

    // ...
}

// 转换后的 Kotlin 数据类
data class VideoAssets(
    @SerializedName("mpeg")
    @Expose
    var mpeg: List<Mpeg> = emptyList(),
    @SerializedName("hls")
    @Expose
    var hls: String,
    @SerializedName("widevine")
    @Expose
    val wideVine: WideVine? = null
) : Serializable

// 尝试的非数据类方法
class VideoAssets(
    @SerializedName("mpeg")
    @Expose
    var mpeg: List<Mpeg> = emptyList(),
    @SerializedName("hls")
    @Expose
    val hlsUrl: String? = null,
    @SerializedName("widevine")
    @Expose
    val wideVine: WideVine? = null
) : Serializable {
    val hls: String? = hlsUrl
        get() = field?.let { Macros.replaceURl(it) }
}

请注意,由于你已经明确要求只返回翻译好的部分,我已将详细的解释和指导性内容删除。如果你有进一步的问题或需要更多帮助,请随时提问。

英文:

I have a model class in Java which I converted to data class in kotlin

public class VideoAssets implements Serializable {

@SerializedName(&quot;type&quot;)
@Expose
String type;

@SerializedName(&quot;mpeg&quot;)
@Expose
List&lt;Mpeg&gt; mpeg = null;

@SerializedName(&quot;hls&quot;)
@Expose
String hls;

@SerializedName(&quot;widevine&quot;)
@Expose
WideVine wideVine;

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public List&lt;Mpeg&gt; getMpeg() {
    return mpeg;
}

public void setMpeg(List&lt;Mpeg&gt; mpeg) {
    this.mpeg = mpeg;
}

public String getHls() {
    hls = Macros.INSTANCE.replaceURl(hls);
    return hls;
}

public void setHls(String hls) {
    this.hls = hls;
}

public WideVine getWideVine() {
    return wideVine;
}

public void setWideVine(WideVine wideVine) {
    this.wideVine = wideVine;
}
}

As you see I want to change the value of variable hls when I retrieve it.

I created the data class as below

data class VideoAssets(@SerializedName(&quot;mpeg&quot;) @Expose
                   var mpeg: List&lt;Mpeg&gt; = emptyList(),
                   @SerializedName(&quot;hls&quot;)
                   @Expose
                   var hls: String,
                   @SerializedName(&quot;widevine&quot;)
                   @Expose
                   val wideVine: WideVine? = null) : Serializable

I am struggling here as how should I update the get method for data class.
After searching and taking reference from Override getter for Kotlin data class
I even created a non data class which doesn't seem to work

class VideoAssets(@SerializedName(&quot;mpeg&quot;) @Expose
              var mpeg: List&lt;Mpeg&gt; = emptyList(),
              @SerializedName(&quot;hls&quot;)
              @Expose
              val hlsUrl: String? = null,
              @SerializedName(&quot;widevine&quot;)
              @Expose
              val wideVine: WideVine? = null) : Serializable {
val hls: String? = hlsUrl
    get() = field?.let { Macros.replaceURl(it) }

}

Whenerver I try to retrieve videoAssets.getHls() it returns null while it should return the new value. The object videoAssets.gethlsUrl() has the value but not `videoAssets.getHls()' is always null.

Can someone point me what I am missing?

答案1

得分: 1

这是您的代码:

val hls: String? = hlsUrl
    get() = field?.let { Macros.replaceURl(it) }

所做的是创建一个名为 hls 的属性,并为它创建一个后备字段(变量)称为 field。初始时,它将 field 设置为传递到构造函数中的 hlsUrl 值(可能为 null)。

getter 代码获取 field 的值,如果它不为 null,则调用 replaceURl 函数并返回结果,否则返回 null。

因此,如果将 hlsUrl 设置为 null,则 field 将始终为 null,hls getter 将始终返回 null。即使稍后更新了 hlsUrl(我假设您会这样做,如果我将值传递给构造函数,代码对我来说可以正常运行),field 的值在初始化时就已固定。

另外,您的 Java 代码运行方式不同 - 当获取 hls 的新值时,它会存储该值并在下一个 get 的函数调用中使用它。您从未更改 field 的值,因此您的 Kotlin 代码每次都使用初始值。

从技术上讲,由于您始终在实际上调用 hlsUrl?.let { Macros.replaceURl(it) },您不需要后备字段。在这种情况下,您可以将 hlsUrl 声明为变量并对其进行更新,或者您可以为 hls 属性添加一个 setter,在获取新值时设置后备字段。

这是有关属性的 Kotlin 页面,以防您还没有看过它!

英文:

Here's your code:

val hls: String? = hlsUrl
    get() = field?.let { Macros.replaceURl(it) }

So what this is doing, is creating a property called hls and giving it a backing field (a variable) called field. It initially sets that to whatever value for hlsUrl was passed into the constructor (might be null).

The getter code takes that value for field, and if it isn't null it calls that replaceURl function and returns the result, otherwise it returns null.

So if you set hlsUrl to null, field will always be null and the hls getter will always return null. Even if you update hlsUrl later (whicb I'm assuming you're doing, the code runs fine for me if I pass in a value to the constructor) the value of field is fixed at initialisation.

Also your Java code runs differently - when that gets the new value of hls, it stores that and uses it in the function call of the next get. You're never changing the value of field so your Kotlin code uses the initial value every time.

Technically you don't need the backing field since you're always effectively calling hlsUrl?.let { Macros.replaceURl(it) }. In that case you could make hlsUrl var and update that, or you can add a setter to your hls property and set the backing field when you get the new value

Here's the Kotlin page on properties, in case you haven't seen it!

huangapple
  • 本文由 发表于 2020年9月23日 17:05:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/64024532.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定