Post

🐣 chap9. λ¦¬νŒ©ν„°λ§, ν…ŒμŠ€νŒ…, 디버깅

λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ μ „λž΅, ν…œν”Œλ¦Ώ λ©”μ„œλ“œ, μ˜΅μ €λ²„, 의무 체인, νŒ©ν† λ¦¬ λ“±μ˜ 객체지ν–₯ λ””μžμΈ νŒ¨ν„΄μ„ κ°„μ†Œν™”ν•  수 μžˆλŠ” 방법 탐색

9.1 가독성과 μœ μ—°μ„±μ„ κ°œμ„ ν•˜λŠ” λ¦¬νŒ©ν„°λ§

λžŒλ‹€, λ©”μ„œλ“œ μ°Έμ‘°, 슀트림 λ“±μ˜ κΈ°λŠ₯을 μ΄μš©ν•΄ 더 가독성 쒋은 μ½”λ“œλ‘œΒ λ¦¬νŒ©ν„°λ§Β ν•˜λŠ” 방법

9.1.1 μ½”λ“œ 가독성 κ°œμ„ 

μΌλ°˜μ μœΌλ‘œΒ μ½”λ“œ 가독성이 μ’‹λ‹€ = μ–΄λ–€ μ½”λ“œλ₯Ό λ‹€λ₯Έ μ‚¬λžŒλ„ μ‰½κ²Œ 이해할 수 μžˆμŒΒ μ„ 의미

즉, λ‚΄κ°€ κ΅¬ν˜„ν•œ μ½”λ“œλ₯Ό λ‹€λ₯Έ μ‚¬λžŒμ΄Β μ‰½κ²Œ μ΄ν•΄ν•˜κ³  μœ μ§€λ³΄μˆ˜ ν•  수 있게 λ§Œλ“œλŠ” 것

  • λžŒλ‹€, λ©”μ„œλ“œ μ°Έμ‘°, μŠ€νŠΈλ¦Όμ„ ν™œμš©ν•œ 3가지 λ¦¬νŒ©ν„°λ§ 방법

9.1.2 읡λͺ… 클래슀λ₯Ό λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ λ¦¬νŒ©ν„°λ§ν•˜κΈ°

읡λͺ… ν΄λž˜μŠ€λŠ” μ½”λ“œλ₯Ό μž₯ν™©ν•˜κ²Œ λ§Œλ“€κ³  μ‰½κ²Œ μ—λŸ¬λ₯Ό μΌμœΌν‚€κΈ° λ•Œλ¬Έμ— 더 κ°„κ²°ν•˜κ³  가독성 쒋은 μ½”λ“œλ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄Β λžŒλ‹€ ν‘œν˜„μ‹Β μ„ μ΄μš©ν•˜λŠ” 것이 μ’‹μŒ

ν•˜μ§€λ§Œ, λͺ¨λ“  읡λͺ… ν΄λž˜μŠ€κ°€ λ‹€ λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ λ³€ν™˜κ°€λŠ₯ν•œ 것은 μ•„λ‹˜

  1. 읡λͺ… ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©ν•œΒ this와 superΒ λŠ” λžŒλ‹€ ν‘œν˜„μ‹μ—μ„œ λ‹€λ₯Έ 의미λ₯Ό κ°–λŠ”λ‹€. 읡λͺ… ν΄λž˜μŠ€μ—μ„œ thisλŠ” 읡λͺ…ν΄λž˜μŠ€ μžμ‹ μ„ κ°€λ¦¬ν‚€μ§€λ§Œ λžŒλ‹€μ—μ„œλŠ” λžŒλ‹€λ₯Ό κ°μ‹ΈλŠ” 클래슀λ₯Ό 가리킨닀.
  2. 읡λͺ… ν΄λž˜μŠ€λŠ” 감싸고 μžˆλŠ” 클래슀의 λ³€μˆ˜λ₯Ό 가릴 수 μžˆλ‹€. But λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œλŠ” λ³€μˆ˜λ₯Ό 가릴 수 μ—†μŒ
  3. 읡λͺ… 클래슀λ₯Ό λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ λ°”κΎΈλ©΄ μ½˜ν…μŠ€νŠΈ μ˜€λ²„λ‘œλ”©μ— λ”°λ₯Έ λͺ¨ν˜Έν•¨ 초래 κ°€λŠ₯ 읡λͺ… ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ν™”ν•  λŒ€ λͺ…μ‹œμ μœΌλ‘œ ν˜•μ‹μ΄ μ •ν•΄μ§€λŠ” 반면 λžŒλ‹€μ˜ ν˜•μ‹μ€ μ½˜ν…μŠ€νŠΈμ— 따라 달라지기 λ•Œλ¬Έμ΄λ‹€. ν•˜μ§€λ§Œ, IntelliJ λ“±μ˜ IDEμ—μ„œλŠ” 이λ₯ΌΒ μžλ™μœΌλ‘œ ν•΄κ²°ν•΄μ£ΌλŠ” λ¦¬νŒ©ν„°λ§ κΈ°λŠ₯ 제곡

