2016-12-22 9 views
3

というカスタムプロパティを持つgetがあり、それがfieldという識別子を使用していない場合、とにかくバッキングフィールドが生成されることに気付きました。私はバイトコードをチェックし、ドキュメントがようにも述べている:それはアクセサの少なくとも一つの デフォルトの実装を使用して、または カスタム場合場合Kotlin - "計算された" varプロパティの有用性

バッキングフィールドは、プロパティのために生成されますアクセサはフィールド識別子を通じてそれを参照します。
(強調は私です)

は、このようなクラスを考えてみましょう。

class Banana { 
    var ripeness = 1 

    var color: String = "green" 
     get() = when { 
      ripeness > 80 -> "brown" 
      ripeness > 50 -> "yellow" 
      else -> "green" 
     } 
} 

val b = Banana() 
b.color = "blue" 

println(b.color) 

しかし、printlnは常に関係なく、私はcolorへを設定したもの、「緑」印刷されません:それが生成されますvarプロパティ、デフォルトset(したがって、バッキングフィールド)がありますので。とにかくバッキングフィールドは「青」に設定されます。
アクセサーメソッドの外側(またはリフレクションを介して)にアクセスする方法がないため、これは理由を考えることができません。
ここに何か不足していますか?たぶんユースケースやバッキングフィールドにアクセスする別の方法?それとも単なるバグですか(IntelliJの警告がありません)? "計算"

+2

カスタムケースのバッキングフィールドを使用する場合があります。そうしないとバッキングフィールドが役に立たなくなります。私はこれがコンパイラの警告を与えているはずだったと思います。 – marstran

+0

@marstranはい私は警告に同意します。それは最悪のケースですが、すぐに実行できるものがあるので、それ以上のものがあるかもしれないと思いました。 – Lovis

答えて

5

A使用バッキングフィールドを持つvarプロパティがvalプロパティ "計算された" である必要があります。

例でバッキングフィールドを使用しない場合は、Banana.colorvarではなくvalである必要があります。例えば:一方

class Banana { 
    var ripeness = 1 

    val color: String 
     get() = when { 
      ripeness > 80 -> "brown" 
      ripeness > 50 -> "yellow" 
      else -> "green" 
     } 
} 

、あなたが実際にいくつかのケースでは、あなたの「計算された」プロパティをオーバーライドしたかったならば、あなたが実際にバッキングフィールドを使用する必要があります。例:

class Banana { 
    var ripeness = 1 

    var color: String = "green" 
     get() = when { 
      ripeness > 80 -> "brown" 
      ripeness > 50 -> "yellow" 
      else -> field 
     } 
} 
+0

はい、私はそれを 'val'と宣言しなければならないことを知っています。私はちょうど初心者が容易に入り込むかもしれないトラップだと思っていたので、とにかくそれを許可する正当な理由があると思った。 – Lovis

関連する問題