Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Effective Java and Kotlin

4,310 views

Published on

https://www.youtube.com/watch?v=QIRJKIDLZgU
Effective Java는 효율적이고 잘 설계된 Java 프로그램을 구현하기 위한 지침들을 소개하는 책입니다. Kotlin에서는 이 지침들이 잘 적용될 수 있는 설계를 갖추고 있는데요, Kotlin Reference 문서에서는 설명을 뒷받침하기 위해 이 책을 인용하기도 합니다. 세션에서는 "이펙티브 자바" 책의 규칙들을 짚어가면서, Kotlin에 어떻게 반영되었는지, 혹은 어떻게 적용될수 있는지에 대해 공유합니다.

Published in: Engineering
  • Be the first to comment

Effective Java and Kotlin

  1. 1. • • 4 • •
  2. 2. Kotlin Night
  3. 3. Effective Kotlin Effective Java?🤔
  4. 4. Kotlin Java ?
  5. 5. ( ) Kotlin , 
 . , 
 . - Andrey Q. Kotlin .
  6. 6. . . - Andrey Q. JVM ?
  7. 7. , , . 
 . - Hadi hariri Q. ?
  8. 8. Kotlin , . Kotlin
  9. 9. Effective Kotlin Effective Java?🤔
  10. 10. Effective Java 3rd Edition Java 
 
 • • •
  11. 11. 1.   2.   3. private   4. private   5.   6. …. 
  12. 12. Kotlin ! Effective Java ?
  13. 13. • Effecive Java Kotlin • Effective Kotlin ! Effecive Java Kotlin
  14. 14. Item 3
  15. 15. public class NutritionFacts { private final int servingSize; !// (mL, 1 ) private final int servings; !// ( , n ) private final int calories; !// (1 ) private final int fat; !// (g/1 ) private final int sodium; !// (mg/1 ) private final int carbohydrate; !// (g/1 ) }
  16. 16. public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 0); } public NutritionFacts(int servingSize, int servings, int calories) { this(servingSize, servings, calories, 0); } public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) { this.servingSize = servingSize; this.servings = servings; this.calories = calories; this.fat = fat; this.sodium = sodium; this.carbohydrate = carbohydrate; }
  17. 17. public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27); } • •
  18. 18. public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(240); cocaCola.setServings(8); cocaCola.setCalories(100); cocaCola.setSodium(35); cocaCola.setCarbohydrate(27); } • •
  19. 19. public class NutritionFacts { public static class Builder { !// } public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts .Builder(240, 8) .calories(100) .sodium(35) .carbohydrate(27) .build(); } }
  20. 20. public static class Builder { !// private final int servingSize; private final int servings; !// - . private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } !// } Boilerplate 😵
  21. 21. class NutritionFacts( private val servingSize: Int, private val servings: Int, private val calories: Int = 0, private val fat: Int = 0, private val sodium: Int = 0, private val carbohydrate: Int = 0 ) Default arguments
  22. 22. val nutritionFacts = NutritionFacts( servingSize = 240, servings = 8, calories = 100, fat = 0, sodium = 35, carbohydrate = 27 ) Named arguments 

  23. 23. Named arguments Default arguments Item 3
  24. 24. private Item 3
  25. 25. • • 
 .
  26. 26. public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { } public void leaveTheBuilding() { System.out.println("Whoa baby, I'm outta here!"); } public static void main(String[] args) { Elvis elvis = Elvis.INSTANCE; elvis.leaveTheBuilding(); } }
  27. 27. object Elvis { fun leaveTheBuilding() { println("Whoa baby, I'm outta here!"); } } fun main() { Elvis.leaveTheBuilding() }
  28. 28. Decompile ? public final class Elvis { public static final Elvis INSTANCE; public final void leaveTheBuilding() { String var1 = "Whoa baby, I'm outta here!"; System.out.println(var1); } private Elvis() { } static { Elvis var0 = new Elvis(); INSTANCE = var0; } } object Elvis { fun leaveTheBuilding() { println("Whoa baby, I'm outta here!"); } } fun main() { Elvis.leaveTheBuilding() }
  29. 29. object Item 3 private
  30. 30. private Item 4
  31. 31. class NoConstructor private constructor() val noConstructor = NoConstructor() Compile Error!
  32. 32. ? . ( )
  33. 33. class NoConstructor private constructor() { val number = 1 fun printHello() { println("Hello!") } }
  34. 34. val number = 1 fun printHello() { println("Hello!") }
  35. 35. , Top Level function Item 4 private
  36. 36. Item 18
  37. 37. • - , 
 • • InstrumentedHashSet • HashSet
  38. 38. class InstrumentedHashSet<E> : HashSet<E> { var addCount = 0 private set override fun add(element: E): Boolean { addCount!++ return super.add(element) } override fun addAll(elements: Collection<E>): Boolean { addCount += elements.size return super.addAll(elements) } }
  39. 39. fun main() { val s = InstrumentedHashSet<String>() s.addAll(List.of("1", "2", “3")) println(s.addCount) } “6” 🤔 3 “3”
  40. 40. public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } HashSet AbstractSet
  41. 41. override fun add(element: E): Boolean { addCount!++ return super.add(element) } override fun addAll(elements: Collection<E>): Boolean { addCount += elements.size return super.addAll(elements) } addAll elements , super.addAll add
  42. 42. open class ForwardingSet<E>( private val s: MutableSet<E> ) : MutableSet<E> { override fun add(element: E): Boolean { return s.add(element) } override fun addAll(elements: Collection<E>): Boolean { return s.addAll(elements) } clear, iterator, remove, removeAll, ……… }
  43. 43. class InstrumentedHashSet<E> : ForwardingSet<E>(HashSet()) { !// var addCount = 0 private set override fun add(element: E): Boolean { addCount!++ return super.add(element) } override fun addAll(elements: Collection<E>): Boolean { addCount += elements.size return super.addAll(elements) } } “3” !
  44. 44. override fun add(element: E): Boolean { addCount!++ return super.add(element) } override fun addAll(elements: Collection<E>): Boolean { addCount += elements.size return super.addAll(elements) } super.addAll, ForwardingSet addAll 
 InstrumentedHashSet add .
  45. 45. •   . . • . . .
  46. 46. open class ForwardingSet<E>( private val s: MutableSet<E> ) : MutableSet<E> { override fun add(element: E): Boolean { return s.add(element) } override fun addAll(elements: Collection<E>): Boolean { return s.addAll(elements) } clear, iterator, remove, removeAll, ……… }
  47. 47. open class ForwardingSet<E>( private val s: MutableSet<E> ) : MutableSet<E> by s
  48. 48. class InstrumentedHashSet<E>( private val s: MutableSet<E> ) : MutableSet<E> by s { var addCount = 0 private set override fun add(element: E): Boolean { addCount!++ return s.add(element) } override fun addAll(elements: Collection<E>): Boolean { addCount += elements.size return s.addAll(elements) } }
  49. 49. .
 Kotlin (Deleagte ) by . Item 18
  50. 50. . Item 19
  51. 51. • , • . • .
  52. 52. class Parent { } class Child extends Parent { }
  53. 53. final class Parent { } class Child extends Parent { }
  54. 54. class Parent class Child : Parent()
  55. 55. open class Parent class Child : Parent()
  56. 56. . . Item 19 .
  57. 57. public public Item 16
  58. 58. Public public class Point { public double x; public double y; }
  59. 59. public class Point { private double x; private double y; public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } }
  60. 60. Public public class Point { public double x; public double y; } • API 
 . • . • . • .
  61. 61. class Point { var x : Double = 0.0 var y : Double = 0.0 }
  62. 62. class Point { var x : Double = 0.0 get() { println("x ") return field } var y : Double = 0.0 get() { println("y ") return field } }
  63. 63. Kotlin Getter, Setter 
 
 . Item 16 public public
  64. 64. @Override Item 40
  65. 65. public class Monogram { private final char character; public Monogram(char character) { this.character = character; } public boolean equals(Monogram m) { return character !== m.character; } public static void main(String[] args) { Set<Monogram> set = new HashSet<Monogram>(); set.add(new Monogram('a')); set.add(new Monogram('a')); System.out.println(set.size()); } 1 “2” equals ,
 ! @Override ?
  66. 66. public class Monogram { private final char character; public Monogram(char character) { this.character = character; } @Override public boolean equals(Monogram m) { return character !== m.character; } public static void main(String[] args) { Set<Monogram> set = new HashSet<Monogram>(); set.add(new Monogram('a')); set.add(new Monogram('a')); System.out.println(set.size()); } } Compile error Object !🧐
  67. 67. public class Monogram { @Override public boolean equals(Object o) { if (!(o instanceof Monogram)) return false; Monogram monogram = (Monogram) o; return character !== monogram.character; } public static void main(String[] args) { Set<Monogram> set = new HashSet<Monogram>(); set.add(new Monogram('a')); set.add(new Monogram('a')); System.out.println(set.size()); } } “1”
  68. 68. class Monogram(private val character: Char) { override fun equals(other: Any?): Boolean { return if(other is Monogram) { character !== other.character } else { false } } } Compile error
  69. 69. Java @Override 
 . 
 Kotlin 
 override . Item 40 @Override
  70. 70. Item 17
  71. 71. ( ) • • . • . • ( ) • •
  72. 72. • Java private char character = 'a'; private final char character = 'a'; • Kotlin private var character: Char = 'a' private val character: Char = ‘a'
  73. 73. final VS val ? • final - , • val, var - • ( ) , • , val
  74. 74. Kotlin List vs Java List(Kotlin MuableList) • Kotlin List (add, addAll) - Read Only • Mutable , List List .
  75. 75. . Kotlin . Item 17
  76. 76. Item 61
  77. 77. • • int, double, boolean • • String, List • . • - Integer, Double, Boolean
  78. 78. vs • . • null . • .
  79. 79. Kotlin ? • Kotlin .(int, boolean) • , (Nullable, Generics ) 
 .
  80. 80. private static final int a = 3; @Nullable private static final Integer b = 3; val a: Int = 3 val b: Int? = 3 Decompile
  81. 81. Kotlin , . Item 61
  82. 82. equals equals hashCode toString Item 10, 11, 12
  83. 83. Java Object equals, Kotlin Any equals • (reflexivity) : null x , x.equals(x) true . • (symmertry): null x, y , x.equals(y) true y.equals(x) true . • (transitivity): null x, y, z x.equals(y) true , y.equals(z) true x.equals(z) true . • (consistency): null x, y , x.equals(y) true false . • null- : null x , x.equals(null) false .
  84. 84. Java Object equals, Kotlin Any equals • (reflexivity) : null x , x.equals(x) true . • (symmertry): null x, y , x.equals(y) true y.equals(x) true . • (transitivity): null x, y, z x.equals(y) true , y.equals(z) true x.equals(z) true . • (consistency): null x, y , x.equals(y) true false . • null- : null x , x.equals(null) false . data class MyData(val text: String)
  85. 85. Java Hashcode • equals , hashCode . , . • equals(Object) , hashCode . • equals(Object) , hashCode . .
  86. 86. HashCode (?) • int result c . c 2.a . equals . 10 ). • f . • c . • , Type.hashCode(f) . Type . • equals equals , hashCode . , (canonical representation) hashCode . null 0 ( 0 .) • , . , 2.b . (0 ) . Arrays.hashCode . • 2.a c result . .
 result = 31 * result + c; • result .
  87. 87. HashCode (?) • int result c . c 2.a . equals . 10 ). • f . • c . • , Type.hashCode(f) . Type . • equals equals , hashCode . , (canonical representation) hashCode . null 0 ( 0 .) • , . , 2.b . (0 ) . Arrays.hashCode . • 2.a c result . .
 result = 31 * result + c; • result . data class MyData(val text: String)
  88. 88. toString • toString . • toString .
  89. 89. data class Student( val name: String, val score: Int ) fun main() { val student = Student(" ", 42) println(student) } Student(name= , score=42)
  90. 90. Data class equals, hashCode, toString . Item 10, 11, 12 equals equals hashCode toString
  91. 91. Item 77
  92. 92. try { !// } catch (Exception e) { e.printStackTrace(); }
  93. 93. ? try { !// } catch (Exception e) { e.printStackTrace(); } • • • 
 
 ?🤔
  94. 94. Checked Exception • try - catch , throw Exception Appendable append(CharSequence csq) throws IOException; • • • •
  95. 95. Kotlin ? • Checked Exception • - , “ ”
  96. 96. try { !// } catch (Exception e) { e.printStackTrace(); } “ ” UncheckedException
  97. 97. Kotlin CheckedException . . Item 77
  98. 98. Item 83
  99. 99. • • . • , • Kotlin Delegated Properties(by lazy)
  100. 100. val number by lazy { expensiveFunction() }
  101. 101. fun <T> lazy( mode: LazyThreadSafetyMode, initializer: () !-> T ) public enum class LazyThreadSafetyMode { SYNCHRONIZED, PUBLICATION, NONE, }
  102. 102. val number by lazy(LazyThreadSafetyMode.NONE) { expensiveFunction() }
  103. 103. Kotlin Deleagted Properties(by lazy) . . Item 83
  104. 104. API Item 31
  105. 105. List<? extends Number> numbers; if(condition) { numbers = new ArrayList<Int>(); } else { numbers = new ArrayList<Double>(); } val numbers: List<Number> = if(condition) { ArrayList<Int>() } else { ArrayList<Double>() }
  106. 106. Declaration-site variance, Use-site variance API Item 31 API
  107. 107. !🥳

×