9.1.3. λžŒλ‹€ ν‘œν˜„μ‹μ„ λ©”μ„œλ“œ 참쑰둜 λ¦¬νŒ©ν„°λ§ν•˜κΈ°

λžŒλ‹€ ν‘œν˜„μ‹μ€ μ‰½κ²Œ 전달할 수 μžˆλŠ” 짧은 μ½”λ“œμ΄μ§€λ§Œ,Β λ©”μ„œλ“œ μ°Έμ‘°Β λ₯Ό μ΄μš©ν•˜λ©΄ 더 가독성을 높일 수 μžˆλ‹€.

λ©”μ„œλ“œ 참쑰의 λ©”μ„œλ“œλͺ…μœΌλ‘œ μ½”λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•ν•˜κ²Œ μ•Œλ¦΄ 수 있기 λ•Œλ¬Έ

1
2
3
4
5
6
7
8
9
10
11
12
//λžŒλ‹€ ν‘œν˜„μ‹
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel =
		menu.stream()
		  .collect(groupingBy(dish -> {
            if (dish.getCalories() <= 400) return CaloricLevel.DIET;
            else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
            else return CaloricLevel.FAT;
}));

//λ©”μ„œλ“œ μ°Έμ‘°
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream()
        .collect(groupingBy(Dish::getCaloricLevel));

λ˜ν•œ,Β comparingκ³ΌΒ maxBy 같은 정적 헬퍼 λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜λŠ” 것도 μ’‹λ‹€.

sum,Β maximumλ“± 자주 μ‚¬μš©ν•˜λŠ” 리듀싱 연산은 λ©”μ„œλ“œ 참쑰와 ν•¨κ»˜ μ‚¬μš©ν•  수 μžˆλŠ” λ‚΄μž₯ 헬퍼 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.

λ‚΄μž₯ 컬렉터λ₯Ό μ΄μš©ν•˜λ©΄ 더 λͺ…ν™•ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

9.1.4. λͺ…λ Ήν˜• 데이터 처리λ₯Ό 슀트림으둜 λ¦¬νŒ©ν„°λ§ν•˜κΈ°

슀트림 APIλŠ” 데이터 처리 νŒŒμ΄ν”„λΌμΈμ˜ μ˜λ„λ₯Ό 더 λͺ…ν™•ν•˜κ²Œ 보여쀀닀.

1
2
3
4
5
6
7
8
9
10
11
//슀트림 μ‚¬μš© X
List<String> dishNames = new ArrayList<>();
for(Dish dish: menu) {
    if(dish.getCalories() > 300) {
        dishNames.add(dish.getName());
    }
}
//슀트림 μ‚¬μš© O
menu.parallelStream().filter(d -> d.getCalories() > 300)
     .map(Dish::getName)
     .collect(toList());

9.2. λžŒλ‹€λ‘œ 객체지ν–₯ λ””μžμΈ νŒ¨ν„΄ λ¦¬νŒ©ν„°λ§ν•˜κΈ°

λ””μžμΈ νŒ¨ν„΄Β μ€ λ‹€μ–‘ν•œ νŒ¨ν„΄μ„ μœ ν˜•λ³„λ‘œ μ •λ¦¬ν•œ κ²ƒμœΌλ‘œ 곡톡적인 μ†Œν”„νŠΈμ›¨μ–΄ 문제λ₯Ό 섀계할 λ–„ μž¬μ‚¬μš©ν•  수 μžˆλŠ”, κ²€μ¦λœ 청사진을 μ œκ³΅ν•œλ‹€. λ””μžμΈ νŒ¨ν„΄μ— λžŒλ‹€ ν‘œν˜„μ‹μ„ μ΄μš©ν•˜λ©΄ 문제λ₯Ό 더 쉽고 κ°„λ‹¨ν•˜κ²Œ ν•΄κ²°ν•  수 μžˆλ‹€.

