클래스 내부에 선언한 클래스로 이 클래스를 감싸고 있는 외부 클래스와 밀접한 연관이 있는 경우가 많고, 다른 외부 클래스에서 사용할 일이 거의 없는 경우에 사용한다. 중첩 클래스라고도 한다. 내부 클래스에서 외부 클래스의 멤버들에 쉽게 접근할 수 있고 코드의 복잡성도 줄일 수 있다.
[내부 클래스 종류]
종류 사용 가능한 변수 인스턴스 내부 클래스 외부 인스턴스 변수, 외부 전역 변수 정적 내부 클래스 외부 전역 변수 지역 내부 클래스 외부 인스턴스 변수, 외부 전역변수 익명 내부 클래스 외부 인스턴스 변수, 외부 전역변수
public class Outer {
private int num = 1;
private static int staticNum = 2;
public Outer(){
// Outer 생성자에서 Inner 생성자 호출
inner = new Inner();
}
private Inner inner;
// 인스턴스 내부 클래스는 캡슐화를 지키기 위해 웬만하면 private로!
private class Inner {
private int inum = 3;
// 사용 불가!, 외부 클래스가 생성되어야 내부 클래스가 생성될 수 있기 때문
// private static int staticiNum = 4;
private static final int STATIC_FINAL = 5;
public void innerTest() {
System.out.println(num); // 외부 인스턴스 변수 출력
System.out.println(staticNum); // 외부 static 변수 출력
System.out.println(inum); // 내부 인스턴스 변수 출력
// System.out.println(staticiNum); // 내부 static 변수 출력 불가
System.out.println(STATIC_FINAL); // 내부 상수 출력
}
public Inner(){}
}
public void outerTest() {
inner.innerTest();
}
}
public void outerTest() {
inner.innerTest();
}
}
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
outer.outerTest();
}
}
public class Outer {
private int num = 1;
private static int staticNum = 2;
public Outer(){
// Outer 생성자에서 Inner 생성자 호출
inner = new Inner();
}
private Inner inner;
// 내부 정적 클래스(static)
public static class Inner {
private int inum = 3;
private static int staticiNum = 4;
private static final int STATIC_FINAL = 5;
public void innerTest() {
// System.out.println(num); // 외부 인스턴스 변수 출력 불가, 정적 내부 클래스가 먼저 메모리에 할당되었기 때문에
System.out.println(staticNum); // 외부 static 변수 출력
System.out.println(inum); // 내부 인스턴스 변수 출력
System.out.println(staticiNum); // 내부 static 변수 출력
System.out.println(STATIC_FINAL); // 내부 상수 출력
}
public Inner(){}
public static void innerStaticTest() {
// System.out.println(inum); // static 메서드 내에서는 인스턴스 변수 사용 불가
System.out.println(staticNum);
System.out.println(staticiNum);
System.out.println(STATIC_FINAL);
}
}
public void outerTest() {
inner.innerTest();
}
}
public class Main {
public static void main(String[] args) {
}
}
public class Main {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.innerTest();
}
}
외부 클래스의 멤버가 아닌 메서드 내에서 정의되는 클래스로 지역 변수와 유사하다. 메서드가 호출될 때 메모리에 로딩되기 때문에 static 키워드를 붙일 수 없다!
public class Outer { //외부 클래스
int num = 5;
void test() {
int num2 = 6;
class LocalInClass { //지역 내부 클래스, 접근 제어자 사용 불가(해당 지역 내에서만 사용가능하기 때문에 큰 의미가 없어서)
void getPrint() { // 접근 제어자 사용 가능
System.out.println(num);
System.out.println(num2);
}
}
LocalInClass localInClass = new LocalInClass();
localInClass.getPrint();
}
}
클래스의 선언과 객체 생성을 동시에 하기 때문에 하나의 객체만 생성 가능하고 일회용이다. 익명이라는 점을 빼면 지역 내부 클래스와 유사하다. 만약 일회성으로 내부 클래스를 사용하려면 코드를 더 간결하게 만들 수 있다.
interface Person {
String name = "test";
void getName();
}
public class Main {
public static void main(String[] args) {
Person obj = new Person() {
public void getName() {
System.out.println("내 이름은 " + name);
}
};
obj.getName();
}
}