https://www.youtube.com/watch?v=QIRJKIDLZgU
Effective Java는 효율적이고 잘 설계된 Java 프로그램을 구현하기 위한 지침들을 소개하는 책입니다. Kotlin에서는 이 지침들이 잘 적용될 수 있는 설계를 갖추고 있는데요, Kotlin Reference 문서에서는 설명을 뒷받침하기 위해 이 책을 인용하기도 합니다. 세션에서는 "이펙티브 자바" 책의 규칙들을 짚어가면서, Kotlin에 어떻게 반영되었는지, 혹은 어떻게 적용될수 있는지에 대해 공유합니다.
16. 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 )
}
17. 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;
}
18. public static void main(String[] args) {
NutritionFacts cocaCola =
new NutritionFacts(240, 8, 100, 0, 35, 27);
}
•
•
19. 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);
}
•
•
20. 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();
}
}
21. 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 😵
22. 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
27. 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();
}
}
28. object Elvis {
fun leaveTheBuilding() {
println("Whoa baby, I'm outta here!");
}
}
fun main() {
Elvis.leaveTheBuilding()
}
29. 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()
}
39. 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)
}
}
40. fun main() {
val s = InstrumentedHashSet<String>()
s.addAll(List.of("1", "2", “3"))
println(s.addCount)
}
“6” 🤔
3 “3”
41. public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
HashSet AbstractSet
42. 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
43. 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, ………
}
44. 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” !
67. 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 ?
68. 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
!🧐
69. 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”
70. class Monogram(private val character: Char) {
override fun equals(other: Any?): Boolean {
return if(other is Monogram) {
character !== other.character
} else {
false
}
}
}
Compile error