はじめに
本投稿ではJavaとKotlinの相互運用において、
「Kotlinのクラスで定義したプロパティが、Javaからどのように見えるのか、呼び出すことができるのか」
を紹介します。まず
- Getterのみ
- SetterとSetterの両方
が生成される場合があることを説明し、次に生成されるSetterとGetterの名前について説明します。
Getterのみができるのか?GetterとSetter両方ができるのか?
次のようなKotlinのPersonクラスを用意します。
class Person(val name:String, var age:Int)
Kotlinでの利用例はこんな感じですね
- valで定義したnameは書き換えることができません。値or参照の取得のみが可能です。
- varで定義したageは書き換えることができます。値or参照の取得・設定両方が可能です。
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という名前のプロパティがあるクラスを作ります。
class KData0(var isEnabled:Boolean, var isValid:String)
このKotlinのクラスを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から利用できるでしょうか。
class KData1(var is_enabled:Boolean, var is_valid:String)
このKotlinのクラスを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からプロパティ形式で利用できます。それはまた、別の機会で。
参考コードは、こちら。