클래스 안의 클래스
내부클래스에서 외부클래스의 멤버들을 쉽게 접근할 수 있다
코드의 복잡성을 줄일 수 있다(캡슐화)
내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일 ☞ private, default, protected, public
static 내부 클래스만 static 멤버를 정의할 수 있다
static 내부 클래스에서는 외부 클래스의 instance 멤버에 접근할 수 없다
단, 상수인 경우에는 static 허용
instance 멤버는 static멤버에 접근할 수 있지만, 그 반대는 불가하다
❗️내부 클래스에서 외부 클래스의 private 멤버에 접근 가능하다.
❗️내부클래스는 외부 클래스의 지역변수 중 final이 붙은 상수에만 접근가능하다
외부 클래스의 객체를 먼저 만들어야 내부 클래스의 객체를 만들 수 있다.
동일 변수명일 경우 구분: 지역변수 변수명
- 내부 인스턴스변수 this.변수명
- 외부 인스턴스변수 클래스명.this.변수명
이름이 없는 일회용 클래스. 정의와 생성을 동시에 한다.
new 조상클래스이름() { // 내용 }
or
new 구현인터페이스이름() { // 내용 }
Object iv = new Object() { void method(){} }; //익명클래스
static Object cv = new Object(){ void method(){} }; //익명클래스
void myMethod() {
Object lv = new Object() { void method(){} }; //익명클래스
}
에러 - 프로그램 코드에 의해 수습될 수 없는 심각한 오류
예외 - 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것
☞ 프로그램의 비정상 종료를 막고 정상적인 실행상태를 유지하는 것
Throwable : 모든 오류의 조상 클래스
Exception
⎻ Exception 클래스와 자손들 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
⎻ RuntimeException 클래스와 자손들 : 프로그래머의 실수로 발생하는 예외
try {
} catch (Exception1 e1) {
} catch (Exception e2) {
}
if 문과 달리 블럭 내 포함된 문장이 하나 뿐이라도 괄호 생략 불가하다
Exception이 선언된 catch블럭은 모든 예외의 조상이므로, 가장 마지막에 위치할 수 있도록 한다(모든 예외의 처리가 가능하다)
printStackTrace()
예외 발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다
getMessage()
발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다
내용이 같은 catch 블럭을 하나로 합친 것
try {
} catch (ExceptionA | ExceptionB e){
}
두 예외가 부모 자식 관계일 경우 에러 ☞ 그냥 부모타입 에러만 명시해도 무방하다
ExceptionA에만 선언된 메서드는 호출 불가하다 (두 종류의 Exception이 모두 들어올 수 있기에 공통 멤버만 사용 가능하다)
try {
Exception e = new Exception("고의 발생");
throw e;
// throw new Exception();
}
catch (Exception e) {
System.out.println("에러메시지: "+ e.getMessage());
e.printStackTrace();
}
System.out.println("프로그램이 정상 종료되었음");
checked 예외
컴파일러가 예외처리 여부를 체크한다 (예외처리 필수), 예외처리 안할 시 컴파일이 안된다
☞ Exception 클래스와 그 자손
unchecked 예외
컴파일러가 예외처리 여부를 체크하지 않는다 (예외처리 선택), 예외처리 안해도 컴파일은 된다
☞ RuntimeException 클래스와 그 자손
메서드가 호출 시 발생가능한 예외를 호출하는 쪽에 알리는 것
void method() throws Exception1, Exception2, .. ExceptionN {
}
void method() throws Exception {
}
throw (예외를 발생시킨다) vs throws (예외를 메서드에 선언할 때 사용)
예외 발생여부와 관계없이 수행되어야 하는 코드를 넣는다
try {
startInstall();
copyFiles();
} catch (Exception e) {
e.printStackTrace();
} finally {
deleteTempFiles();
}
사용자가 직접 예외 클래스를 정의할 수 있다
조상은 Exception과 RuntimeException 중에서 선택한다
예외를 처리한 후에 다시 예외를 발생시키는 것
☞ 호출한 메서드와 호출된 메서드 양쪽 모두에서 예외처리하는 것
한 예외가 다른 예외를 발생시킬 수 있다
예외 A가 예외 B를 발생시킨다면, A는 B의 원인 예외라고 한다.
Throwable initCause(Throwable cause) // 지정한 예외를 원인 예외로 등록
Throwable getCause() // 원인 예외를 반환
void install() throws InstallException {
try {
startInstall();
copyFiles();
} catch (SpaceException e) { // 예외 연결
InstallException ie = new InstallException("설치 중 예외발생"); // 예외 생성
ie.initCause(e); // InstallException의 원인 예외를 SpaceException으로 지정
throw ie; // InstallException 발생
} catch (MemoryException me) {
...
}
try {
install();
} catch(InstallException e) { //InstallException만 처리해주면 된다
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}