Help us understand the problem. What is going on with this article?

【val?var?】KotlinのプロパティのJavaからの見え方【isEnabledの名前は?】

More than 3 years have passed since last update.

はじめに

本投稿ではJavaとKotlinの相互運用において、

「Kotlinのクラスで定義したプロパティが、Javaからどのように見えるのか、呼び出すことができるのか」

を紹介します。まず

  • Getterのみ
  • SetterとSetterの両方

が生成される場合があることを説明し、次に生成されるSetterとGetterの名前について説明します。

Getterのみができるのか?GetterとSetter両方ができるのか?

次のようなKotlinのPersonクラスを用意します。

Personクラス
class Person(val name:String, var age:Int)

Kotlinでの利用例はこんな感じですね

  • valで定義したnameは書き換えることができません。値or参照の取得のみが可能です。
  • varで定義したageは書き換えることができます。値or参照の取得・設定両方が可能です。
PersonクラスのKotlinでの利用例
val person = Person("Ryota", 27)
println(person.name)
println(person.age)

// 下記はコンパイルエラー
// person.name = "RyotaMurohoshi"
person.age = 28

println(person.name)
println(person.age)

さて、このPersonクラスをJavaから使った場合どのように利用できるでしょうか?Javaでの利用例を下記に示します。

Person person = new Person("Ryota", 27);
System.out.println(person.getName());
System.out.println(person.getAge());

// 下記はコンパイルエラー
// person.setName("Super Ryota");
person.setAge(28);

System.out.println(person.getName());
System.out.println(person.getAge());
  • valで定義したnameはGetterのみが利用できました。getNameメソッドですね。
  • varで定義したageはGetterとSetter両方が利用できました。getAgeメソッド、setAgeメソッドですね。

まとめると

  • valで定義したプロパティは、JavaではGetterのみが作られ利用できる
  • varで定義したプロパティは、JavaではGetterとSetterが作られ両方が利用できる

ですね。

どのような名前のGetter・Setterが作られるのか

ではどのような名前のGetterとSetterが生成されるのでしょう?

原則

先ほどのKotlinのageというプロパティは、

  • GetterはgetAge
  • SetterはsetAge

が生成されました。

原則のルールは次のとおりです。

xxxという名前のプロパティは

  • getXxx
  • setXxx

というアクセサが生成されます。ただしvalの場合はSetterは生成されません。

isXxxというKotlinのプロパティ

KotlinではBoolean型のプロパティにisXxxという名前を使うと思います。さて、これが先ほどの原則ルールに適用されたとします。Javaからはどう利用できるでしょうか。もし、先ほどの原則ルールに則るならば、

isXxxというプロパテには

  • getIsXxx
  • setIsXxx

というような形になるのでしょうか?不自然なGetterとSetterですね。

では、実際のコードで見てみましょう。次のようにisXxxという名前のプロパティがあるクラスを作ります。

KotlinのKData0クラス
class KData0(var isEnabled:Boolean, var isValid:String)

このKotlinのクラスをJavaから使ってみます。

KData0クラスをJavaから利用する
KData0 kData0 = new KData0(true, "xxxxx");            

System.out.println(kData0.isEnabled());
System.out.println(kData0.isValid(););

kData0.setEnabled(true);
kData0.setValid("fffff");

isEnabledというプロパティでは、

  • isEnabledというGetter
  • setEnabledというSetter

ができました。

isValidというプロパティでは、

  • isValidというGetter
  • setValidというSetter

ができました。

まとめると、ixXxxというプロパティは、

  • isXxxというGetter
  • setXxxというSetter

ができます。

まとめると、isXxxというプロパティは原則ルールと違うルールが適用され、Javaとして自然なGetter・Setterが生成されます。

ちなみに、Boolean型以外でisXxxというプロパティ名は利用しないと思います。しかし、isXxxというプロパティはBoolean型以外でもこのルールでGetter・Setterが生成されます。

is_xxxというKotlinのプロパティ

Java・Kotlinの命名規則としては正しくはないかもしれませんが、is_xxxという名称のプロパティはどのようにJavaから利用できるでしょうか。

KotlinのKData0クラス
class KData1(var is_enabled:Boolean, var is_valid:String)

このKotlinのクラスをJavaから使ってみます。

KData1クラスをJavaから利用する
KData1 kData1 = new KData1(true, "xxxxx");

System.out.println(kData1.is_valid(););
System.out.println(kData1.is_enabled());

kData1.set_enabled(true);
kData1.set_valid("fffff");

is_enabledというプロパティでは、

  • is_enabledというGetter
  • set_enabledというSetter

ができました。

is_validというプロパティでは、

  • is_validというGetter
  • set_validというSetter

ができました。

まとめると、ix_xxxというプロパティは、

  • is_xxxというGetter
  • set_xxxというSetter

これも、Boolean型以外のis_xxxというプロパティ名でもこのルールが適用されます。

その他は?

hasXxxというプロパティはどうでしょうか?

これは、

  • getHasXxx
  • setHasXxx

という原則ルールが適用されるようです。

そしてisxxxというプロパティは

  • getIsxxx
  • setIsxxx

と、こちらも原則ルールが適用されるようです。

どうやら、プロパティ名がキャメルケース・スネークケースで区切られていて先頭がisの場合に、例外ルールが適用されるようですね。

さいごに

KotlinはJavaとの連携を非常に大事にしています。
この投稿では、Kotlinで作ったクラスのプロパティが、JavaからはGetter・Setterとして利用できるのですが、そのルールと例を紹介しました。

Kotlinのクラスのvarで作ったプロパティは、JavaからはGetter・Setterの両方が利用できます。
Kotlinのクラスのvalで作ったプロパティは、JavaからはGetterのみが利用できます。

また、Kotlinのクラスのxxxという名前のプロパティはJavaからはgetXxxやsetXxxというアクセサが利用できます。(setXxxはvarのみ)
一方で、KotlinのクラスのisXxxという名前のプロパティはJavaからはisXxxやsetXxxというアクセサが利用できます。(setXxxはvarのみ)

さて最後に問題です。

class Data(var isXxx:String, var xxx:String)

というクラスはコンパイルエラーになります。理由はなんでしょうか?

このクラスをJavaから見たとき、どのようなアクセサが利用できるか考えてください。

isXxxプロパティは

  • isXxx
  • setXxx

ですね。

xxxプロパティは

  • getXxx
  • setXxx

ですね。

setXxxという名前が衝突しているため、コンパイルエラーになるのです。

さてこの投稿とは逆に、JavaのアクセサをKotlinからプロパティ形式で利用できます。それはまた、別の機会で。

参考コードは、こちら

関連

【Kotlin】BooleanフィールドはisXXXという命名が推奨されている

RyotaMurohoshi
プログラミングが大好きで、 C#が大好きで、 .NETが大好きで、 LINQが大好きで、 JVM言語が大好きで、 ゲームで遊ぶことが大好きで、 ゲーム開発が大好きで、 頑張るのが大好きで、 Unityが大好きだったから...!
http://mrstar-memo.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away