Skip to content

Latest commit

Β 

History

History
244 lines (181 loc) Β· 8.97 KB

ExceptionHandling.md

File metadata and controls

244 lines (181 loc) Β· 8.97 KB

μžλ°” Exception 계측 ꡬ쑰

IMAGES

  • Checked Exception은 μ»΄νŒŒμΌμ„ ν•  κ²½μš°μ— μ˜ˆμΈ‘κ°€λŠ₯ν•œ μ˜ˆμ™Έλ‘œ ClassNotFoundException, FileNotFoundException 등이 μžˆλ‹€.
  • UnChecked Exception은 λŸ°νƒ€μž„μ‹œ λ°œμƒν•  μˆ˜λ„ 있고 λ°œμƒν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλŠ” μ˜ˆμ™Έλ‘œ ArithmeticException, NullPointerException 등이 μžˆλ‹€.

μžλ°”μ—μ„œ μ—λŸ¬μ™€ μ˜ˆμ™Έ

  1. μ—λŸ¬λŠ” JVM 싀행에 λ¬Έμ œκ°€ μƒκΈ°λŠ” 것을 λ§ν•˜λ©°, 일반적으둜 κ°œλ°œμžκ°€ 직접 μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•  μˆ˜λŠ” μ—†λ‹€. 보톡 μ‹œμŠ€ν…œμ˜ λ¦¬μ†ŒμŠ€ 문제둜 λ°œμƒν•˜κ²Œ λœλ‹€.(μ‹œμŠ€ν…œ 좩돌, λ©”λͺ¨λ¦¬ λΆ€μ‘± λ“±)
  • 컴파일 μ‹œμ— λ°œμƒν•  수 μ—†λ‹€.

  • OutOfMemory , StackOverflowError 등이 μžˆλ‹€.

  • java.lang.error νŒ¨ν‚€μ§€μ— 쑴재

  1. μ˜ˆμ™ΈλŠ” κ°œλ°œμžκ°€ μž‘μ„±ν•œ μ½”λ“œλ‘œ λ°œμƒν•œλ‹€. 컴파일 및 λŸ°νƒ€μž„μ— λ°œμƒν•˜λŠ” κ²½μš°μ΄λ‹€. κ°œλ°œμžκ°€ μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•  수 μžˆλ‹€. 즉, μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν†΅ν•΄μ„œ λ¬Έμ œκ°€ λ°œμƒν•˜λ”λΌλ„ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ’…λ£Œλ˜μ§€ μ•Šκ³ , ν”„λ‘œκ·Έλž¨μ΄ 정상 λ™μž‘ν•  수 있게 μ²˜λ¦¬κ°€ κ°€λŠ₯ν•˜λ‹€.
  • NullPointerExceoption, SqlException 등이 μžˆλ‹€.

  • java.lang.Exception νŒ¨ν‚€μ§€μ— 쑴재

μ˜ˆμ™Έμ²˜λ¦¬ 방법 1. try-catch-finally

  • tryΒ :Β μ˜ˆμ™Έκ°€ λ°œμƒν•  κ°€λŠ₯성이 μžˆλŠ” λ²”μœ„λ₯Ό μ§€μ •ν•˜λŠ” 블둝이닀.Β try 블둝은 μ΅œμ†Œν•œ ν•˜λ‚˜μ˜Β catch 블둝이 μžˆμ–΄μ•Ό ν•˜λ©°,Β catch 블둝은 try 블둝 λ‹€μŒμ— μœ„μΉ˜ν•œλ‹€.
  • catchΒ :Β λΈ”λ‘μ˜ λ§€κ°œλ³€μˆ˜λŠ” μ˜ˆμ™Έ 객체가 λ°œμƒν–ˆμ„ λ•Œ μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜λͺ…μœΌλ‘œ λ°˜λ“œμ‹œ java.lang.Throwable 클래슀의 ν•˜μœ„ 클래슀 νƒ€μž…μœΌλ‘œ μ„ μ–Έλ˜μ–΄μ•Ό ν•œλ‹€.
  • finallyΒ : 이 블둝은 ν•„μˆ˜ 블둝은 μ•„λ‹ˆλ©°,Β finally 블둝은 catchΒ μœ λ¬΄μ™€ 상관 없이 무쑰건 μˆ˜ν–‰λœλ‹€. 주둜 IO λ˜λŠ” Connection을 close() ν•˜λŠ”λ° μ‚¬μš©λœλ‹€.

