gpt4 book ai didi

kotlin - @JvmField 通用/抽象类的属性

转载 作者:行者123 更新时间:2023-12-02 13:39:26 24 4
gpt4 key购买 nike

目前我有一个 abstract class :

abstract class Vec2t<T : Number> {    

abstract var x: T
abstract var y: T
...
}

还有很多实现,比如this one :

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>()

现在,我的愿望是在 Java 中拥有与 Kotlin 相同的访问行为,即:

val f = v.x

v.x = f

当然,Java 的默认值是:

float f = v.getX();

v.setX(f);

我通过编写特定的 access funtions 以某种方式减轻了“压力” :

fun x(x: T) {
this.x = x
}
fun y(y: T) {
this.y = y
}

这样我就可以“只”:

float f = v.x();

v.x(f);

但是,如果我能像在 Kotlin 中那样拥有这些,我真的很乐意:

float f = v.x;

v.x = f;

问题是 @JvmField 不允许用于 abstract 属性,但是如果我将 Vec2t 切换为:

open class Vec2t<T : Number> {

@JvmFiled open var x: T // error

property must be initialized or abstract

    @JvmField open var x by Delegates.notNull<T>()

也无效:

@JvmField cannot be applied to delegate properties

如果我尝试初始化它:

    @JvmField open var x = 0 as T

@JvmField can only be applied to final properties

我有没有意识到的机会?

最佳答案

由于 @JvmField 是在 Java 中直接访问的,我们不能用任何像委托(delegate)这样棘手的东西来初始化,也不能将它标记为 lateinit。这也是为什么它不能由抽象或开放属性支持的原因;如果您在 Java 的类中有 float x;,它会被直接访问,并且您无法以任何方式拦截对其的读/写,而这是上述所有功能所需要的。

您要解决的问题是在创建时使用有效值初始化它们。您可以做的一件事是将它们标记为可为空并将它们初始化为 null,但我认为这将直接违背您正在寻找的便利性(可能还有性能,因为它们现在必须装箱),我只是想我会提到这是可能的。

这就是说,您基本上只能使用一种解决方案,或者如果它适合您的用例,我建议从构造函数参数中初始化它们:

abstract class Vec2t<T : Number> constructor(_x: T, _y: T)  {

@JvmField
var x: T = _x

@JvmField
var y: T = _y

}

class Vec2(x: Float, y: Float) : Vec2t<Float>(x, y)

通过这种方式,您可以将您的值标记为 @JvmField,并且可以直接从两种语言访问它,并且它们在创建时被初始化为真实值。

更新:

这是一个较短的版本(作者 @mfulton26 ):

abstract class Vec2t<T : Number>(@JvmField var x: T, @JvmField var y: T)

关于kotlin - @JvmField 通用/抽象类的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42646452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com