중첩 클래스/인터페이스
: 클래스 내부에 선언한 클래스/인터페이스
class ClassName {
class NestedClassName { // 중첩 클래스 예시
...
}
interface NestedInterfaceName { // 중첩 인터페이스 예시
...
}
}
- 장점
1. 두 클래스의 멤버들에 쉽게 접근 가능
2. 코드 복잡성 감소
중첩 클래스
- 멤버 클래스
1. 인스턴스 멤버 클래스
: 인스턴스 필드와 메소드 선언 가능(정적 필드/메소드는 X)
외부에서 접근시 A 객체를 먼저 생성하고 B 객체를 생성한 후에 사용 가능
→ 장점: 바깥 클래스 접근 가능
// 인스턴스 멤버 클래스 예시
class A {
class B {
B() { ... }
int field;
void method1() { ... }
}
}
2. 정적 멤버 클래스
: static 클래스로 선언된 클래스, 모든 종류의 필드와 메소드 선언 가능
외부에서 접근시 A 객체를 먼저 생성하지 않고 B 객체를 생성하면 사용 가능
→ 단점: 바깥 클래스 접근 불가
// 정적 멤버 클래스 예시
class A {
class B {
B() { ... }
int field;
static int field2;
void method1() { ... }
static void method2() { ... }
}
}
- 로컬 클래스
: 메소드 내에서 생성된 클래스, 메소드가 실행될 때만 사용 가능
접근 제한자 불가(static, private, public X)
인스턴스 필드/메소드만 선언 가능
메소드 종료 시 로컬 클래스 객체는 남아있지만 로컬 변수, 매개변수는 사라짐
→ 로컬 변수, 매개변수의 기억 장소를 로컬 클래스 내부에 복사하여 final로 선언하여 값 보존
void method() {
class D {
D() { ... }
int field; // final 특성을 가짐
void method1() { ... }
}
D d = new D(); // 메소드 내에서 객체 생성 및 사용
d.field = 3;
d.method1();
}
인스턴스 멤버 클래스 | 정적 멤버 클래스 | 로컬 클래스 | |
외부 클래스 접근 |
바깥 클래스 접근 가능 | 바깥 클래스 접근 불가 | 바깥 클래스 접근 가능 |
선언 | 인스턴스 필드/메소드만 선언 가능 | 모든 필드/메소드 선언 가능 | 인스턴스 필드/메소드만 선언 가능 |
중첩 클래스에서의 this
- 중첩 클래스 내부에서 this 키워드를 사용하면 중첩 클래스 내를 가리킴
- 중첩 클래스 외부의 필드, 메소드를 얻고 싶으면 외부클래스명.this.* 로 가져오면 됨
중첩 인터페이스
: 클래스의 멤버로 선언된 인터페이스, 이벤트 처리 목적으로 사용
// 이벤트 예시
public class Button {
OnClickListener listener;
void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
void touch() {
listener.onClick();
}
interface OnclickListener { // 중첩 인터페이스
void onClick();
}
}
익명 객체
: 이름이 없는 객체, 단독 생성 불가, 인터페이스나 클래스에서 사용
주로 필드의 초기값, 로컬 변수의 초기값, 매개변수의 매개값으로 대입
생성자 선언 불가(필드, 메소드만 가능)
메소드 종료 시 로컬 클래스 객체는 남아있지만 로컬 변수, 매개변수는 사라짐
→ 로컬 변수, 매개변수의 기억 장소를 로컬 클래스 내부에 복사하여 final로 선언하여 값 보존
- 생성
Parent p = new Parent(매개변수1, 매개변수2, ...) {
// 필드
// 메소드
};
- 익명 자식 객체에 새롭게 정의된 필드/메소드는 익명 자식 객체 내부에서만 사용
- 인터페이스형 익명 객체 구현 시, 인터페이스 내의 모든 추상 메소드들의 실체 메소드를 작성해야 함
예외 처리
- 일반 예외(Exception)
: Exception을 상속받는 클래스
자바 소스를 컴파일하는 과정에서 체크
- 실행 예외(Runtime Exception)
: RuntimeException을 상속받는 클래스
자바 컴파일러가 체크하지 않음
→ 종류
이름 | 설명 |
NullPointerException | null값을 갖는 참조 변수로 객체 접근시 발생(객체가 없는 상태에서 객체 사용) |
ArrayIndexOutOfBoundsException | 배열 인덱스 범위 초과 |
NumberFormatException | 숫자로 변환될 수 없는 문자를 포함한 문자열을 숫자로 변환하는 경우 발생 |
ClassCastException | 상속 및 구현 관계를 무시하고 타입 변환하는 경우 발생 |
ClassNotFountException | 클래스가 존재하지 않는 경우 발생 |
예외 처리 코드
: try - catch - finally 블록 이용
- 다중 catch
: 예외 처리는 한 번만 실행되므로 상위 예외 클래스(Exception)가 하위 예외 클래스보다 아래에 위치해야 함
- 멀티 catch
: 하나의 블록에서 여러 예외 동시에 처리
ex) try { ... } catch(ArrayIndexOutOfBoundsException | NumberFormatException) { ... }
자동 리소스 닫기
: try - with - resources 블록 이용
// 자동 리소스 닫기 예제
public class FileInputStream implements AutoCloseable {
private String file;
public FileInputStream(String file) {
this.file = file;
}
public void read() {
sout(file + "을 읽습니다.");
}
public void close() throws Exception {
// try 블록에서 파일 읽기가 종료된 후 throw new Exception();으로 실행
sout(file + "을 닫습니다.");
}
}
- 조건: AutoCloseable 인터페이스를 구현해야 함
예외 떠넘기기
: throws 키워드 사용
public void method(String str, ...) throws Exception { ... } // 모든 예외를 호출한 곳으로 떠넘김
public void method(String str, ...) throws NumberFormatException { ... } // 명시한 예외만 떠넘김
→ 호출한 곳으로 예외 처리를 떠넘겼으므로 호출한 곳에서 try - catch 블록을 사용해서 예외를 처리해주어야 함
사용자 정의 예외
: 어플리케이션 예외는 사용자가 직접 정의해서 만들어야 함
일반 예외는 Exception, 실행 예외는 RuntimeException을 상속
// 사용자 정의 예외 예시
public class BalanceInsufficientException extends Exception {
public BalanceInsufficientException() { ... }
public BalanceInsufficientException(String message) { super(message); }
}
예외 발생시키기
: throw new 예외명(); 또는 throw new 예외명("메시지");
예외 정보 얻기
1. 예외가 가진 메시지 얻기
: e.getMessage();
2. 예외 발생경로 추적
: e.printStackTrace();
'Language > Java' 카테고리의 다른 글
Java - 멀티 스레드 정리 (0) | 2021.07.02 |
---|---|
Java - 기본 API 클래스 정리 (0) | 2021.06.25 |
Java - 인터페이스 복습 (0) | 2021.06.24 |
Java - 상속 복습 (0) | 2021.06.23 |
Java - 클래스 복습 (0) | 2021.06.22 |