【Android】Kotlin導入するためにやったこと（学習編）

自プロダクトにKotlin導入するために個人的にやった学習方法の紹介です。（LT用資料も兼ねてます）
[【Android】Kotlin導入するためにやったこと（説得編）](https://qiita.com/rkowase/items/a2f26c64c60d04d51c94)の続きになります。

## はじめに
あくまで個人的にやった内容なので、このやり方が必ずしもベストというわけではないです。

---

## 学習の流れ
1. :movie_camera: I/O '17のKeynoteを見て**モチベを高める**
1. :book: Kotlin入門までの助走読本を読む
1. :book: 公式リファレンスをざっと読む
1. :pencil: Java to Kotlinを試す
1. :pencil: Kotlin to Javaを試す
1. :muscle: Kotlinを書いてみる

---

## :movie_camera: I/O '17のKeynoteを見て**モチベを高める**
まずはGoogle I/OのKeynoteを見てモチベを高める。

![](https://qiita-image-store.s3.amazonaws.com/0/123122/419d1803-720f-20b7-92a8-a8d2a7954e62.png)
（引用） https://youtu.be/Y2VF8tmLFHw?t=1h27m25s

## :pencil: [Kotlin入門までの助走読本(PDF)](https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view) を読む

これを読むだけでKotlinの言語的特徴、Javaとの違い、Kotlin移行時のメリット・デメリットなどが分かるので必読です。
80ページ程度、かつ日本語なのでサクッと読めます。
![](https://qiita-image-store.s3.amazonaws.com/0/123122/8d816d14-7e7c-4021-9be7-1278f05f328d.png)
（引用） https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view の1ページ目

---

以下、目次引用 & 整形
>
* 第 1 章 Kotlin について知る
    * 1.1 Kotlin とは
    * 1.2 Kotlin を使うと何が嬉しいのか
    * 1.3 Kotlin の特徴
    * 1.4 将来の展望
    * 1.5 導入事例
* 第 2 章 Kotlin を学ぶ
    * 2.1 環境構築から HelloWorld まで
    * 2.2 Kotlin の味見
    * 2.3 Java から Kotlin への移行
* 第 3 章 次のステップ
    * 3.1 学習方法
    * 3.2 コミュニティ
    * 3.3 次回リリースの予告

---

## [公式リファレンス](https://kotlinlang.org/docs/reference/) をざっと読む
公式リファレンスを読むことで基本的な文法やイディオムなどが分かります。

![](https://qiita-image-store.s3.amazonaws.com/0/123122/45b33ea8-0057-f2af-6963-0369363a4e3a.png)
https://kotlinlang.org/docs/reference/

---

## :pencil: Java to Kotlinを試す
Javaファイルを開いている状態でメニューの`Code` > `Convert Java File to Kotlin File`からKotlinに変換できます。

![](https://qiita-image-store.s3.amazonaws.com/0/123122/05c720c5-a385-7aaa-d523-dde546edec13.png)

---

### テストコードをKotlinに変換してみる

```java
// Java
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() {
        assertEquals(4, 2 + 2);
    }
}
```
```kotlin
// Kotlin
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        assertEquals(4, (2 + 2))
    }
}
```

---

### ActivityをKotlinに変換してみる

```java
// Java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
```
```kotlin
// Kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
```

---

## :pencil: Kotlin to Javaを試す
`tools` > `Kotlin` > `Show Kotlin Bytecode`
![](https://qiita-image-store.s3.amazonaws.com/0/123122/1a947abf-250f-d1a1-d0c8-c62584f7b499.png)

`Decompile`ボタン押下
![](https://qiita-image-store.s3.amazonaws.com/0/123122/c8125f23-7daa-e090-5d48-936f42bac832.png)

---

### KotlinのdataクラスをJavaに変換してみる

```kotlin
// Kotlin
data class User(var name: String, var age: Int)
```
```java
// Java
public final class User {
   @NotNull
   private String name;
   private int age;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.name = var1;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public User(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
      this.age = age;
   }

   @NotNull
   public final String component1() {
      return this.name;
   }

   public final int component2() {
      return this.age;
   }

   @NotNull
   public final User copy(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      return new User(name, age);
   }

   // $FF: synthetic method
   // $FF: bridge method
   @NotNull
   public static User copy$default(User var0, String var1, int var2, int var3, Object var4) {
      if((var3 & 1) != 0) {
         var1 = var0.name;
      }

      if((var3 & 2) != 0) {
         var2 = var0.age;
      }

      return var0.copy(var1, var2);
   }

   public String toString() {
      return "User(name=" + this.name + ", age=" + this.age + ")";
   }

   public int hashCode() {
      return (this.name != null?this.name.hashCode():0) * 31 + this.age;
   }

   public boolean equals(Object var1) {
      if(this != var1) {
         if(var1 instanceof User) {
            User var2 = (User)var1;
            if(Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}
```

---

## :muscle: Kotlinを書いてみる

### https://try.kotlinlang.org/ をやってみる
ブラウザでKotlinの文法などを手軽に学べます。
![](https://qiita-image-store.s3.amazonaws.com/0/123122/00fb1927-64f8-46a0-8abb-a4c3e5f6bd58.png)

---

### とりあえずJavaっぽく書いてIDEの変換に任せる

まず書いてみると

![](https://qiita-image-store.s3.amazonaws.com/0/123122/a0ac845e-63b2-9c3d-09ee-0e2a2ec85a32.png)
↑`return`でWarningが出てる :warning: 

---

`Option + Enter` (`Alt + Enter`)を押すととIDEが教えてくれるので押してみると
![](https://qiita-image-store.s3.amazonaws.com/0/123122/4b4291fe-b60d-5516-154c-711c739d4ff4.png)

---
**シッュ**となる（Kotlinらしくなる）

```kotlin
fun increment(num: Int): Int = num + 1
```

（再掲）シュッとなる前

```kotlin
fun increment(num: Int): Int {
    return num + 1
}
```

単一の式からなる関数定義は`return`を省略できる

---

ちなみに戻り値の型が自明なときは型も省略できる


```kotlin
fun increment(num: Int): Int = num + 1
```
:arrow_down: 

```kotlin
fun increment(num: Int) = num + 1
```

---
もう一つ例を挙げると`if`文も**シュッ**と書ける場合があります。

```kotlin
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
```
:arrow_down: シュッ（`if`は式なので代入できる）


```kotlin
var max: Int = if (a > b) {
    a
} else {
    b
}
```
:arrow_down: シュッ（三項演算子っぽくも書ける）

```kotlin
var max: Int = if (a > b) a else b
```

---

### 慣れてきたらコーディング規約やベストプラクティスに沿って書く
[FRESH!のコーディング規約](https://github.com/openfresh/android-kotlin-style-guide)は可読性を重視した規約になっているのでとても参考になります。
また、[Idiomatic Kotlin. Best Practices.](https://blog.philipphauer.de/idiomatic-kotlin-best-practices/)というベストプラクティス集もオススメです。

---

## 継続的に勉強するために
- コミュニティに参加する
  - Kotlin勉強会: https://connpass.com/search/?q=kotlin
- 情報発信する
  - 記事を書いたり発表してみる
- Podcastを聞く
  - [Talking Kotlin](http://talkingkotlin.com/)というPodcastがあります。（英語）
- フルKotlinでアプリを作ってみる

---

## まとめ
- [Kotlin入門までの助走読本(PDF)](https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view) や [公式リファレンス](https://kotlinlang.org/docs/reference/) を読んで**基本文法などを学ぶ**。
- Java to Kotlinを試して**Kotlinの場合どう書くかを知る**。
- 実際にKotlinを書いてみて**IDEの力を使いながら慣れる**。

---

## 補足
今回Jvmアノテーションについては言及しませんでしたが、既存のJavaプロダクトに導入していく際はJavaからどう見えるかを意識しつつ書く必要もあります。
Kotlinを学ぶという目的だけであれば、フルKotlinでアプリを作ってみるのが個人的にはオススメです。

---

## 参考
Latest Posts – Talking Kotlin
http://talkingkotlin.com/

Reference - Kotlin Programming Language
https://kotlinlang.org/docs/reference/

A multi-language Hello | Try Kotlin
https://try.kotlinlang.org


kotlin-prior-learning-book.pdf - Google Drive
https://drive.google.com/file/d/0Bylpznm149-gTGRjOFRkWm9PODg/view

【Android】Kotlin導入するためにやったこと（説得編） - Qiita
https://qiita.com/rkowase/items/a2f26c64c60d04d51c94

【Android】KotlinからJavaへ変換（デコンパイル）する手順 - Qiita
https://qiita.com/rkowase/items/8965bac34804e5e737fa