java で書かれたandroid アプリに kotlin を適用させていく
TRANSCRIPT
Java で書かれたAndroid アプリに
Kotlin を適用させていく
2017/11/18DevFest Shikoku 2017@徳島大学
辰濱健一
自己紹介
•辰濱健一(たつはまけんいち)• 徳島県生まれ、神山町在住
• GDG Shikoku スタッフ
• Sansan 株式会社、名刺アプリ Eight のアプリ開発
• Twitter:@tatsuhama50
• Facebook:kenichi.tatsuhama
2
Sansan株式会社 神山ラボ
3
Kotlin とは?
Kotlin とは
5
• JetBrains 社が開発しているプログラミング言語
• JVM 上で動作する言語で、Java と完全に相互互換がある
• Google I/O 2017 にて、Android の開発言語に選定
Kotlin とは
6
• JetBrains 社が開発しているプログラミング言語
• JVM 上で動作する言語で、Java と完全に相互互換がある
• Google I/O 2017 にて、Android の開発言語に選定
だけじゃない!
Kotlin とは
7
• Native iOS Support
• Web Apps (Ktor)
• Multiplatform Projects
Kotlin とは
8
• Native iOS Support
• Web Apps (Ktor)
• Multiplatform Projects
もう、Kotlin は Android だけじゃない。サーバも Web も iOS も Kotlin で書ける!
Kotlin の特徴
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
10
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
11
Null 安全
• 型で 「null 不許容型」「null 許容型」が分かれる• Java の String は null 許容型
• → 「 null でない」という状態が型ではわからない
•
• 例)String の場合• null 許容型:String?
• null 不許容型:String
12
Null 安全
13
• null が来ないことが確実であれば…Java
Kotlin
Null 安全
• 型で null を許容するか否かを表現できる
• NullPointerException がなくなるわけではない!• 例)Kotlin の関数を Java から呼び出す
• Kotlin の定義が non-null でも、Java から null を渡すことができてしまう…
• → support annotation を付けておこう。
14
Java でも IDE が認識して、null チェックの必要性を判断してくれます
Java
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
15
型の省略
16
Java
Kotlin
Kotlin
※型推論に時間が掛かるので、
型を書いた方が、コンパイルが速い
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
17
ラムダ式
• ラムダ式• 関数の宣言なしに、関数オブジェクトを生成できる
18
Java
Kotlin
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
19
Data class
• モデルクラスでおなじみの関数を自動生成• 各 getter, setter, equals, hashCode, …
20
Kotlin
Java
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
21
拡張関数
• 他のクラスに関数を付け加えることができる
22
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
23
便利なコレクション関数
• filter:絞り込み
• map:変換
• sum() :合計
24
Kotlin の特徴
• Null 安全
• 型の省略
• ラムダ式
• data class
• 拡張関数
• 便利なコレクション関数
• デフォルト引数
25
デフォルト引数
• 指定しなかった引数のデフォルト値を指定できる
26
既存のAndroid アプリに適用させていく
Java プロジェクトへ Kotlin を!
• プロジェクト内に Kotlin を部分導入可能(ファイル単位)
• Android Studio の Java to Kotlin コンバータが便利
• Java からの見え方を知っておく
• Java → Kotlin するタイミング
28
Java プロジェクトへ Kotlin を!
• プロジェクト内に Kotlin を部分導入可能(ファイル単位)
• Android Studio の Java to Kotlin コンバータが便利
• Java からの見え方を知っておく
• Java → Kotlin するタイミング
29
Kotlin の部分導入(ファイル単位)
• 同じパッケージ内に java ファイルと kt ファイルの共存が可能
30
Kotlin
Java
Java
Kotlin
Java
Kotlin の部分導入(ファイル単位)
• 1つの Java ファイル内の関数を切り出して、Kotlin で記述するという方法も…
31
Java
Java
Kotlin
切り出し
呼出
Java プロジェクトへ Kotlin を!
• プロジェクト内に Kotlin を部分導入可能(ファイル単位)
• Android Studio の Java to Kotlin コンバータが便利
• Java からの見え方を知っておく
32
Convert to Kotlin
33
Convert to Kotlin
34
Java
Kotlin
Convert to Kotlin
•だいぶ Converter も賢くなってきた
•とはいえ、まだまだ過信してはいけない• Converter が判断できない部分は手直しが必要
• そのままビルドが通とは限らない
• 実行時エラーになることも
35
変換後のエラー
• 例)Parcelable な Model
36
Java
変換後のエラー
37
Convert to Kotlin 後の手直し
• 必要があれば、nullable → non-null に(String? → String)
• モデルクラスであれば、 data class に
他にも…
• var(書き換え可能な変数) → val (書き換え不可な変数) に
• Kotlin の言語機能(コレクション関数など)に置き換える
38
Java プロジェクトへ Kotlin を!
• プロジェクト内に Kotlin を部分導入可能(ファイル単位)
• Android Studio の Java to Kotlin コンバータが便利
• Java からの見え方を知っておく
• Java → Kotlin するタイミング
39
実行時エラー
40
CREATOR が見つからない???
Java からの見え方に配慮を
• 100% Java と互換性があるとはいえ、Java からの見え方やコンバート結果は気をつけておく必要がある
• 例)Kotlin にしかない拡張関数も Java から使えて呼べる
→ どうやって Java から呼ぶ??
41
Java からKotlin ファイルは
どう見える?
Java からKotlin ファイルは
どう見える?
これを知っておけば、Java と Kotlin が混在しても怖くない!!
みてみよう
• Android Studio Tools > Kotlin > Show Kotlin Bytecode
44
みてみよう
45
KotlinKotlinBytecode
みてみよう
46
KotlinKotlinBytecode
to Java
みてみよう
47
Java
プロパティ
48
JavaKotlin
var プロパティはsetter / getterが生成されている
val なら getter のみ
プロパティの呼び出し方
49
Kotlin
Java
※public field へのアクセスに見えるが、 getter 経由になっている
Non-null 型
50
JavaKotlin
Non-null 型の実現はJava から見ると、アノテーションでの宣言とnull 例外にすぎない!
non-null の Java からの見え方
• アノテーションの付与でしかないので、警告しか出せない
• → コンパイル&実行できて、実行時エラー
51
static 関数の見え方
52
KotlinJava
static なCompanion 子クラス内に関数が生成される
static 関数の呼び出し方
53
Kotlin
Java※Companion オブジェクト経由の呼び出しになる
static 関数&変数の見え方の制御
54
Java
• 全ての呼び出し元に Companion をつけなければいけない。。。
• Parcelable なオブジェクトは クラス.CREATOR がある前提(このままでは、クラス.Companion.CREATOR になり、機能しない)
Static 関数の見え方の制御
• @JvmStatic アノテーションCompanion を経由しない static 関数呼び出しを可能にする
55
Book.staticFunction() でアクセス可能
static 変数の見え方の制御
• @JvmField アノテーションCompanion を経由しない static 変数呼び出しを可能にする
56
Parcelable なオブジェクトのCREATOR フィールドには@JvmField 付与必須!
拡張関数の見え方
57
Kotlin
Java拡張関数は、XXKt クラスの static 関数として出力される
拡張関数を呼び出す
58
Java
Kotlin
※第一引数は拡張関数が生えているクラスのインスタンス
デフォルト引数の見え方
59
Kotlin
Java
Java から見えるfunction(String):引数1つは存在しない・・・!?
デフォルト引数の関数を呼ぶために
• @JvmOverloads アノテーション
デフォルト引数なしの関数のオーバロード関数を生成する
60
@JvmOverloads の付与
61
Kotlin Java
Java からの見え方
まとめ
Java からの見え方
63
項目 Java からの見え方
プロパティ getter / setter
non-null @NotNull アノテーションnull 時に例外を throw する関数
Static 関数 Companion オブジェクト経由呼び出しor @JvmStatic の付与
Static 変数 Companion オブジェクト経由呼び出しor @JvmField の付与
拡張関数 XXXKt.function(reciver) 形式での呼び出し
デフォルト引数 @JvmOverloads の付与
Java プロジェクトへ Kotlin を!
• プロジェクト内に Kotlin を部分導入可能(ファイル単位)
• Android Studio の Java to Kotlin コンバータが便利
• Java からの見え方を知っておく
• Java → Kotlin するタイミング
64
Java → Kotlin するタイミング
• 基本的に大きな機能修正をする場合に行う(Kotlin 変換だけのリファクタはほぼしない。開発&テストされる機会に変換する)
• する場合も、1ファイルごとに動作確認しながら
• Java ファイルの数行の編集なら、Java で書く(レビューコストがかさまないように)
• モデルクラスは、触るタイミングで Kotlin に移行しても安心(機能がシンプル、レビューも容易)
※新規コードは全て Kotlin で書いています
65
Java → Kotlin の例
• 例)Parcelable なオブジェクト
66
Java
Kotlin
Java → Kotlin の例
• 例)Parcelable なオブジェクト
67
Java
Kotlin
↓エラー修正
Java → Kotlin の例
• 例)Parcelable なオブジェクト
68
ちゃんと Java から見えるように
Java → Kotlin の例
• 例)Parcelable なオブジェクト
69
↓Kotlin の機能を使う(Single Expression)
Java → Kotlin の例
• 例)Parcelable なオブジェクト
70
まだ長い…さらに、Kotlin の機能を使うと…!
Java → Kotlin の例
• 例)Parcelable なオブジェクト
71
これだけ(実質2行)で OK !
※まだ Experimental な Kotlin Extensions の @Parcelize を使っています
Java からの見え方を意識すれば、
Kotlin のプロジェクト投入も怖くない!
Let’s enjoy Kotlin