μ˜ˆμ™Έμ²˜λ¦¬ 방법 2. throws

public static void main(String[] args) {
        while(true) {
            try {
                A();
            } catch(ArithmeticException e) {
                e.printStackTrace();
            } finally {
                System.out.println("무쑰건 μ‹€ν–‰λ©λ‹ˆλ‹€.");
            }
        }
    }

public static void A() throws ArithmeticException { // μ˜ˆμ™Έ λ°œμƒμ‹œ A() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ κ³³μ—μ„œ μ²˜λ¦¬ν•˜λ„λ‘ 함.
    Scanner scan = new Scanner(System.in);
    int value = scan.nextInt();
    System.out.println(9/value);
}

A λ©”μ„œλ“œμ—μ„œ 였λ₯˜λ₯Ό λ˜μ Έμ€˜μ„œ, A λ₯Ό ν˜ΈμΆœν•œ κ³³μ—μ„œ μ—λŸ¬μ²˜λ¦¬λ₯Ό λŒ€μ‹  ν•˜λŠ” 방법이닀.

단점 : A() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 뢀뢄이 μ—„μ²­ λ§Žλ‹€κ³  μƒκ°ν•΄λ³΄μž. A() κ°€ λ˜μ§„ μ˜ˆμ™Έλ₯Ό μ–΄λ–€ λΆ€λΆ„μ—μ„œ μ²˜λ¦¬ν–ˆλ˜κ±΄μ§€ μΆ”μ ν•˜κΈ°κ°€ νž˜λ“€μ–΄μ§„λ‹€! throws λ₯Ό 많이 μ‚¬μš©ν•˜μ§€ 말자.

λŒ€μ•ˆ : tryλ¬Έ μ•ˆμ—μ„œ λ°œμƒν•˜λŠ” Checked Exception을 catchλ¬Έ μ•ˆμ—μ„œ Unchecked Exception으둜 λ°”κΏ”μ„œ λ˜μ Έμ£ΌλŠ” 방법을 μ μš©ν•΄λ³Ό 수 μžˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄, μ˜ˆμ™Έκ°€ μ–΄λ””μ—μ„œ λ°œμƒν–ˆλŠ”μ§€ μ •ν™•ν•˜κ²Œ μ•Œ μˆ˜κ°€ μžˆλ‹€.

// κΈ°μ‘΄ μ½”λ“œ
public static String A(BufferedReader bufferedReader) throws IOException { // throws μ‚¬μš©
        String requestLine = bufferedReader.readLine();
        return requestLine;
}

// κ°œμ„ ν•œ μ½”λ“œ
public class CustomRuntimeException extends RuntimeException {
    public CustomRuntimeException(String message) {
        super(message);
    }
}
public static String A(BufferedReader bufferedReader) {
    try {
        String requestLine = bufferedReader.readLine();
        return requestLine;
    } catch (IOException e) {
        throw new CustomRuntimeException("μž…λ ₯ 값이 잘λͺ»λ˜μ—ˆμŠ΅λ‹ˆλ‹€."); // 이제 μ‚¬μš©μžκ°€ μž…λ ₯값이 잘λͺ»λ˜μ—ˆλ‹€λŠ” 것을 μ•Œκ³ , μœ νš¨ν•œ μž…λ ₯을 ν•˜κ²Œ λ˜μ–΄ 이 μ—λŸ¬λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.
    }
}

μ˜ˆμ™Έμ²˜λ¦¬ 방법 3. κ°•μ œλ‘œ μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œμΌœμ„œ 처리 (throw)

μž₯점 : μ˜ˆμ™Έκ°€ λ°œμƒν•˜λŠ” κ³³μ—μ„œ μ˜ˆμ™Έκ°€ λ˜μ Έμ§€κΈ°μ— μ˜ˆμ™Έλ₯Ό μΆ”μ ν•˜κΈ° μ’‹λ‹€.

