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

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

800912a73ce4e879003b6c89cf80cfeb?s=47 yagi
March 09, 2017

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

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

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

800912a73ce4e879003b6c89cf80cfeb?s=128

yagi

March 09, 2017
Tweet

Transcript

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

  2. "CPVU.F w 5PTIJIJSP:BHJ !TZTZBHJ  w DPPLQBE w "OESPJEΤϯδχΞ ٕज़෦௕

  3. None
  4. None
  5. None
  6. ,PUMJO

  7. None
  8. ,PUMJO΍ͬͯ·͔͢ʁ

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

  10. w ,PUMJOίϯύΠϥ͕ੜ੒ͨ͠+BWBόΠτίʔ υͰಡΉ͜ͱͰɺ,PUMJO͕ߦͬͯ͘ΕΔ࢓ࣄ Λཧղ͢Δ w ,PUMJOΛॻ͘ͱ͖ʹɺ+BWBͩͱͲ͏ͳͬͯ ͍Δ͔ΠϝʔδͰ͖ΔΑ͏ʹͳΔɻࣗ෼Ͱ֬ ೝͰ͖ΔΑ͏ʹͳΔ w ,PUMJOΛ࢖͏͜ͱͰলུͰ͖ͨϘΠϥʔϓϨʔ

    τίʔυ͕ՄಡੑΛͲͷΑ͏ʹߴΊɺઃܭʹ ӨڹΛ༩͑Δͷ͔ʹ͍ͭͯΠϝʔδ͕༙͘ ຊηογϣϯͷ໨త
  11. ࠷ऴతʹ ײͯ͡΄͍͜͠ͱ

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

  13. ,PUMJO ؆୯ศར͡ΌΜ

  14. ,PUMJO ΍ͬͯΈΔ͔ʙ

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

  16. σίϯύΠϧͷํ๏

  17. σίϯύΠϧͷํ๏

  18. σίϯύΠϧͷํ๏

  19. σίϯύΠϧͷํ๏

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

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

  22. OVMMڐ༰ܕ

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

    Λ͚ͭΔ͜ͱͰએݴͰ͖Δ
  24. w ҰํͰඇOVMMܕ͸OVMMΛ୅ೖͰ͖ͳ͍ɻ ม਺΍Ҿ਺΍໭Γ஋͕ඇOVMMܕͳΒɺ஋ ͕ඞͣඇOVMMͰ͋Δ͜ͱΛอূ͢Δ OVMMڐ༰ܕͱ͸Կ͔ val name:String = "Hello" //

    OK val name:String = null // Error fun toString() :String ໭Γ஋͕ඇOVMMͰ͋Δ͜ͱΛอূ͢Δ
  25. w OVMMڐ༰ܕ͸ͦͷ··ૢ࡞Ͱ͖ͳ͍ OVMMڐ༰ܕͱ͸Կ͔ str.length ίϯύΠϧΤϥʔʹͳΔ

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

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

    0.5f } ؔ਺಺ͰWJFX͕ඇOVMMͰ͋Δ͜ͱΛอূ͢Δ
  28. w OVMMͷڥքͰҧ൓͕͋ΔͱίϯύΠϥ͕ ڭ͑ͯ͘ΕΔ OVMMڐ༰ܕͱ͸Կ͔ val text: View? = findViewById(R.id.text) semitransparent(text)

    5ZQFNJTTNBUDIͰίϯύΠϧΤϥʔ
  29. w ةݥͳݺͼग़͠͸ةݥͳͷͰ௚͢΂͖ ͱ͍͏͜ͱ͕Θ͔Δ OVMMڐ༰ܕͱ͸Կ͔ val text: View? = findViewById(R.id.text) semitransparent(text!!)

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

    { semitransparent(it) } OVMM͡Όͳ͚Ε͹࣮ߦɻ
  31. OVMMڐ༰ܕ͸+BWBͰ ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

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

  33. val nonNull: String = ”nonNull” nonNull.length String nonNull = “nonNull";

    nonNull.length(); +BWBʹͳΔ͚ͩ
  34. val nullable: String? = null nullable?.length

  35. val nullable: String? = null nullable?.length String nullable = (String)null;

    if(nullable != null) { nullable.length(); } OVMMνΣοΫ͕௥Ճ͞ΕΔ
  36. nullable!!.length

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

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

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

    return text.length(); } fun length(text: String) = text.length
  40. w ͳΒOVMMνΣοΫΛ௥Ճ͢Δ w ͳΒOVMMνΣοΫͱྫ֎ͷεϩʔΛ௥Ճ ͢Δ w ؔ਺ͷҾ਺͕ඇOVMMܕͳΒࣄલ৚݅ͷ νΣοΫΛ௥Ճ͢Δ w ཁ͢ΔʹOVMMνΣοΫ͕ඞཁͳͱ͜Ζʹ

    OVMMνΣοΫΛࣗಈͰࠩ͠ࠐΜͰ͘ΕΔ OVMMڐ༰ܕ͕΍͍ͬͯΔ͜ͱ
  41. ؔ਺ܕɺϥϜμࣜ

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

    Ҿ਺ʹ7JFXΛडऔΓɺ໭Γ஋͸ͳ͍ؔ਺Λද͢
  43. w ߴ֊ؔ਺Λهड़Ͱ͖Δ ؔ਺ܕͱ͸Կ͔ fun calc( a: Int, b: Int, op:

    (Int, Int) -> Int ): Int { return op(a, b) }
  44. ϥϜμࣜͱ͸Կ͔ calc(1, 2, { a, b -> a + b

    }) *OU *OU *OUܕΛͦͷ৔Ͱهड़Ͱ͖Δ w ؔ਺Ϧςϥϧɻؔ਺ܕͷ࣮૷Λࣜͱ͠ ͯهड़Ͱ͖Δ
  45. ؔ਺ܕͱϥϜμࣜ listOf(1, 2, 3)
 .filter { it % 2 ==

    0 }
 .map { it * 2 } // 4 w ڧྗͳॲཧΛ؆ܿʹهड़Ͱ͖Δ
  46. ؔ਺ܕͱϥϜμࣜ͸+BWBͰ ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

  47. val onClick: (View) -> Unit

  48. val onClick: (View) -> Unit @NotNull private final Function1 onClick;

    ਖ਼֬ʹ͸'VODUJPO7JFX 6OJU
  49. public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } 'VODUJPO͸ͨͩͷΠϯλϑΣʔε ؔ਺ܕ͸Ҿ਺ͷ਺ʹԠͯ͡ 'VODUJPO/ʹม׵͞ΕΔ
  50. calc(1, 2, { a, b -> a + b })

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

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

    calc(1, 2, (Function2)null.INSTANCE); ίϯύΠϥ͕ϥϜμࣜΛ੩తͩͱ൑அͨ͠৔߹͸ γϯάϧτϯͷΫϥεΛੜ੒͢Δ
  53. None
  54. 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(); } खಈͰ௚͢ͱ͜Μͳײ͡
  55. 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Λܧঝ
  56. 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Λܧঝ
  57. 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Λܧঝ
  58. 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Λܧঝ
  59. val seed = 10 calc(1, 2, { a, b ->

    a + b + seed })
  60. 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; } })); Ϋϩʔδϟͷ৔߹͸ແ໊ΫϥεΛੜ੒͢Δ
  61. var seed = 10 calc(1, 2, { a, b ->

    seed++; a + b })
  62. 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Ϋϥε͕࢖ΘΕΔ
  63. w ؔ਺ܕΛҾ਺ͷ਺ʹԠͨ͡'VODUJPO/Πϯλ ϑΣʔεʹม׵͢Δ w ϥϜμࣜΛɺ-BNCEBΛܧঝͯ͠'VODUJPO/Λ ࣮૷͢ΔΫϥεʹม׵͢Δ w ϥϜμࣜͷத਎ʹΑͬͯ࠷దͳίʔυΛੜ੒͢Δ w جຊతʹ͸SFUSPMBNCEB΍KBDLͳͲͰͷ+BWB

    ϥϜμࣜαϙʔτͱಉ͡Α͏ͳΞϓϩʔνͰؔ਺ ܕΛ࣮ݱͯ͘͠ΕΔɻࠩ෼ͱͯ͠͸Ϋϩʔδϟ͕ ͪΐͬͱॊೈͱ͍͏͘Β͍ ؔ਺ܕɺϥϜμ͕ࣜ΍͍ͬͯΔ͜ͱ
  64. ֦ுؔ਺

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

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

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

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

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

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

  71. @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
  72. public static final WindowManager getWindowService(Context $receiver) { Object var10000 =

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

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

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

    ֦ுؔ਺͕΍͍ͬͯΔ͜ͱ
  76. ϓϩύςΟ

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

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

    val id = product.id product.name = "meat"
  79. w ΧελϜΞΫηαΛ࣮૷Ͱ͖Δ ϓϩύςΟͱ͸Կ͔ class Product(val id: Int) { var name:

    String = “" get() = field set(value) { field = value } } ϓϩύςΟΞΫηε͸ඞͣΞΫηαΛհ͢ɻ ΞΫηα಺͔ΒͰͷΈΞΫηεͰ͖Δ όοΩϯάϑΟʔϧυͱ͍͏࣮ମ͕͋Δ
  80. ϓϩύςΟ͸+BWBͰ ͲͷΑ͏ʹ࣮ݱ͞Ε͍ͯΔ͔ʁ

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

  82. 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, “<set-?>"); this.name = var1; } class Product(val id: Int, var name: String)
  83. 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, “<set-?>"); this.name = var1; } class Product(val id: Int, var name: String) QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ
  84. 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, “<set-?>"); this.name = var1; } class Product(val id: Int, var name: String) QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ WBMͷ৔߹HFUUFSͷΈੜ੒͞ΕΔ
  85. 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, “<set-?>"); this.name = var1; } class Product(val id: Int, var name: String) QSJWBUFͳϑΟʔϧυ͕એݴ͞ΕΔ WBMͷ৔߹HFUUFSͷΈੜ੒͞ΕΔ WBSͷ৔߹HFUUFSTFUUFS͕ੜ੒͞ΕΔ
  86. val id = product.id product.name = "meat"

  87. val id = product.id product.name = "meat" int id =

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

    εͳͲ͕͋Δ ϓϩύςΟ͕΍͍ͬͯΔ͜ͱ
  89. ͜͜·Ͱͷ·ͱΊ

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

    ͜͜·Ͱͷ·ͱΊ
  91. ઃܭʹ༩͑ΔӨڹ

  92. OVMMڐ༰ܕ

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

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

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

  96. fun semitransparent(view: View) { view.alpha = 0.5f } val text:

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

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

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

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

    View? = findViewById(R.id.text) text?.let { semitransparent(it) } OVMM͡Όͳ͚Ε͹࣮ߦɻ ͳΜ͔ͩ৑௕ͩ͠ɺͦ΋ͦ΋OVMMͷέʔε͸૝ఆͯ͠ͳ͍ͷͰ͸ʁ
  101. 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ͷར༻Λݕ౼
  102. fun semitransparent(view: View) { view.alpha = 0.5f } semitransparent(binding.text) OVMMڐ༰ܕ͕ݱΕΔͱ͜ΖݮΒͦ͏ͱ͍ͯ͘͜͠ͱͰɺ

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

    OVMMڐ༰ܕ͕ઃܭʹ༩͑ΔӨڹ
  104. ֦ுؔ਺

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

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

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

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

  109. inline fun <reified T> Intent.getRequired(key: String): T {
 extras?.get(key).let {


    if (it !is T) {
 throw IllegalArgumentException("$key")
 }
 return it
 } } LFZ͕ͳ͍৔߹ʹྫ֎Λεϩʔ͢Δɺ HFU3FRVJSFEؔ਺Λ*OUFOUʹ௥Ճ͢Δ
  110. val id:Int = intent.getRequired("id") *OUFOUࣗ਎ʹඞਢ஋ΛऔΓग़͢ͱ͍͏੹຿Λ ௥Ճ͢Δ͜ͱͰɺҙਤ͕໌շͳݺͼग़͕͠ՄೳʹͳΔ

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

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

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

    Δ શମͷ·ͱΊ
  114. -FU`TFOKPZ,PUMJO

  115. ·ͩ·ͩ͋Δ,PUMJOͷػೳ w σϦήʔτϓϩύςΟ w ΦϖϨʔλΦʔόʔϩʔυ w ίϯύχΦϯΦϒδΣΫτ w γʔϧυΫϥε w

    XIFOࣜ w ίϧʔνϯ w λΠϓΤΠϦΞε w ۩৅Խ͞Εͨܕύϥϝʔλ w σʔλΫϥε w ໊લ෇͖Ҿ਺ w εϚʔτΩϟετ w ෼ղએݴ w ϩʔΧϧؔ਺ w ຤ඌ࠶ؼ࠷దԽ w MBUFJOJU w Πϯελϯεͷؔ਺ࢀর FUD
  116. ͜ͷઌ͸܅ͷ໨Ͱ ͔֬Ίͯ͘Εʂ

  117. THANK YOU