Java & Kotlin
[Java 기능] 중첩 클래스 (2)
Sue
2022. 2. 14. 18:58
지역 내부 클래스
- 메서드 내부에 정의하여 사용하는 클래스
- 메서드의 호출이 끝나면 지역변수의 유효성은 사라짐
- 반면 지역 내부 클래스 안에서 사용되는 메서드의 지역 변수나 매개변수는 final로 선언됨
AnonymousInnerTest.java
- Runnable : 클래스를 쓰레드화 하는데 필요한 run 메서드를 구현할 때 사용하는 인터페이스
- 지역변수는 메서드가 호출될 때 생성되고 호출이 끝나면 소멸됨 (스택 메모리에 존재)
- 하지만 지역 내부 클래스의 run() 메서드는 getRunnable 메서드가 호출되고 난 후에도 또 호출될 수 있음
- 따라서 컴파일러가 자동으로 매개변수와 지역변수를 final로 설정함 → 변수의 값을 바꿀 수 없음
- MyRunnable 클래스를 사용하려면 getRunnable 메서드를 호출하여 생성된 개체를 반환받아야 함 (직접 생성x)
package ch01;
class Outer2{
int outNum = 100;
static int sNum = 200;
Runnable getRunnable(int i) {
int num = 10;
class MyRunnable implements Runnable { // 지역 내부 클래스
int localNum = 1000;
@Override
public void run() {
// i = 50; 값 변경시 오류
// num = 20;
System.out.println("i =" + i);
System.out.println("num =" + num);
System.out.println("localNum =" + localNum);
System.out.println("outNum =" + outNum + "(외부 클래스 인스턴스 변수)");
System.out.println("Outer.sNum =" + Outer2.sNum + "(외부 클래스 정적 변수)");
}
}
return new MyRunnable();
}
}
public class AnonymousInnerTest {
public static void main(String[] args) {
Outer2 out = new Outer2();
Runnable runner = out.getRunnable(100); // getRunnable 메서드 실행하여 개체 반환
runner.run();
}
}
수행 결과
i =100
num =10
localNum =1000
outNum =100(외부 클래스 인스턴스 변수)
Outer.sNum =200(외부 클래스 정적 변수)
익명 내부 클래스
- 이름이 없는 클래스
- 클래스의 이름을 생략하고 주로 하나의 인터페이스 혹은 추상 클래스를 구현하여 반환
- 인터페이스나 추상 클래스의 자료형 변수에 직접 대입하여 클래스를 생성하거나 지역 내부 클래스의 메서드 내부에서 생성하여 반환할 수 있음
- 안드로이드 프로그래밍에서 widget의 이벤트 핸들러에 활용됨
익명 내부 클래스
- 위의 코드에서 MyRunnable 클래스는 다른 곳에서 호출 될 일이 없음 (클래스 이름의 필요성 x)
Runnable getRunnable(int i) {
int num = 10;
return new Runnable() { // 1. Runnable 인터페이스를 구현하여 바로 반환
int localNum = 1000;
@Override
public void run() {
// i = 50; 값 변경시 오류
// num = 20;
System.out.println("i =" + i);
System.out.println("num =" + num);
System.out.println("localNum =" + localNum);
System.out.println("outNum =" + outNum + "(외부 클래스 인스턴스 변수)");
System.out.println("Outer.sNum =" + Outer2.sNum + "(외부 클래스 정적 변수)");
}
};
}
Runnable runnable = new Runnable() { // 2. Runnable 인터페이스에 대한 인스턴스 변수를 선언해서 implement
@Override
public void run() {
System.out.println("Runnable class");
}
};
public class AnonymousInnerTest {
public static void main(String[] args) {
Outer2 out = new Outer2();
Runnable runner = out.getRunnable(100);
runner.run();
out.runnable.run();
}
}
수행 결과
i =100
num =10
localNum =1000
outNum =100(외부 클래스 인스턴스 변수)
Outer.sNum =200(외부 클래스 정적 변수)
Runnable class