public static void A() {
        Scanner scan = new Scanner(System.in);
        int value = scan.nextInt();
        if (value == 0) {
            throw new ArithmeticException("0으둜 λ‚˜λˆŒ 수 μ—†μŠ΅λ‹ˆλ‹€.");
        }
        System.out.println(9 / value);
}

μžμ›μ— λŒ€ν•œ μ˜ˆμ™Έμ²˜λ¦¬ 방법 : try-with-resources

κ°œμš” : try에 μžμ› 객체λ₯Ό μ „λ‹¬ν•˜λ©΄, try μ½”λ“œ 블둝이 λλ‚˜λ©΄ μžλ™μœΌλ‘œ μžμ›μ„ μ’…λ£Œν•΄μ£ΌλŠ” κΈ°λŠ₯이닀.

// try에 전달할 수 μžˆλŠ” μžμ›μ€ AutoCloseable μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄λ‘œ ν•œμ •λœλ‹€.
try (SomeResource resource = getResource()) {
    use(resource);
} catch(...) {
    ...
}

AutoCloseable μΈν„°νŽ˜μ΄μŠ€λŠ” JDK 1.7 λΆ€ν„° μΆ”κ°€λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.

public interface AutoCloseable {
    void close() throws Exception;
}

try-with-resource λŠ” try( ... ) μ•ˆμ— AutoCloseable 의 κ΅¬ν˜„μ²΄λ₯Ό λ„£μ–΄μ£Όλ©΄, try 블둝이 μ’…λ£Œλ λ•Œ ν•΄λ‹Ή κ΅¬ν˜„μ²΄μ˜ close() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ£ΌλŠ” κΈ°λŠ₯이라고 보면 λœλ‹€.

λ§Œμ•½ 이 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ λ‹€μŒκ³Ό 같이 μ½”λ“œλ₯Ό μž‘μ„±ν–ˆμ„ 것이닀.

SomeResource resource = null;
try {
    resource = getResource();
    use(resource);
} catch(...) {
    ...
} finally {
    if (resource != null) {
        try { 
            resource.close(); 
        } catch(...) { 
            /* 아무것도 μ•ˆ 함 */ 
        }
    }
}

μ£Όμ˜μ‚¬ν•­

λ³€μˆ˜λ₯Ό λ§Œλ“€μ§€ μ•Šμ€ μƒνƒœλ‘œ μ‚¬μš©ν•  경우 close() λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ§€μ•ŠλŠ”λ‹€. μ•„λž˜ μ˜ˆμ œμ½”λ“œλ₯Ό λ³΄λ©΄μ„œ μ΄ν•΄ν•˜μž.

public static void main(String[] args) {
    try(B b = new B(new A())){

    }catch(Exception e){

    }
}

// A, B λŠ” λͺ¨λ‘ AutoCloseable λ₯Ό μƒμ†λ°›μ•˜λ‹€. ν•˜μ§€λ§Œ, μ΄λ•Œ A의 closeλŠ” ν˜ΈμΆœλ˜μ§€ μ•ŠλŠ”λ‹€.
// μ—¬κΈ°μ„œλŠ” B의 close 만 ν˜ΈμΆœλœλ‹€.
// A 도 ν˜ΈμΆœν•˜κΈ°μœ„ν•΄μ„œλŠ” A μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ₯Ό 생성해주어야 ν•œλ‹€.

public static void main(String[] args) {
    try(A a = new A();
        B b = new B(a)){

    }catch(Exception e){

    }
}

μ˜ˆμ™Έμ²˜λ¦¬ 방법 정리