9.2.1. μ „λž΅

μ „λž΅ νŒ¨ν„΄Β μ€Β ν•œ μœ ν˜•μ˜ μ•Œκ³ λ¦¬μ¦˜μ„ λ³΄μœ ν•œ μƒνƒœμ—μ„œ λŸ°νƒ€μž„μ— μ μ ˆν•œ μ•Œκ³ λ¦¬μ¦˜μ„ μ„ νƒν•˜λŠ” 기법

λ‹€μ–‘ν•œ 기쀀을 κ°–λŠ” μž…λ ₯값을 κ²€μ¦ν•˜κ±°λ‚˜, λ‹€μ–‘ν•œ νŒŒμ‹± 방법을 μ‚¬μš©ν•˜κ±°λ‚˜, μž…λ ₯ ν˜•μ‹μ„ μ„€μ •ν•˜λŠ” λ“±μ˜ μ‹œλ‚˜λ¦¬μ˜€μ— μ μš©ν•  수 μžˆλ‹€.

μ „λž΅νŒ¨ν„΄μ˜ ꡬ성 λΆ€λΆ„

  • μ•Œκ³ λ¦¬μ¦˜μ„ λ‚˜νƒ€λ‚΄λŠ” μΈν„°νŽ˜μ΄μŠ€ (Strategy μΈν„°νŽ˜μ΄μŠ€)
  • λ‹€μ–‘ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ λ‚˜νƒ€λ‚΄λŠ” ν•œ 개 μ΄μƒμ˜ μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ (ConcreteStrategyA, ConcreteStrategyB 같은 ꡬ체적인 κ΅¬ν˜„ 클래슀)
  • μ „λž΅ 객체λ₯Ό μ‚¬μš©ν•˜λŠ” ν•œ 개 μ΄μƒμ˜ ν΄λΌμ΄μ–ΈνŠΈ
1
2
3
4
5
6
7
8
9
10
11
//λžŒλ‹€ μ‚¬μš© μ „
Validator numericValidator = new Validator(new IsNumberic());
boolean b1 = numericValidator.validate("aaaa");
Validator lowerCaseValidator = new Validator(new IsAllLowwerCase());
boolean b2 = lowerCaseValidator.validate("bbbb");

//λžŒλ‹€ μ‚¬μš© ν›„
Validator numericValidator = new Validator((String s) -> s.matches("[a-z]+"));
boolean b1 = numericValidator.validate("aaaa");
Validator lowewrCaseValidator = new Validator((String s) -> s.matches("\\d+"));
boolean b2 = lowerCaseValidator.validate("bbbb");
  • λžŒλ‹€λ₯Ό μ΄μš©ν•˜λ©΄ μ „λž΅ λ””μžμΈ νŒ¨ν„΄μ—μ„œ λ°œμƒν•˜λŠ” μžμž˜ν•œ μ½”λ“œλ₯Ό μ œκ±°ν•  수 μžˆλ‹€.
  • λžŒλ‹€ ν‘œν˜„μ‹μ€ μ½”λ“œμ‘°κ°(λ˜λŠ” μ „λž΅) 을 μΊ‘μŠν™”ν•œλ‹€.

9.2.2. ν…œν”Œλ¦Ώ λ©”μ„œλ“œ

