Kotlin @泛型/抽象类的属性上的JVM字段
目前我有一个: 或 当然,Java的默认设置是:Kotlin @泛型/抽象类的属性上的JVM字段,kotlin,Kotlin,目前我有一个: 或 当然,Java的默认设置是: float f = v.getX(); 或 我写了一些具体的东西来减轻“压力”: 这样我就“只能”: 或 但是,如果我能像Kotlin一样拥有这些,我还是很乐意的: 或 问题是@JvmField不允许在abstract属性上使用,但是如果我将Vec2t切换到: open class Vec2t<T : Number> { @JvmFiled open var x: T // error @JvmField只能应用于最终属
float f = v.getX();
或
我写了一些具体的东西来减轻“压力”:
这样我就“只能”:
或
但是,如果我能像Kotlin一样拥有这些,我还是很乐意的:
或
问题是@JvmField
不允许在abstract
属性上使用,但是如果我将Vec2t
切换到:
open class Vec2t<T : Number> {
@JvmFiled open var x: T // error
@JvmField只能应用于最终属性
我是否有可能不知道?@JvmField指示Kotlin编译器不要为此属性生成getter/setter并将其作为字段公开,因此如果它将是字段,则不可能覆盖它 对于您的案例,您需要以下内容:
abstract class Vec2t<T : Number> {
@JvmField
var x: T
@JvmField
var y: T
}
抽象类Vec2t{
@JvmField
变量x:T
@JvmField
变量y:T
}
由于在Java中直接访问@JvmField
,因此我们不能使用诸如委托之类的复杂操作进行初始化,也不能将其标记为lateinit
。这也是为什么它不能由抽象或开放的属性支持;如果你有float x
在Java中的一个类中,它是直接访问的,并且您不能以任何方式截取对它的读/写操作,这是上述所有功能所需要的
您试图解决的问题是在创建时使用有效值初始化它们。您可以做的一件事是将它们标记为可空,并将它们初始化为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)
>属性必须初始化或抽象。感谢zsmb,它看起来很完美!这个
Vec2t
实现可以通过将@JvmField
属性直接放在构造函数中来简化:抽象类Vec2t(@JvmField var x:T,@JvmField var y:T)
。哦,对了,我不知道为什么我没有做那一步,那要整洁得多。我想我已经习惯于把它们放在班级里了。
float f = v.getX();
v.setX(f);
fun x(x: T) {
this.x = x
}
fun y(y: T) {
this.y = y
}
float f = v.x();
v.x(f);
float f = v.x;
v.x = f;
open class Vec2t<T : Number> {
@JvmFiled open var x: T // error
@JvmField open var x by Delegates.notNull<T>()
@JvmField open var x = 0 as T
abstract class Vec2t<T : Number> {
@JvmField
var x: T
@JvmField
var y: T
}
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)
abstract class Vec2t<T : Number>(@JvmField var x: T, @JvmField var y: T)