μ˜ˆμ™Έκ°€ λ°œμƒν•  여지가 μžˆλŠ”Β λ©”μ„œλ“œ(A)λ₯Ό ν˜ΈμΆœν•˜λŠ”Β λ©”μ„œλ“œ(B)κ°€ μžˆλ‹€κ³  ν•˜μž.

  • B κ°€ Aμ—μ„œ λ˜μ§„ μ˜ˆμ™Έλ₯Ό ν™œμš©ν•΄ 무엇인가 의미 μžˆλŠ” μž‘μ—…(μ—λŸ¬ μƒν™©μ΄λ‚˜ 문제λ₯Ό ν•΄κ²°)을 ν•  수 μžˆλ‹€λ©΄ Checked Exception 으둜 처리
  • B κ°€ Aμ—μ„œ λ˜μ§„ μ˜ˆμ™Έλ₯Ό ν™œμš©ν•΄μ„œ μ•„λ¬΄λŸ° μž‘μ—…λ„ ν•  수 μ—†λ‹€λ©΄ Unchecked Exception 으둜 처리
  • λ‘˜ 쀑 μ–΄λ–€ 상황인지 ν™•μ‹€ν•˜κ²Œ κ²°μ •ν•  수 μ—†λ‹€λ©΄ Unchecked Exception 으둜 처리

μžλ°”μ—μ„œ null을 μ•ˆμ „ν•˜κ²Œ λ‹€λ£¨λŠ” 방법?

  1. λ©”μ†Œλ“œμ˜ 인자λ₯Ό 받을 λ•ŒΒ Objects.requireNonNull()을 μ‚¬μš©ν•˜μ—¬ λ°©μ–΄ν•  수 μžˆλ‹€.

μž₯점 1 : μ½”λ“œ μƒμ—μ„œ ν•΄λ‹Ή 객체가 null이 μ•„λ‹ˆμ–΄μ•Ό 함을 λͺ…μ‹œμ μœΌλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€.

public class A {
	String name;
}

public class B {
    A a;

    public B(A a) {
        this.a = Objects.requireNonNull(a);
    }
}

// requireNonNull μ°Έκ³  μ½”λ“œ
public static <T> T requireNonNull(T obj) {
      if (obj == null)
          throw new NullPointerException();
      return obj;
}

μž₯점 2 : fail-fast(μž₯μ• κ°€ λ°œμƒν•œ μ‹œμ μ—μ„œ μ¦‰μ‹œ νŒŒμ•…ν•  수 μžˆλŠ” 것)

public class C{
    A a;

    public C(A a) {
        this.a = a;     //Objects.requireNonNull μ‚¬μš©x
    }
    //...getter
}

A a = null;
C c = new C(a);
c.getA();      // 객체 생성 이후에 늦게 NPE λ°œμƒ

requireNonNull 을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , 객체 생성 이후에 늦게 μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€λ©΄, μ‹œμŠ€ν…œμ΄ λ³΅μž‘ν•΄ 질수둝 μž₯μ• λ₯Ό λ°œκ²¬ν•˜κΈ° μ–΄λ ΅κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

  1. Optional을 μ‚¬μš©ν•΄Β λ¦¬ν„΄ νƒ€μž…μ—μ„œ null을 λ°˜ν™˜ν•˜μ§€ μ•Šλ„λ‘ λ°©μ–΄ν•  수 μžˆλ‹€.
  • Optional : java 8 μ—μ„œ μΆ”κ°€λ˜μ—ˆμœΌλ©°, 객체λ₯Ό Optional 둜 κ°μ‹Έλ©΄μ„œ NullpointerException 을 ν•΄κ²°ν•  수 μžˆλŠ” 방법을 μ œκ³΅ν•΄μ€€λ‹€.
  • Optional 은 주둜 λ¦¬ν„΄νƒ€μž…μ— μ‚¬μš©λ˜λŠ” 것이 ꢌμž₯λœλ‹€.
  • ofNullable, orElse, orElseGet λ“± 을 직접 μ‚¬μš©ν•΄λ³΄μ‹œλŠ” 것을 μΆ”μ²œν•©λ‹ˆλ‹€.

Optional μ°Έκ³  μ‚¬μ΄νŠΈ

  1. μžλ°” 9 λΆ€ν„°λŠ” μ•„λž˜ λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜λ©΄μ„œ, Optional κ³Ό λΉ„μŠ·ν•˜κ²Œ μ‚¬μš©κ°€λŠ₯ν•˜λ‹€.
requireNonNullElseGet(T obj, Supplier<? extends T> supplier)

Reference