🥤 내부클래스란?
- 클래스 안의 클래스
일반. class A { ... } class B { ... // A의 객체를 생성해야 쓸수있음. }
내부 클래스 class A { // B의 외부클래스 ... class B { // A의 내부 클래스 ... // 객체생성없이 A의 멤버 접근가능 } }
👉내부 클래스의 장점
-> 내부클래스에서 외부클래스의 멤버들을 쉽게 접근할 수 있다.
-> 코드의 복잡성을 줄일 수 있다. (캡슐화)
🥤 내부 클래스의 제어자와 접근성
- 내부클래스의 제어자는 변수에 사용 가능한 제어자와 동일
- 내부클래스에서는 외부클래스의 private멤버도 접근 가능
- 지역 외부클래스에서는 상수만 접근 가능
public class InnerEx1 { // 인스터스 클래스 class InstanceInner{ int iv = 100; static int cv = 100; // 에러. static 변수선언 불가능 final static int CONST = 100;// final static은 상수여서 가능. } //static 클래스 static class StaticInner{ int iv = 200; static int cv = 200; //static클래스만 static멤버 정의가능 } void myMethod(){ // 지역클래스. 메서드 내부에 존재하므로 InnerEx1객체가 우선 생성이 되어야만 // 메서드가 사용될수 있기때문에 사용불가능. class LocalInner { int iv = 300; static int cv = 300; // 에러. static변수 선언 불가능 final static int CONST = 300; } }
🥤 프로그램오류
1. 컴파일 에러 - 컴파일할 때 발생
->javac.exe 자바컴파일러
1) 구문체크 2) 번역 3) 최적화
2. 런타임 에러 - 실행 중 발생 (프로그램 종료)
-> Error : 심각한 에러(수습 불가능)
-> Exception : 미약한 에러(수습 가능)
3. 논리적 에러 - 작성 의도와 다르게 동작 (프로그램 종료X)
.
🥤 예외처리?
-> 프로그램 실행시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
-> 프로그램의 비정상 종료를 막기
🥤 예외처리구문 try - catch
try { // 예외가 발생할 가능성 있는 문장 넣기 } catch (Exception1 e1) { // Exception1 발생하면, 이를 처리할 문장 적기 } catch (Exception2 e2) { // Exception2 발생하면, 이를 처리할 문장 적기 } catch (ExceptionN eN) { // ExceptionN 발생하면, 이를 처리할 문장 적기 } // { } 괄호 생략 불가
🥤 try - catch문에서의 흐름
👉 try 블럭 내에서 예외가 발생한 경우,
1. 발생한 예외와 일치하는 catch블럭이 있는지 확인
2.일치하는 catch블럭을 찾게되면, 그 catch블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행.
만일 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못한다.public static void main(String[] args) { String str = null; try { System.out.println(str.toString()); } catch(Exception e) { // e 매개변수에 위의 예외에 관한 정보가 제공. System.out.println("예외원인: " + e); } System.out.println("프로그램 종료"); } // 결과: 예외원인: java.lang.NullPointerException 프로그램 종료 // 객체가 null인 상태에서는 참조를 할 수가 없다. 그래서 예외가 발생됨.
👉 try 블럭 내에서 예외가 발생하지 않은 경우,
catch 블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속한다.public static void main(String[] args) { String str = "Hello World Java!!"; try { System.out.println(str.toString()); } catch(Exception e) { System.out.println("테스트"); } System.out.println("프로그램 종료"); } // 결과: Hello World Java!! 프로그램 종료
🥤 printStackTrace() & getMessage()
printStackTrace()
: 예외발생 당시의 호출스택(Call stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력
getMessage()
: 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있음.
🥤 멀티 catch블럭
- 내용이 같은 catch블럭을 하나로 합친것
try{ ... }catch(ExceptionA e) { e.printStackTrace(); }catch(ExceptionB e2){ e2.printStackTrace(); }
👇👇👇👇👇
try{ ... } catch(ExceptionA | ExceptionB e) { e.printStackTrace(); }
부모자식관계 안됨! try{ ... //}catch(ParentException | ChildException e) { // 에러! } catch (ParentException e) { // ok. 위의 라인과 의미상 동일 e.printStackTrace(); }
🥤 예외 발생시키기
- 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음
ex> Exception e = new Exception("고의로 발생시켰음");- 키워드 throw를 이용해서 예외를 발생시킨다.
ex> throw e;
🥤 checked예외, unchecked예외
- checked예외 : 컴파일러가 예외처리 여부를 체크 (예외처리 필수)
- unchecked예외 : 컴파일러가 예외처리 여부를 체크 안함(예외처리 선택)
🥤 메서드에 예외 선언하기
- 예외를 처리하는 방법 : try-catch문(직접처리), 예외 선언하기(예외 떠넘기기,알리기)
- 메서드가 호출시 발생가능한 예외를 호출하는 쪽에 알리는 것
void method"() throws Exception1, Exception2,...ExceptionN { // 메서드 내용 }
📌참고> 잘 구별하기!
-> 예외를 발생시키는 키워드는 throw
-> 예외를 메서드에 선언할 때 쓰이는 throws
🥤 finally 블럭
- 예외 발생여부와 관계없이 수행되어야 하는 코드를 넣는다.
try { // 예외가 발생할 가능성이 있는 문장들 넣기 } catch(Exception e) { // 예외처리를 위한 문장 적기 } finally { // 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들 넣기 // finally블럭은 try-catch문의 맨 마지막에 위치 }
📌참고>
try블럭 안에 return문이 있어서 try블럭을 벗어나갈 때도 finally블럭이 실행됨.
🥤 참고
책: Java의 정석