Slide 1

Slide 1 text

Annotations specific to the Java platform. 2017.08.22 夏のKotlin LT祭 @tebasakyu

Slide 2

Slide 2 text

自己紹介 ● 鈴木 誠 (Makoto Suzuki) ○ 娘: 遙華(Haruka) 5ヶ月 ● Monstar Lab, Inc. ● Android Engineer ● Twitter: @tebasakyu

Slide 3

Slide 3 text

Annotations 公式リファレンス https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/index.html#annotations ● Javaとの相互運用には欠かせないもの ○ 100%Kotlinなら不要 ○ KotlinからJavaへの優しさ

Slide 4

Slide 4 text

● JvmField ● JvmMultifileClass ● JvmName ● JvmOverloads ● JvmStatic ● JvmSuppressWildcards ● JvmSynthetic ● JvmWildcard ● PurelyImplements ● Strictfp ● Synchronized ● Throws ● Transient ● Volatile これで全部です。

Slide 5

Slide 5 text

● JvmField ● JvmMultifileClass ● JvmName ● JvmOverloads ● JvmStatic ● JvmSuppressWildcards ● JvmSynthetic ● JvmWildcard ● PurelyImplements ● ● ● Throws ● ● これだけ書きました。

Slide 6

Slide 6 text

● JvmField ● JvmMultifileClass ● JvmName ● JvmOverloads ● JvmStatic ● JvmSuppressWildcards ● JvmSynthetic ● JvmWildcard ● PurelyImplements ● ● ● Throws ● ● よく使いそうなのはこの辺りですね。

Slide 7

Slide 7 text

● JvmField ● ● JvmName ● JvmOverloads ● ● JvmSuppressWildcards ● ● ● ● ● ● Throws ● ● 今日はこの辺りを話します。

Slide 8

Slide 8 text

@JvmName ● クラス名、メソッド名にJavaからの実行用別名をつける View.kt @file:JvmName("View") package com.xxx.extensions fun View.toVisible() { this.visibility = View.VISIBLE }

Slide 9

Slide 9 text

MainActivity.java ViewKt.toVisible(textView); textView.setVisibility =View.GONE; MainActivity.java View.toVisible(textView); textView.setVisibility = android.view.View.GONE; ● @JvmName無しの場合 拡張関数の命名規則を”com.xxx.extentions.<拡張元クラス名>”などとしている場合、 下手に別名を付けると面倒なこともある。

Slide 10

Slide 10 text

@JvmOverloads ● デフォルト値付き引数を持つメソッドのオーバーロードを生成 する @JvmOverloads fun hoge( bool: Boolean = false ) { } 生成されたJavaコード public void hoge() { hoge(false) } // アノテーションを付けないと出てこない。 public void hoge(boolean bool) { } // 無しの場合はこちらだけ。

Slide 11

Slide 11 text

@JvmSuppressWildcards ● ジェネリクスのワイルドカードを利用不可にする interface Foo class Bar: Foo { fun hoge(list: List<@JvmSuppressWildcards Foo>) { } } ■Javaから実行する new Bar().hoge(new ArrayList()); // OK new Bar().hoge(new ArrayList()); // NG (Barは extends Foo>だから)

Slide 12

Slide 12 text

@Throws ● Kotlinから検査例外を明示させる ○ Kotlinは検査例外が無いので、try-catchを強制できない class Hoge { @Throws(IOException::class) fun fuga() { throw IOException() } } ■Javaから実行 hoge.fuga(); // コンパイルエラー(「try-catchしなさい」)

Slide 13

Slide 13 text

相互運用せざるをえない人たちも居ます。 そんな人たちに出会ったとき、これらのアノテーションを思い出し てあげてください。 きっと救われます。

Slide 14

Slide 14 text

ご静聴、ありがとうございましました。

Slide 15

Slide 15 text

以下、時間内に収まらなかったもの。

Slide 16

Slide 16 text

@JvmField ● プロパティアクセスを可能にする ○ 通常はgetter/setterを介してアクセスさせる class data { @JvmField val hoge = "fuga" // プロパティアクセス可 val fuga = "hoge" // getFuga() / setFuga() でアクセスする }

Slide 17

Slide 17 text

@JvmStatic ● JavaからStatic呼び出しを可能にする companion object { @JvmStatic fun newInstance() : MainFragment = MainFragment() } ■Javaから実行 アノテーションあり:MainFragment.newInstance(); アノテーションなし:MainFragment.Companion.newInstance();

Slide 18

Slide 18 text

@JvmMultifileClass ● 複数ファイルにまたがって同一の”JvmName”を利用する Hoge.kt @file:JvmName("Util") @JvmMultifileClass package com.xxx fun hoge() { }

Slide 19

Slide 19 text

Fuga.kt @file:JvmName("Util") @JvmMultifileClass package com.xxx fun fuga() { } MainActivity.java com.xxx.Util.hoge(); com.xxx.Util.fuga();

Slide 20

Slide 20 text

@JvmWildcard ● ジェネリクスのワイルドカードをつける ○ List → List extends String> ○ 不要な場合(finalなど)、デフォルトでワイルドカード無しに なる fun foo(l: List) // in Java: List (String is final) fun foo(l: List<@JvmWildcard String>) // in Java: List extends String> 引用元:https://goo.gl/ETK3Sm

Slide 21

Slide 21 text

@PurelyImplements ● Java側がKotlinのために付ける(っぽい) ● 型パラメータをプラットフォーム型にしない @PurelyImplements("kotlin.collections.MutableList") public class MyPureList extends AbstractList { ... } ■Kotlinから実行 MyPureList().add(null) // NG アノテーション無しだとOKになってしまう MyPureList().add(null) // OK

Slide 22

Slide 22 text

@JvmSynthetic ● 公式に説明が無い ● stack overflowで「I advice to not using it in normal "user" code.」と言われている。 ○ https://goo.gl/Z1CSy