
aka. 중첩 클래스
종류 : 인스턴스 내부 클래스, 정적(static) 내부 클래스, 지역(local) 내부 클래스, 익명(anonymous) 내부 클래스
// 외부 클래스를 이용하여 내부 클래스 생성
OutClass outClass = new OutClass();
OutClass.InClass inClass = outClass.new InClass();
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass(){
inClass = new InClass(); // 내부 클래스 생성
}
class InClass{
int inNum = 100;
//static int sInNum = 200; //에러 남
//static void sTest(){ //에러 남
//} //인스턴스 내부클래스에서는 정적변수,함수 선언 불가
void inTest(){
System.out.println("OutClass num = " +num + "(외부 클래스의 인스턴스 변수)");
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 스태틱 변수)");
System.out.println("InClass inNum = " + inNum + "(내부 클래스의 인스턴스 변수)");
}
}
public void usingClass(){
inClass.inTest(); //외부 클래스에서 내부 클래스 변수를 사용하여 메서드 호출하기
}
}
//외부 클래스 생성하지 않고 바로 정적 내부 클래스 생성
OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass(){
inClass = new InClass(); // 내부 클래스 생성
}
static class InStaticClass{
int inNum = 100;
static int sInNum = 200;
void inTest(){ //정적 클래스의 일반 메서드
//num += 10; // 외부 클래스의 인스턴스 변수는 사용할 수 없음.
System.out.println("InStaticClass inNum = " + inNum + "(내부 클래스의 인스턴스 변수 사용)");
System.out.println("InStaticClass sInNum = " + sInNum + "(내부 클래스의 스태틱 변수 사용)");
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 스태틱 변수 사용)");
}
static void sTest(){ // 정적 클래스의 static 메서드
//num += 10; // 외부 클래스의 인스턴스 변수는 사용할 수 없음.
//inNum += 10; // 내부 클래스의 인스턴스 변수는 사용할 수 없음
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 스태틱 변수 사용)");
System.out.println("InStaticClass sInNum = " + sInNum + "(내부 클래스의 스태틱 변수 사용)");
}
}
}
//외부클래스 이용하여 내부클래스 메소드 실행
Outer out = new Outer();
Runnable runner = out.getRunnable(10);
runner.run();
class Outer{
int outNum = 100;
static int sNum = 200;
Runnable getRunnable(final int i){ //final 선언 해야함
final int num = 100; //final 선언 해야함
class MyRunnable implements Runnable{
int localNum = 10;
@Override
public void run() {
outNum = 5;
//num = 200; //에러 남. 지역변수(함수 내에서 선언된 변수)는 상수로 바뀜
//i = 100; //에러 남. 매개 변수 역시 지역변수처럼 상수로 바뀜,
//num, i는 메소드가 실행되는 동안 Stack에 쌓이고, 함수 실행이 끝나면, Stack에서 해제된다.
//getRunnable()메소드와 MyRunnalbe의 클래스의 실행 주기가 달라서, 내구 클래스에서 stack에 할당 된 변수를 사용하면 안된다. 따라서 final 처치 해야함.
//즉, 사용하는 것은 OK, 변경하는 것은 안됨
System.out.println("i =" + i);
System.out.println("num = " +num);
System.out.println("localNum = " +localNum);
System.out.println("outNum = " + outNum + "(외부 클래스 인스턴스 변수)");
System.out.println("Outter.sNum = " + Outer.sNum + "(외부 클래스 정적 변수)");
}
}
return new MyRunnable();
}
}
Outer out = new Outer();
Runnable runner = out.getRunnable(10);
runner.run();
Runnable runner = new Runnable(){
int localNum = 10;
@Override
public void run() {
System.out.println("localNum = " +localNum);
}
};
runner.run();
Runnable runner = ()->{
int localNum = 10;
System.out.println("localNum = " +localNum);
};
runner.run();