Language/Java

Java - 중첩 클래스와 중첩 인터페이스, 예외 처리 복습

둉이 2021. 6. 25. 10:10

 

중첩 클래스/인터페이스

: 클래스 내부에 선언한 클래스/인터페이스

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