Upgrade to Pro — share decks privately, control downloads, hide ads and more …

解剖Kotlin ~バイトコードを読み解く~

yagi
March 09, 2017

解剖Kotlin ~バイトコードを読み解く~

Kotlinの特徴的な機能としてnull許容型や関数型や拡張関数などがよく取り沙汰されます。null安全だとか高階関数で簡潔に記述だとか拡張関数便利最高といった話は枚挙に暇がありません。確かに言語機能としていろいろとJavaに比べて便利なのは分かるんだけど、でもまぁ別にJavaを使っていてクリティカルに困っているわけではないしな〜学習コストとかチームへの導入コストを考えるとそこまで旨味を感じられるわけでもないしな〜みたいなそんな気分。わかります。

本セッションではKotlinのコードをコンパイルして得られるJavaバイトコードを、可読化したりデコンパイルする事によって、Kotlinの特徴的な言語機能がJavaでどのように表現されているかを読み解いていきます。これによりKotlinが肩代わりしてくれるボイラープレートコード群を明らかにします。Kotlinを使うことで省略できたボイラープレートコードが可読性をどのように高め、設計に影響を与えるのかについても言及します。

yagi

March 09, 2017
Tweet

More Decks by yagi

Other Decks in Technology

Transcript

  1. ɹɹɹղ๤
    dόΠτίʔυΛಡΈղ͘d
    %SPJE,BJHJ
    3PPNd
    5PTIJIJSP:BHJ

    View full-size slide

  2. "CPVU.F
    w 5PTIJIJSP:BHJ !TZTZBHJ

    w DPPLQBE
    w "OESPJEΤϯδχΞ ٕज़෦௕

    View full-size slide

  3. ,PUMJO΍ͬͯ·͔͢ʁ

    View full-size slide

  4. +BWBʹൺ΂ͯศརͳͷ͸෼͔ΔΜͩ
    ͚ͲɺͰ΋·͊ผʹ+BWBΛ࢖͍ͬͯ
    ͯΫϦςΟΧϧʹࠔ͍ͬͯΔΘ͚Ͱ
    ͸ͳ͍͠ͳʙֶशίετͱ͔νʔϜ
    ΁ͷಋೖίετΛߟ͑Δͱͦ͜·Ͱ
    ࢫຯΛײ͡ΒΕΔΘ͚Ͱ΋ͳ͍͠ͳʙ

    View full-size slide

  5. w ,PUMJOίϯύΠϥ͕ੜ੒ͨ͠+BWBόΠτίʔ
    υͰಡΉ͜ͱͰɺ,PUMJO͕ߦͬͯ͘ΕΔ࢓ࣄ
    Λཧղ͢Δ
    w ,PUMJOΛॻ͘ͱ͖ʹɺ+BWBͩͱͲ͏ͳͬͯ
    ͍Δ͔ΠϝʔδͰ͖ΔΑ͏ʹͳΔɻࣗ෼Ͱ֬
    ೝͰ͖ΔΑ͏ʹͳΔ
    w ,PUMJOΛ࢖͏͜ͱͰলུͰ͖ͨϘΠϥʔϓϨʔ
    τίʔυ͕ՄಡੑΛͲͷΑ͏ʹߴΊɺઃܭʹ
    ӨڹΛ༩͑Δͷ͔ʹ͍ͭͯΠϝʔδ͕༙͘
    ຊηογϣϯͷ໨త

    View full-size slide

  6. ࠷ऴతʹ
    ײͯ͡΄͍͜͠ͱ

    View full-size slide

  7. ͋ɺͳʔΜͩ
    +BWBʹ͢Δͱ
    ͜Μͳײ͡ͳͷ͔

    View full-size slide

  8. ,PUMJO
    ؆୯ศར͡ΌΜ

    View full-size slide

  9. ,PUMJO
    ΍ͬͯΈΔ͔ʙ

    View full-size slide

  10. w ,PUMJOͷಛఆͷݴޠػೳʹ͍ͭͯ
    ؆୯ʹղઆ͢Δ
    w ͦͷݴޠػೳΛ࢖ͬͨίʔυΛσ
    ίϯύΠϧ͠ɺ݁ՌΛಡΉ
    w +BWBͰॻ͘ͱ͖ͱൺ΂ͯԿΛ΍ͬ
    ͯ͘Ε͍ͯΔ͔ΛݟΔ
    ຊηογϣϯͷΞϓϩʔν

    View full-size slide

  11. σίϯύΠϧͷํ๏

    View full-size slide

  12. σίϯύΠϧͷํ๏

    View full-size slide

  13. σίϯύΠϧͷํ๏

    View full-size slide

  14. σίϯύΠϧͷํ๏

    View full-size slide

  15. w OVMMڐ༰ܕ
    w ؔ਺ܕͱϥϜμࣜ
    w ֦ுؔ਺
    w ϓϩύςΟ
    ΞδΣϯμલฤ

    View full-size slide

  16. w ઃܭʹ༩͑ΔӨڹ
    w OVMMڐ༰ܕ
    w ֦ுؔ਺
    ΞδΣϯμޙฤ

    View full-size slide

  17. w OVMMڐ༰ܕ͸Ҿ਺΍ม਺΍໭Γ஋͕ɺ
    OVMMʹͳΓಘΔ͔Ͳ͏͔Λ໌ࣔతʹએݴ
    ͢Δػೳ
    OVMMڐ༰ܕͱ͸Կ͔
    val name:String? = null
    ܕͷ຤ඌʹ Λ͚ͭΔ͜ͱͰએݴͰ͖Δ

    View full-size slide

  18. w ҰํͰඇOVMMܕ͸OVMMΛ୅ೖͰ͖ͳ͍ɻ
    ม਺΍Ҿ਺΍໭Γ஋͕ඇOVMMܕͳΒɺ஋
    ͕ඞͣඇOVMMͰ͋Δ͜ͱΛอূ͢Δ
    OVMMڐ༰ܕͱ͸Կ͔
    val name:String = "Hello" // OK
    val name:String = null // Error
    fun toString() :String
    ໭Γ஋͕ඇOVMMͰ͋Δ͜ͱΛอূ͢Δ

    View full-size slide

  19. w OVMMڐ༰ܕ͸ͦͷ··ૢ࡞Ͱ͖ͳ͍
    OVMMڐ༰ܕͱ͸Կ͔
    str.length
    ίϯύΠϧΤϥʔʹͳΔ

    View full-size slide

  20. w OVMMڐ༰ܕʹରͯ҆͠શͳݺͼग़͠ͱة
    ݥͳݺͼग़͠Λબ୒͢Δ
    OVMMڐ༰ܕͱ͸Կ͔
    // nullͳΒԿ΋͠ͳ͍
    str?.length
    // nullͷ৔߹NullPointerException
    str!!.length

    View full-size slide

  21. w Ҿ਺΍໭Γ஋ΛඇOVMMܕʹ͢Δ͜ͱͰؔ
    ਺಺Ͱ͸ؔ৺ࣄʹूதͰ͖Δ
    OVMMڐ༰ܕͱ͸Կ͔
    fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    ؔ਺಺ͰWJFX͕ඇOVMMͰ͋Δ͜ͱΛอূ͢Δ

    View full-size slide

  22. w OVMMͷڥքͰҧ൓͕͋ΔͱίϯύΠϥ͕
    ڭ͑ͯ͘ΕΔ
    OVMMڐ༰ܕͱ͸Կ͔
    val text: View? = findViewById(R.id.text)
    semitransparent(text)
    5ZQFNJTTNBUDIͰίϯύΠϧΤϥʔ

    View full-size slide

  23. w ةݥͳݺͼग़͠͸ةݥͳͷͰ௚͢΂͖
    ͱ͍͏͜ͱ͕Θ͔Δ
    OVMMڐ༰ܕͱ͸Կ͔
    val text: View? = findViewById(R.id.text)
    semitransparent(text!!)
    ةݥͳݺͼग़͠ɻཁվળͷγάφϧ

    View full-size slide

  24. w ةݥͳݺͼग़͠͸ةݥͳͷͰ௚͢΂͖
    ͱ͍͏͜ͱ͕Θ͔Δ
    OVMMڐ༰ܕͱ͸Կ͔
    val text: View? = findViewById(R.id.text)
    text?.let { semitransparent(it) }
    OVMM͡Όͳ͚Ε͹࣮ߦɻ

    View full-size slide

  25. OVMMڐ༰ܕ͸+BWBͰ
    ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

    View full-size slide

  26. val nonNull: String = ”nonNull”
    nonNull.length

    View full-size slide

  27. val nonNull: String = ”nonNull”
    nonNull.length
    String nonNull = “nonNull";
    nonNull.length();
    +BWBʹͳΔ͚ͩ

    View full-size slide

  28. val nullable: String? = null
    nullable?.length

    View full-size slide

  29. val nullable: String? = null
    nullable?.length
    String nullable = (String)null;
    if(nullable != null) {
    nullable.length();
    }
    OVMMνΣοΫ͕௥Ճ͞ΕΔ

    View full-size slide

  30. nullable!!.length

    View full-size slide

  31. nullable!!.length
    if(nullable == null) {
    Intrinsics.throwNpe();
    }
    nullable.length();
    OVMMͳΒྫ֎Λεϩʔ

    View full-size slide

  32. fun length(text: String)
    = text.length

    View full-size slide

  33. Ҿ਺͕OVMMͳΒྫ֎Λεϩʔ
    public final int length(@NotNull String text) {
    Intrinsics.checkParameterIsNotNull(text, “text");
    return text.length();
    }
    fun length(text: String)
    = text.length

    View full-size slide

  34. w ͳΒOVMMνΣοΫΛ௥Ճ͢Δ
    w ͳΒOVMMνΣοΫͱྫ֎ͷεϩʔΛ௥Ճ
    ͢Δ
    w ؔ਺ͷҾ਺͕ඇOVMMܕͳΒࣄલ৚݅ͷ
    νΣοΫΛ௥Ճ͢Δ
    w ཁ͢ΔʹOVMMνΣοΫ͕ඞཁͳͱ͜Ζʹ
    OVMMνΣοΫΛࣗಈͰࠩ͠ࠐΜͰ͘ΕΔ
    OVMMڐ༰ܕ͕΍͍ͬͯΔ͜ͱ

    View full-size slide

  35. ؔ਺ܕɺϥϜμࣜ

    View full-size slide

  36. w ϑΝʔετΫϥεΦϒδΣΫτɻؔ਺Λ
    ม਺ʹ୅ೖͨ͠Γɺؔ਺ͷҾ਺ʹͨ͠
    Γɺ໭Γ஋ʹͨ͠ΓͰ͖Δ
    ؔ਺ܕͱ͸Կ͔
    val onClick: (View) -> Unit
    Ҿ਺ʹ7JFXΛडऔΓɺ໭Γ஋͸ͳ͍ؔ਺Λද͢

    View full-size slide

  37. w ߴ֊ؔ਺Λهड़Ͱ͖Δ
    ؔ਺ܕͱ͸Կ͔
    fun calc(
    a: Int,
    b: Int,
    op: (Int, Int) -> Int
    ): Int {
    return op(a, b)
    }

    View full-size slide

  38. ϥϜμࣜͱ͸Կ͔
    calc(1, 2, { a, b -> a + b })
    *OU *OU
    *OUܕΛͦͷ৔Ͱهड़Ͱ͖Δ
    w ؔ਺Ϧςϥϧɻؔ਺ܕͷ࣮૷Λࣜͱ͠
    ͯهड़Ͱ͖Δ

    View full-size slide

  39. ؔ਺ܕͱϥϜμࣜ
    listOf(1, 2, 3)

    .filter { it % 2 == 0 }

    .map { it * 2 } // 4
    w ڧྗͳॲཧΛ؆ܿʹهड़Ͱ͖Δ

    View full-size slide

  40. ؔ਺ܕͱϥϜμࣜ͸+BWBͰ
    ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

    View full-size slide

  41. val onClick: (View) -> Unit

    View full-size slide

  42. val onClick: (View) -> Unit
    @NotNull
    private final Function1 onClick;
    ਖ਼֬ʹ͸'VODUJPO7JFX 6OJU

    View full-size slide

  43. public interface Function1
    : Function {
    public operator fun invoke(p1: P1): R
    }
    'VODUJPO͸ͨͩͷΠϯλϑΣʔε
    ؔ਺ܕ͸Ҿ਺ͷ਺ʹԠͯ͡
    'VODUJPO/ʹม׵͞ΕΔ

    View full-size slide

  44. calc(1, 2, { a, b -> a + b })

    View full-size slide

  45. calc(1, 2, { a, b -> a + b })
    calc(1, 2, (Function2)null.INSTANCE);

    View full-size slide

  46. calc(1, 2, { a, b -> a + b })
    calc(1, 2, (Function2)null.INSTANCE);
    ίϯύΠϥ͕ϥϜμࣜΛ੩తͩͱ൑அͨ͠৔߹͸
    γϯάϧτϯͷΫϥεΛੜ੒͢Δ

    View full-size slide

  47. final class call$1
    extends kotlin.jvm.internal.Lambda
    implements Function1 {
    public call$1() {
    super(2);
    }
    public final int invoke(int a, int b) {
    return a + b;
    }
    public final static $call$1 INSTANCE
    = new call$1();
    }
    खಈͰ௚͢ͱ͜Μͳײ͡

    View full-size slide

  48. final class call$1
    extends kotlin.jvm.internal.Lambda
    implements Function1 {
    public call$1() {
    super(2);
    }
    public final int invoke(int a, int b) {
    return a + b;
    }
    public final static $call$1 INSTANCE
    = new call$1();
    }
    -BNCEBΛܧঝ

    View full-size slide

  49. final class call$1
    extends kotlin.jvm.internal.Lambda
    implements Function1 {
    public call$1() {
    super(2);
    }
    public final int invoke(int a, int b) {
    return a + b;
    }
    public final static $call$1 INSTANCE
    = new call$1();
    }
    Ҿ਺ͷ਺Λ਌Ϋϥεʹ౉͢
    -BNCEBΛܧঝ

    View full-size slide

  50. final class call$1
    extends kotlin.jvm.internal.Lambda
    implements Function2 {
    public call$1() {
    super(2);
    }
    public final int invoke(int a, int b) {
    return a + b;
    }
    public final static $call$1 INSTANCE
    = new call$1();
    }
    Ҿ਺ͷ਺Λ਌Ϋϥεʹ౉͢
    'VODUJPOΛ࣮૷
    -BNCEBΛܧঝ

    View full-size slide

  51. final class call$1
    extends kotlin.jvm.internal.Lambda
    implements Function1 {
    public call$1() {
    super(2);
    }
    public final int invoke(int a, int b) {
    return a + b;
    }
    public final static $call$1 INSTANCE
    = new call$1();
    }
    Ҿ਺ͷ਺Λ਌Ϋϥεʹ౉͢
    γϯάϧτϯ
    'VODUJPOΛ࣮૷
    -BNCEBΛܧঝ

    View full-size slide

  52. val seed = 10
    calc(1, 2, { a, b -> a + b + seed })

    View full-size slide

  53. val seed = 10
    calc(1, 2, { a, b -> a + b + seed })
    final byte seed = 10;
    calc(1, 2, (Function2)(new Function2(2) {
    public final int invoke(int a, int b) {
    return a + b + seed;
    }
    }));
    Ϋϩʔδϟͷ৔߹͸ແ໊ΫϥεΛੜ੒͢Δ

    View full-size slide

  54. var seed = 10
    calc(1, 2, { a, b -> seed++; a + b })

    View full-size slide

  55. var seed = 10
    calc(1, 2, { a, b -> seed++; a + b })
    final IntRef seed = new IntRef();
    seed.element = 10;
    calc(1, 2, (Function2)(new Function2(2) {
    public final int invoke(int a, int b) {
    int var3 = seed.element++;
    return a + b;
    }
    }));
    Ωϟϓνϟͨ͠ม਺Λมߋ͢Δ৔߹͸
    3FGΫϥε͕࢖ΘΕΔ

    View full-size slide

  56. w ؔ਺ܕΛҾ਺ͷ਺ʹԠͨ͡'VODUJPO/Πϯλ
    ϑΣʔεʹม׵͢Δ
    w ϥϜμࣜΛɺ-BNCEBΛܧঝͯ͠'VODUJPO/Λ
    ࣮૷͢ΔΫϥεʹม׵͢Δ
    w ϥϜμࣜͷத਎ʹΑͬͯ࠷దͳίʔυΛੜ੒͢Δ
    w جຊతʹ͸SFUSPMBNCEB΍KBDLͳͲͰͷ+BWB
    ϥϜμࣜαϙʔτͱಉ͡Α͏ͳΞϓϩʔνͰؔ਺
    ܕΛ࣮ݱͯ͘͠ΕΔɻࠩ෼ͱͯ͠͸Ϋϩʔδϟ͕
    ͪΐͬͱॊೈͱ͍͏͘Β͍
    ؔ਺ܕɺϥϜμ͕ࣜ΍͍ͬͯΔ͜ͱ

    View full-size slide

  57. w طଘͷΫϥεʹରͯ͠৽͍ؔ͠਺Λ௥Ճ
    Ͱ͖Δػೳ
    ֦ுؔ਺ͱ͸Կ͔
    fun Int.reversed(): Int {
    return toString().reversed().toInt()
    }

    View full-size slide

  58. w ର৅ͷΫϥεͷΠϯελϯε͔Β௥Ճ͠
    ͨؔ਺Λݺͼग़ͤΔΑ͏ʹͳΔ
    ֦ுؔ਺ͱ͸Կ͔
    334017.reversed() // 710433

    View full-size slide

  59. w ৑௕ͳॲཧΛ֦ுؔ਺ʹ·ͱΊͨΓɺ
    ੹຿Λ௥Ճͨ͠ΓͰ͖Δ
    ֦ுؔ਺ͱ͸Կ͔
    context.getSystemService(Context.WINDOW_SERVICE)
    as WindowManager

    View full-size slide

  60. w ৑௕ͳॲཧΛ֦ுؔ਺ʹ·ͱΊͨΓɺ
    ੹຿Λ௥Ճͨ͠ΓͰ͖Δ
    ֦ுؔ਺ͱ͸Կ͔
    context.getWindowService()
    context.getSystemService(Context.WINDOW_SERVICE)
    as WindowManager

    View full-size slide

  61. ֦ுؔ਺͸+BWBͰ
    ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

    View full-size slide

  62. fun Context.getWindowService()
    = getSystemService(Context.WINDOW_SERVICE)
    as WindowManager

    View full-size slide

  63. @NotNull
    public static final WindowManager getWindowService(@NotNull Context $receiver) {
    Intrinsics.checkParameterIsNotNull($receiver, “$receiver");
    Object var10000 = $receiver.getSystemService(“window");
    if(var10000 == null) {
    throw new TypeCastException("null cannot be cast to non-null type android.view.WindowManager”);
    } else {

    return (WindowManager)var10000;

    }
    }
    fun Context.getWindowService()
    = getSystemService(Context.WINDOW_SERVICE)
    as WindowManager

    View full-size slide

  64. public static final WindowManager
    getWindowService(Context $receiver) {
    Object var10000 =
    $receiver.getSystemService(“window");

    return (WindowManager)var10000;
    }
    fun Context.getWindowService()
    = getSystemService(Context.WINDOW_SERVICE)
    as WindowManager
    ˞γϯϓϧʹͨ͠΋ͷ
    ର৅ͷΫϥεΛୈҰҾ਺ʹऔΔ੩తؔ਺͕ੜ੒͞ΕΔ

    View full-size slide

  65. context.getWindowService()

    View full-size slide

  66. ExtensionsKt.getWindowService(context)
    context.getWindowService()
    ͜͜͸֦ுؔ਺Λఆٛͨ͠Ϋϥεʹґଘ͢Δ

    View full-size slide

  67. w ର৅ͷΫϥεΛୈҰҾ਺ʹऔΔ੩తؔ਺
    Λੜ੒͢Δ
    w ֦ுؔ਺ͷݺͼग़͠Λ੩తؔ਺ͷݺͼग़
    ͠ʹม׵͢Δ
    w ಺෦తʹ͸੩తͳؔ਺ΛूΊͨ6UJMΫϥε
    ͱಉ͡ɻର৅ͷΫϥεʹ੹຿Λ௥Ճͨ͠
    Α͏ʹݟ͔͚ͤΒΕΔΑ͏ʹ͍ͯ͠Δ
    ֦ுؔ਺͕΍͍ͬͯΔ͜ͱ

    View full-size slide

  68. w Ϋϥε͕࣋ͭσʔλͱͯ͠એݴ͢Δɻ
    ϑΟʔϧυͷ୅ΘΓʹ࢖͏
    ϓϩύςΟͱ͸Կ͔
    class Product(
    val id: Int,
    var name: String
    )

    View full-size slide

  69. w ίʔυ্Ͱ͸௚઀ϓϩύςΟʹΞΫη
    ε͍ͯ͠ΔΑ͏ʹݟ͑Δ͕ɺ҉໧తʹΞ
    ΫηαΛ͍࣋ͬͯΔ
    ϓϩύςΟͱ͸Կ͔
    val product = Product(1, “tomato")
    val id = product.id
    product.name = "meat"

    View full-size slide

  70. w ΧελϜΞΫηαΛ࣮૷Ͱ͖Δ
    ϓϩύςΟͱ͸Կ͔
    class Product(val id: Int) {
    var name: String = “"
    get() = field
    set(value) {
    field = value
    }
    }
    ϓϩύςΟΞΫηε͸ඞͣΞΫηαΛհ͢ɻ
    ΞΫηα಺͔ΒͰͷΈΞΫηεͰ͖Δ
    όοΩϯάϑΟʔϧυͱ͍͏࣮ମ͕͋Δ

    View full-size slide

  71. ϓϩύςΟ͸+BWBͰ
    ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

    View full-size slide

  72. class Product(val id: Int, var name: String)

    View full-size slide

  73. private final int id;
    @NotNull
    private String name;
    public final int getId() {
    return this.id;
    }
    @NotNull
    public final String getName() {
    return this.name;
    }
    public final void setName(@NotNull String var1)
    Intrinsics.checkParameterIsNotNull(var1, “");
    this.name = var1;
    }
    class Product(val id: Int, var name: String)

    View full-size slide

  74. private final int id;
    @NotNull
    private String name;
    public final int getId() {
    return this.id;
    }
    @NotNull
    public final String getName() {
    return this.name;
    }
    public final void setName(@NotNull String var1)
    Intrinsics.checkParameterIsNotNull(var1, “");
    this.name = var1;
    }
    class Product(val id: Int, var name: String)
    QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ

    View full-size slide

  75. private final int id;
    @NotNull
    private String name;
    public final int getId() {
    return this.id;
    }
    @NotNull
    public final String getName() {
    return this.name;
    }
    public final void setName(@NotNull String var1)
    Intrinsics.checkParameterIsNotNull(var1, “");
    this.name = var1;
    }
    class Product(val id: Int, var name: String)
    QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ
    WBMͷ৔߹HFUUFSͷΈੜ੒͞ΕΔ

    View full-size slide

  76. private final int id;
    @NotNull
    private String name;
    public final int getId() {
    return this.id;
    }
    @NotNull
    public final String getName() {
    return this.name;
    }
    public final void setName(@NotNull String var1)
    Intrinsics.checkParameterIsNotNull(var1, “");
    this.name = var1;
    }
    class Product(val id: Int, var name: String)
    QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ
    WBMͷ৔߹HFUUFSͷΈੜ੒͞ΕΔ
    WBSͷ৔߹HFUUFSTFUUFS͕ੜ੒͞ΕΔ

    View full-size slide

  77. val id = product.id
    product.name = "meat"

    View full-size slide

  78. val id = product.id
    product.name = "meat"
    int id = product.getId();
    product.setName("meat");

    View full-size slide

  79. w ϑΟʔϧυͱΞΫηαΛࣗಈੜ੒͢Δ
    w ϓϩύςΟΞΫηεΛΞΫηαݺͼग़͠
    ʹม׵͢Δ
    w ಈ࡞ͱͯ͠͸MPNCPLʹ͍ۙɻݟͨ໨͸
    ௚઀ΞΫηε͕ͩඞͣΞΫηαΛܦ༝͠
    ͨݺͼग़͠ʹͳΔɻ͞ΒʹFRVBMT΍
    IBTI$PEFΛ࣮૷ͯ͘͠ΕΔσʔλΫϥ
    εͳͲ͕͋Δ
    ϓϩύςΟ͕΍͍ͬͯΔ͜ͱ

    View full-size slide

  80. ͜͜·Ͱͷ·ͱΊ

    View full-size slide

  81. w +BWBʹͯ͠ΈΔͱͦΜͳʹ೉͍͜͠
    ͱ͸΍ͬͯͳ͍
    w ͪΐͬͱͨ͠ίʔυͷੜ੒Λݞ୅ΘΓ
    ͢Δ͜ͱͰ؆ܿͳॻ͖ํΛखॿ͚ͯ͠
    ͍Δ
    w ݴޠػೳΛશ෦ؚΊΔͱ͔ͳΓͷྔͷ
    ίʔυ͕࡟ݮͰ͖Δ͜ͱʹͳΔ
    ͜͜·Ͱͷ·ͱΊ

    View full-size slide

  82. ઃܭʹ༩͑ΔӨڹ

    View full-size slide

  83. OVMMνΣοΫΛ௥Ճͯ͠ॲཧΛ
    εΩοϓͨ͠Γྫ֎Λεϩʔ͢
    Δ͚ͩͷγϯϓϧͳߏ଄͚ͩͲ
    ͨͬͨͦΕ͚ͩͰઃܭʹӨڹ͕
    ͋ΔΜͩΖ͏͔ʁ

    View full-size slide

  84. !/VMMBCMF !/PO/VMMΛ׆༻
    ͨ͠ΓOVMMνΣοΫΛద੾ʹ࣮
    ૷͢Ε͹͍͍͚ͩͰ͸ʁʁ

    View full-size slide

  85. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    ؔ਺಺ͰWJFX͕ඇOVMMͰ͋Δ͜ͱΛอূ͢Δ

    View full-size slide

  86. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    semitransparent(text)

    View full-size slide

  87. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    semitransparent(text)
    5ZQFNJTTNBUDIͰίϯύΠϧΤϥʔ

    View full-size slide

  88. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    semitransparent(text!!)
    ةݥͳݺͼग़͠ɻཁվળͷγάφϧ

    View full-size slide

  89. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    text?.let { semitransparent(it) }
    OVMM͡Όͳ͚Ε͹࣮ߦɻ

    View full-size slide

  90. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    text?.let { semitransparent(it) }
    OVMM͡Όͳ͚Ε͹࣮ߦɻ
    ͳΜ͔ͩ৑௕ͩ͠ɺͦ΋ͦ΋OVMMͷέʔε͸૝ఆͯ͠ͳ͍ͷͰ͸ʁ

    View full-size slide

  91. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    val text: View? = findViewById(R.id.text)
    text?.let { semitransparent(it) }
    OVMM͡Όͳ͚Ε͹࣮ߦɻ
    ͳΜ͔ͩ৑௕ͩ͠ɺͦ΋ͦ΋OVMMͷέʔε͸૝ఆͯ͠ͳ͍ͷͰ͸ʁ
    %BUB#JOEJOH΍,PUMJO"OESPJE&YUFOTJPOTͷར༻Λݕ౼

    View full-size slide

  92. fun semitransparent(view: View) {
    view.alpha = 0.5f
    }
    semitransparent(binding.text)
    OVMMڐ༰ܕ͕ݱΕΔͱ͜ΖݮΒͦ͏ͱ͍ͯ͘͜͠ͱͰɺ
    OVMMʹରͯ҆͠શͳൣғ͕޿͕͍ͬͯ͘

    View full-size slide

  93. w OVMMʹؔ͢Δܖ໿ΛݴޠϨϕϧͰ୅ߦͯ͠
    ͘ΕΔɻͦΕʹΑΓOVMMͷڥքͷઃܭʹू
    தͰ͖Δ
    w OVMMͷڥք͕ίʔυ্ͰՄࢹԽ͞ΕΔͷͰ
    ઃܭͷվળͷࡐྉʹͳΔ
    w ඇOVMMͷྖҬΛ޿͍͛ͯ͘͜ͱͰɺՄಡੑ
    ͱมߋ༰қੑ্͕͕ΓɺOVMM҆શͱͳΔ
    OVMMڐ༰ܕ͕ઃܭʹ༩͑ΔӨڹ

    View full-size slide

  94. ͦΕͧΕͷؔ਺ͷ࣮૷ࣗମ͸౎
    ౓͠ͳ͖Ό͍͚ͳ͍݁͠ہ੩త
    ؔ਺ͷݺͼग़͠Λஔ͖׵͑Δͩ
    ͚ͩ͠ҙຯ͋Δͷʁʁ

    View full-size slide

  95. ੩తؔ਺ΛूΊͨ6UJMΫϥε܈
    Λద੾ʹӡ༻͢Ε͹͍͍͚ͩͰ
    ͸ʁʁ

    View full-size slide

  96. val id = intent.getIntExtra("id", -1)

    View full-size slide

  97. val id = intent.getIntExtra("id", -1)
    ͜ͷ*OUFOUύϥϝʔλ͕ඞਢͳͷ͔Ͳ͏͔
    ͔͜͜Β͸ಡΈऔΕͳ͍

    View full-size slide

  98. inline fun Intent.getRequired(key: String): T {

    extras?.get(key).let {

    if (it !is T) {

    throw IllegalArgumentException("$key")

    }

    return it

    }
    }
    LFZ͕ͳ͍৔߹ʹྫ֎Λεϩʔ͢Δɺ
    HFU3FRVJSFEؔ਺Λ*OUFOUʹ௥Ճ͢Δ

    View full-size slide

  99. val id:Int = intent.getRequired("id")
    *OUFOUࣗ਎ʹඞਢ஋ΛऔΓग़͢ͱ͍͏੹຿Λ
    ௥Ճ͢Δ͜ͱͰɺҙਤ͕໌շͳݺͼग़͕͠ՄೳʹͳΔ

    View full-size slide

  100. val id:Int = intent.getRequired("id")
    *OUFOUࣗ਎ʹඞਢ஋ΛऔΓग़͢ͱ͍͏੹຿Λ
    ௥Ճ͢Δ͜ͱͰɺҙਤ͕໌շͳݺͼग़͕͠ՄೳʹͳΔ

    View full-size slide

  101. w ର৅ͷΫϥε͕͓͍࣋ͬͯͨ΄͏͕Α͍ͱ
    ͔Μ͕͑ΒΕΔ੹຿Λɺ࣮ࡍʹର৅ͷΫ
    ϥεʹ࣋ͨͤΔ͜ͱ͕Ͱ͖Δɻ
    w طଘͷΫϥεΛ͋ͱ͔Β֦ுͰ͖ΔͷͰɺ
    ϓϥοτϑΥʔϜͷ౎߹ͰՄಡੑ͕٘ਜ਼
    ʹͳΔΑ͏ͳՕॴΛআڈ͠ɺຊདྷ͋Δ΂
    ͖࢟ͱߟ͑ΒΕΔঢ়ଶʹ͍͍͚ۙͮͯΔ
    ֦ுؔ਺͕ઃܭʹ༩͑ΔӨڹ

    View full-size slide

  102. w ,PUMJO͸+BWB
    w ϘΠϥʔϓϨʔτίʔυΛݴޠͷཪʹ
    Ӆ͢͜ͱͰɺຊ౰ʹ࡞Βͳ͚Ε͹͍͚
    ͳ͍෦෼ʹूதͰ͖ΔΑ͏ʹͳͬͯΔ
    w OVMMͷڥքͷઃܭɺ੹຿ͷ௥ՃʹΑΔ
    Մಡੑ޲্ͳͲͳͲɺݴޠػೳ͕ιϑ
    τ΢ΣΞશମͷઃܭվળʹد༩͍ͯ͠
    Δ
    શମͷ·ͱΊ

    View full-size slide

  103. -FU`TFOKPZ,PUMJO

    View full-size slide

  104. ·ͩ·ͩ͋Δ,PUMJOͷػೳ
    w σϦήʔτϓϩύςΟ
    w ΦϖϨʔλΦʔόʔϩʔυ
    w ίϯύχΦϯΦϒδΣΫτ
    w γʔϧυΫϥε
    w XIFOࣜ
    w ίϧʔνϯ
    w λΠϓΤΠϦΞε
    w ۩৅Խ͞Εͨܕύϥϝʔλ
    w σʔλΫϥε
    w ໊લ෇͖Ҿ਺
    w εϚʔτΩϟετ
    w ෼ղએݴ
    w ϩʔΧϧؔ਺
    w ຤ඌ࠶ؼ࠷దԽ
    w MBUFJOJU
    w Πϯελϯεͷؔ਺ࢀর
    FUD

    View full-size slide

  105. ͜ͷઌ͸܅ͷ໨Ͱ
    ͔֬Ίͯ͘Εʂ

    View full-size slide