μ•Œκ³ λ¦¬μ¦˜μ˜ κ°œμš”λ₯Ό μ œμ‹œν•œ λ‹€μŒ,Β μ•Œκ³ λ¦¬μ¦˜μ˜ 일뢀λ₯Ό κ³ μΉ  수 μžˆλŠ” μœ μ—°ν•¨μ„ μ œκ³΅Β ν•΄μ•Ό ν•  λ•ŒλŠ”Β ν…œν”Œλ¦Ώ λ©”μ„œλ“œΒ λ””μžμΈ νŒ¨ν„΄μ„ μ΄μš©ν•˜λŠ” 것이 μ’‹λ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//λžŒλ‹€ μ‚¬μš© μ „
abstract class OnlineBanking {
    public void processCustomer(int id) {
        Customer c = Database.getCustomerWithId(id);
        makeCustomerHappy(c);
    }
    abstract void makeCustomerHappy(Customer c);
}
//λžŒλ‹€ μ‚¬μš© ν›„
public void processCustomer(int id, Consumer<Customer> makeCustomerHappy) {
    Customer c = Database.getCustomerWithId(id);
    makeCustomerHappy.accept(c);
}
new OnlineBankingLambda().processCustomer(1337, (Customer c) ->
            System.out.println("Hello " + c.getName());

λžŒλ‹€λ₯Ό μ‚¬μš©ν•˜λ©΄ onlineBanking 클래슀λ₯Ό 상속받지 μ•Šκ³  직접 λžŒλ‹€ ν‘œν˜„μ‹μ„ 전달해 λ‹€μ–‘ν•œ λ™μž‘μ„ μΆ”κ°€ν•  수 μžˆλ‹€.

9.2.3. μ˜΅μ €λ²„

μ–΄λ–€ μ΄λ²€νŠΈκ°€ λ°œμƒν–ˆμ„ λ•ŒΒ μ£Όμ²΄Β κ°€ λ˜λŠ” ν•œ κ°μ²΄κ°€Β μ˜΅μ €λ²„Β λΌ λΆˆλ¦¬λŠ” λ‹€λ₯Έ 객체 λ¦¬μŠ€νŠΈμ—κ²Œ μžλ™μœΌλ‘œ μ•Œλ¦Όμ„ 보내야 ν•˜λŠ” μƒν™©μ—μ„œΒ μ˜΅μ €λ²„ λ””μžμΈ νŒ¨ν„΄Β μ„ μ‚¬μš©ν•œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//λžŒλ‹€ μ‚¬μš© μ „
class Feed implements Subject {
    private final List<Observer> observers = new ArrayList<>();
    public void registerObserver(Observer o) {
        this.observers.add(o);
    }
    public void notifyObservers(String tweet) {
        observers.forEach(o -> o.notify(tweet));
    }
}
//λžŒλ‹€ μ‚¬μš© ν›„
f.registerObserver((String tweet) -> {
    if(tweet != null && tweet.contains("money")) {
        System.out.println("Breaking news in NY! " + tweet);
    }
});
f.registerObserver((String tweet) -> {
    if(tweet != null && tweet.contains("queen")) {
        System.out.println("Yet more news from London... " + tweet);
    }
});

ν•˜μ§€λ§Œ, μ˜΅μ €λ²„κ°€ μƒνƒœλ₯Ό 가지며, μ—¬λŸ¬ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λŠ” λ“± λ³΅μž‘ν•˜λ‹€λ©΄ λžŒλ‹€ ν‘œν˜„μ‹λ³΄λ‹€ 기쑴의 클래슀 κ΅¬ν˜„λ°©μ‹μ„ κ³ μˆ˜ν•˜λŠ” 것이 λ°”λžŒμ§ν•  μˆ˜λ„ μžˆλ‹€.

9.2.4. 의무 체인

μž‘μ—… 처리 객체의 체인(λ™μž‘ 체인 λ“±)을 λ§Œλ“€ λ•ŒλŠ”Β μ˜λ¬΄ 체인 νŒ¨ν„΄Β μ„ μ‚¬μš©ν•œλ‹€. ν•œ 객체가 μ–΄λ–€ μž‘μ—…μ„ μ²˜λ¦¬ν•œ λ‹€μŒμ— λ‹€λ₯Έ 객체둜 κ²°κ³Όλ₯Ό μ „λ‹¬ν•˜κ³ , λ‹€λ₯Έ 객체도 ν•΄μ•Ό ν•  μž‘μ—…μ„ μ²˜λ¦¬ν•œ λ‹€μŒμ— 또 λ‹€λ₯Έ 객체둜 μ „λ‹¬ν•˜λŠ” 식이닀.

이 νŒ¨ν„΄μ€Β ν•©μˆ˜ 체인(ν•¨μˆ˜ μ‘°ν•©)Β κ³Ό λΉ„μŠ·ν•˜λ‹€. μž‘μ—… 처리 객체λ₯ΌΒ Function<String, String>, 더 μ •ν™•νžˆ ν‘œν˜„ν•˜μžλ©΄Β UnaryOperator<String>Β ν˜•μ‹μ˜ μΈμŠ€ν„΄μŠ€λ‘œ ν‘œν˜„ν•  수 μžˆλ‹€.

9.2.5. νŒ©ν† λ¦¬

μΈμŠ€ν„΄μŠ€ν™” λ‘œμ§μ„ ν΄λΌμ΄μ–ΈνŠΈμ— λ…ΈμΆœν•˜μ§€ μ•Šκ³  객체λ₯Ό λ§Œλ“€ λ•ŒΒ νŒ©ν† λ¦¬ λ””μžμΈ νŒ¨ν„΄Β μ„ μ‚¬μš©ν•œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//λžŒλ‹€ μ‚¬μš© μ „
public class ProductFactory {
    public static Product createProduct(String name) {
        switch(name) {
            case "loan" : return new Loan();
            case "stock" : return new Stock();
            case "bond" : return new Bond();
            default : throw new RuntimeException("No such product " + name);
        }
    }
}
//λžŒλ‹€ μ‚¬μš© ν›„
Supplier<Product> loanSupplier = Loan::new;
Loan loan = loanSupplier.get();

final static Map<String, Supplier<Product>> map = new HashMap<>();
static {
    map.put("loan", Loan::new);
    map.put("stock", Stock::new);
    map.put("bond", Bond::new);
}

But, νŒ©ν† λ¦¬ λ©”μ„œλ“œ μ—­μ‹œ μƒμ„±μžλ‘œ μ—¬λŸ¬ 인수λ₯Ό μ „λ‹¬ν•˜λŠ” μƒν™©μ—μ„œλŠ” μ μš©ν•˜κΈ° μ–΄λ ΅λ‹€.

e.g. μ„Έ 인수λ₯Ό λ°›λŠ” μƒμ„±μžλΌλ©΄ TriFunctionμ΄λΌλŠ” νŠΉλ³„ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•˜κ³ , κ²°κ΅­ λ‹€μŒκ³Ό 같이 Map의 μ‹œκ·Έλ‹ˆμ²˜κ°€ λ³΅μž‘ν•΄μ§„λ‹€.

1
2
3
4
public interface TriFunction <T, U, V, R> {
    R apply(T t, U u, V v);
}
Map<String, TriFunction<Integer, Integer, String, Product>> map = new HashMap<>();

9.3. λžŒλ‹€ ν…ŒμŠ€νŒ…

ν”„λ‘œκ·Έλž¨μ΄ μ˜λ„λŒ€λ‘œ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄Β λ‹¨μœ„ ν…ŒμŠ€νŠΈΒ λ₯Ό ν•΄λ³Ό 수 μžˆλ‹€.

1
2
3
4
5
6
7
@Test
public void testMoveRightBy() throws Exception {
    Point p1 = new Point(5, 5);
    Point p2 = p1.moveRightBy(10);
    assertEquals(15, p2.getX());
    assertEquals(5, p2.getY());
}

9.3.1. λ³΄μ΄λŠ” λžŒλ‹€ ν‘œν˜„μ‹μ˜ λ™μž‘ ν…ŒμŠ€νŒ…

μœ„μ˜ ν…ŒμŠ€νŠΈμ½”λ“œλŠ”Β moveRightByκ°€ publicμ΄λ―€λ‘œ λ¬Έμ œμ—†μ΄ μž‘λ™ν•œλ‹€. ν•˜μ§€λ§Œ λžŒλ‹€λŠ” 읡λͺ…μ΄λ―€λ‘œ ν…ŒμŠ€νŠΈ μ½”λ“œ 이름을 ν˜ΈμΆœν•  수 μ—†λ‹€. λ”°λΌμ„œ ν•„μš”ν•˜λ‹€λ©΄ λžŒλ‹€λ₯Ό ν•„λ“œμ— μ €μž₯ν•΄μ„œ μž¬μ‚¬μš©ν•  수 있으며 λžŒλ‹€μ˜ λ‘œμ§μ„ ν…ŒμŠ€νŠΈν•  수 μžˆλ‹€.

1
2
3
4
5
6
public class Point {
    public final static Comparator<Point> compareByXAndThenY =
        comparing(Point::getX).thenComparing(Point::getY);
    ...
}

1
2
3
4
5
6
7
@Test
public void testComparingTwoPoints() throws Exception {
    Point p1 = new Point(10, 15);
    Point p2 = new Point(10, 20);
    int result = Point.compareByXAndThenY.compare(p1, p2);
    assertTrue(result < 0);
}

9.3.2. λžŒλ‹€λ₯Ό μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œμ˜ λ™μž‘μ— μ§‘μ€‘ν•˜λΌ

λžŒλ‹€μ˜ λͺ©ν‘œλŠ” 정해진 λ™μž‘μ„ λ‹€λ₯Έ λ©”μ„œλ“œμ—μ„œ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜λ‚˜μ˜ 쑰각으둜 μΊ‘μŠν™”ν•˜λŠ” 것 이닀. λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œμ˜ λ™μž‘μ„ ν…ŒμŠ€νŠΈν•¨μœΌλ‘œμ¨ λžŒλ‹€λ₯Ό κ³΅κ°œν•˜μ§€ μ•ŠμœΌλ©΄μ„œλ„ λžŒλ‹€ ν‘œν˜„μ‹μ„ 검증할 수 μžˆλ‹€.

1
2
3
4
5
public static List<Point> moveAllPointsRightBy(List<Point> points, int x) {
    return points.stream()
                 .map(p -> new Point(p.getX() + x, p.getY()))
                 .collect(toList());
}

μœ„ μ½”λ“œμ˜Β p -> new Point(p.getX() + x, p.getY());Β ν…ŒμŠ€νŠΈ

1
2
3
4
5
6
7
8
9
@Test
public void testMoveAllPointsRightBy() throws Exception {
    List<Point> points =
            Arrays.asList(new Point(5, 5), new Point(10, 5));
    List<Point> expectedPoints =
            Arrays.asList(new Point(15, 5), new Point(20, 5));
    List<Point> newPoints = Point.moveAllPointsRightBy(points, 10);
    assertEquals(expectedPointes, newPoints);
}

9.4. 디버깅

λ¬Έμ œκ°€ λ°œμƒν•œ μ½”λ“œλ₯Ό 디버깅할 λ•Œ κ°œλ°œμžλŠ” λ‹€μŒ 두 가지λ₯Ό λ¨Όμ € 확인해야 ν•œλ‹€.

  • μŠ€νƒ 트레이슀
  • λ‘œκΉ…

ν•˜μ§€λ§Œ λžŒλ‹€ ν‘œν˜„μ‹κ³Ό μŠ€νŠΈλ¦Όμ€ 기쑴의 디버깅 기법을 무λ ₯ν™”ν•œλ‹€.

9.4.1. μŠ€νƒ 트레이슀 확인

μ˜ˆμ™Έ λ°œμƒμœΌλ‘œ ν”„λ‘œκ·Έλž¨ 싀행이 κ°‘μžκΈ° μ€‘λ‹¨λ˜μ—ˆλ‹€λ©΄ λ¨Όμ € μ–΄λ””μ—μ„œ λ©ˆμ·„κ³  μ–΄λ–»κ²Œ λ©ˆμΆ”κ²Œ λ˜μ—ˆλŠ”μ§€ μ‚΄νŽ΄λ΄μ•Ό ν•œλ‹€.

λžŒλ‹€ν‘œν˜„μ‹μ€ 이름이 μ—†κΈ° λ•Œλ¬Έμ— 쑰금 λ³΅μž‘ν•œ μŠ€νƒ νŠΈλ ˆμ΄μŠ€κ°€ μƒμ„±λœλ‹€.

1
2
3
Exception in thread "main" java.lang.NullPointerException
    at Debugging.lambda$main$0(Debugging.java:6)
    at Debugging$$Lambda$5/284720968.apply(Unknown Source)

λžŒλ‹€ ν‘œν˜„μ‹ λ‚΄λΆ€μ—μ„œ μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ λžŒλ‹€ ν‘œν˜„μ‹μ€ 이름이 μ—†μœΌλ―€λ‘œ μ»΄νŒŒμΌλŸ¬κ°€ λžŒλ‹€λ₯Ό μ°Έμ‘°ν•˜λŠ” 이름을 λ§Œλ“€μ–΄λ‚Έλ‹€.

λ”°λΌμ„œ λžŒλ‹€ ν‘œν˜„μ‹κ³Ό κ΄€λ ¨ν•œ μŠ€νƒ νŠΈλ ˆμ΄μŠ€λŠ” μ΄ν•΄ν•˜κΈ° μ–΄λ €μšΈ 수 μžˆλ‹€.

This post is licensed under CC BY 4.0 by the author.