2017-03-07 82 views
1

目前性能我有一個​​3210:@JvmField對通用/抽象類

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); 

但是,我真的很喜歡,如果我能有那些在科特林:

float f = v.x; 

v.x = f; 

的問題是@JvmField不允許abstract和性能,但如果切換Vec2t到:

open class Vec2t<T : Number> { 

    @JvmFiled open var x: T // error 

屬性必須被初始化或抽象

​​

無效既不:

@JvmField不能應用於委託物業

,如果我試圖將其初始化:

@JvmField open var x = 0 as T 

@JvmField只能被應用到最終性能

有我一個機會,我不知道的?

回答

2

作爲@JvmField是用Java直接訪問,我們不能耍花樣像一個委託初始化,並且不能將其標記爲lateinit要麼。這也是爲什麼它不能得到抽象或開放財產的支持;如果您在Java的類中有float x;,那麼它可以直接訪問,並且不能以任何方式攔截對其的讀/寫,而所有上述功能都需要。

你試圖解決的問題是關於創造有效的值初始化它們。有一兩件事你可以做的是將它們標記爲可爲空和intialize他們作爲null,但我認爲這將直接違揹你正在尋找的便利性(可能的表現,因爲他們會現在已經被盒裝),我只是想我會提到這是可能的。

這一切說的是,你基本上是堅持你的解決方案之一,或者它是否適合你的使用情況,我建議從構造函數的參數intializing他們:

​​

這種方式你您的價值標記爲@JvmField s,並且可以直接從兩種語言訪問它們,並且它們在創建時具有真正的價值。

更新:

下面是一個較短的版本(由@mfulton26):

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

謝謝zsmb,它看起來很完美! – elect

+1

這'Vec2t'實現可以通過將被簡化了'@ JvmField'屬性直到構造:'抽象類Vec2t (@JvmField VAR X:T,@JvmField VAR Y:T)'。 – mfulton26

+0

哦,對,我不知道爲什麼我沒有這樣做,這很整潔。固定在讓我們猜想他們在班級體內。 – zsmb13

0

@JvmField指示Kotlin編譯器不要爲此屬性生成getters/setter,並將其作爲字段公開,因此如果它是字段,將無法覆蓋它。

對於你的情況,你需要這樣的事:

abstract class Vec2t<T : Number> { 
    @JvmField 
    var x: T 

    @JvmField 
    var y: T 
} 
+0

>屬性必須被初始化或抽象 – elect