자바(Java)는 객체지향 프로그래밍 언어로, 클래스와 객체를 기반으로 한 구조를 가진다. 자바에서는 클래스 내부에 또 다른 클래스를 선언할 수 있는데, 이를 이너 클래스(Inner Class)라고 한다. 이너 클래스는 특정 클래스 내부에서만 사용되는 클래스를 정의할 때 유용하며, 외부 클래스와 밀접한 관계를 형성하여 외부 클래스의 멤버 변수나 메서드에 손쉽게 접근할 수 있다.
이 글에서는 자바의 이너 클래스가 무엇인지, 이너 클래스의 종류, 장단점, 그리고 주의해야 할 사항을 설명하고, 각 이너 클래스의 예제를 코드와 함께 제공한다.
1. 이너 클래스(Inner Class)란 무엇인가?
이너 클래스는 클래스 내부에 선언된 클래스로, 외부 클래스와 밀접하게 연관된 작업을 수행할 때 유용하게 사용된다. 이너 클래스는 외부 클래스의 멤버 변수와 메서드에 쉽게 접근할 수 있으며, 외부 클래스에서 이너 클래스를 통해 특정 기능을 모듈화하거나 캡슐화할 수 있다.
이너 클래스는 다음과 같은 상황에서 사용하면 효과적이다:
- 논리적 그룹화: 관련된 클래스들을 한 곳에 모아 가독성과 유지보수성을 높인다.
- 캡슐화: 외부 클래스의 특정 멤버에 대한 접근을 제한하고, 클래스 간의 상호작용을 정의하여 코드를 더욱 안전하게 만든다.
- 외부 클래스의 데이터 접근: 외부 클래스의 멤버(변수와 메서드)에 손쉽게 접근할 수 있어 특정 로직의 구현이 간결해진다.
2. 자바의 이너 클래스 종류
자바에서 이너 클래스는 크게 네 가지로 나눌 수 있다:
- 멤버 이너 클래스 (Member Inner Class)
- 정적 이너 클래스 (Static Inner Class)
- 지역 이너 클래스 (Local Inner Class)
- 익명 이너 클래스 (Anonymous Inner Class)
각 이너 클래스의 특성과 예제를 통해 이너 클래스가 어떻게 사용되는지 알아보자.
2.1 멤버 이너 클래스 (Member Inner Class)
멤버 이너 클래스는 외부 클래스의 멤버 변수나 메서드처럼 외부 클래스 내부에 선언되는 클래스이다. 멤버 이너 클래스는 외부 클래스의 모든 멤버(정적(static) 멤버 제외)에 접근할 수 있으며, 외부 클래스의 인스턴스가 생성되어야만 사용할 수 있다.
다음은 멤버 이너 클래스의 예제이다.
public class OuterClass {
private int outerVariable = 10;
// 멤버 이너 클래스
public class InnerClass {
public void display() {
System.out.println("외부 클래스 변수 값: " + outerVariable);
}
}
public static void main(String[] args) {
// 외부 클래스의 인스턴스 생성
OuterClass outer = new OuterClass();
// 외부 클래스의 인스턴스를 통해 내부 클래스 인스턴스 생성
InnerClass inner = outer.new InnerClass();
inner.display(); // 출력: 외부 클래스 변수 값: 10
}
}
특징:
- 멤버 이너 클래스는 외부 클래스의 인스턴스를 통해 접근해야 한다.
- 외부 클래스의 모든 멤버 변수와 메서드에 접근 가능하다.
- 외부 클래스와 강하게 결합되어 있으며, 외부 클래스가 소멸될 때 함께 소멸된다.
2.2 정적 이너 클래스 (Static Inner Class)
정적(static) 이너 클래스는 외부 클래스의 인스턴스와 무관하게 독립적으로 생성될 수 있는 이너 클래스이다. 외부 클래스의 정적 멤버(static member)처럼 작동하며, 외부 클래스의 인스턴스 없이 정적 메서드나 변수를 사용할 수 있다.
다음은 정적 이너 클래스의 예제이다.
public class OuterClass {
private static int staticVariable = 20;
// 정적 이너 클래스
public static class StaticInnerClass {
public void display() {
System.out.println("정적 변수 값: " + staticVariable);
}
}
public static void main(String[] args) {
// 정적 이너 클래스의 인스턴스 생성
StaticInnerClass inner = new StaticInnerClass();
inner.display(); // 출력: 정적 변수 값: 20
}
}
특징:
- 외부 클래스의 인스턴스 없이도 정적 이너 클래스를 사용할 수 있다.
- 정적 이너 클래스는 외부 클래스의 정적 멤버(변수, 메서드)만 접근할 수 있다.
- 정적 이너 클래스는 외부 클래스의 비정적(non-static) 멤버에는 접근할 수 없다.
2.3 지역 이너 클래스 (Local Inner Class)
지역 이너 클래스는 메서드나 초기화 블록 내에 선언되며, 해당 블록 내에서만 유효하다. 지역 이너 클래스는 외부 클래스의 멤버에 접근할 수 있으며, 메서드의 로컬 변수도 사용할 수 있다.
다음은 지역 이너 클래스의 예제이다.
public class OuterClass {
public void outerMethod() {
int localVariable = 30;
// 지역 이너 클래스
class LocalInnerClass {
public void display() {
System.out.println("로컬 변수 값: " + localVariable);
}
}
// 지역 이너 클래스의 인스턴스 생성
LocalInnerClass inner = new LocalInnerClass();
inner.display(); // 출력: 로컬 변수 값: 30
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
}
}
특징:
- 메서드 내에 선언된 이너 클래스로, 해당 메서드가 호출될 때만 사용할 수 있다.
- 지역 변수(로컬 변수)에 접근할 수 있지만, 이 변수는 반드시 final 또는 사실상 final이어야 한다.
- 메서드가 종료되면 지역 이너 클래스의 인스턴스도 소멸된다.
2.4 익명 이너 클래스 (Anonymous Inner Class)
익명 이너 클래스는 이름이 없는 클래스이며, 일반적으로 한 번만 사용되는 클래스를 정의할 때 사용된다. 익명 이너 클래스는 인터페이스나 추상 클래스의 인스턴스를 생성하여, 해당 인터페이스나 클래스의 메서드를 구현하는 경우가 많다.
다음은 익명 이너 클래스의 예제이다.
public class OuterClass {
public void displayMessage() {
// 익명 이너 클래스
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("익명 이너 클래스 실행");
}
};
// 스레드 생성 및 실행
new Thread(runnable).start();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.displayMessage(); // 출력: 익명 이너 클래스 실행
}
}
특징:
- 클래스의 이름이 없으며, new 키워드를 사용하여 클래스의 인스턴스를 생성한다.
- 주로 인터페이스나 추상 클래스를 구현하여 단 한 번만 사용되는 코드를 정의할 때 사용된다.
- 익명 이너 클래스는 코드의 간결성을 높여주지만, 가독성이 떨어질 수 있어 주의가 필요하다.
3. 이너 클래스의 장점
이너 클래스를 사용하면 다음과 같은 장점을 얻을 수 있다:
- 코드의 논리적 그룹화: 관련된 클래스들을 외부 클래스 내부에 정의하여 가독성을 높인다.
- 캡슐화: 외부 클래스와의 긴밀한 관계를 정의하여 특정 멤버에 대한 접근을 제한할 수 있다.
- 간편한 외부 클래스 접근: 외부 클래스의 멤버에 쉽게 접근하여 복잡한 연산이나 로직을 단순화할 수 있다.
- 이벤트 핸들링: 익명 이너 클래스를 사용하여 이벤트 핸들러를 간편하게 구현할 수 있다.
4. 이너 클래스 사용 시 주의사항
- 메모리 누수: 멤버 이너 클래스는 외부 클래스의 인스턴스를 참조하기 때문에, 외부 클래스의 인스턴스가 메모리에서 해제되지 않고 남아 메모리 누수가 발생할 수 있다.
- 캡슐화: 외부 클래스의 멤버에 쉽게 접근할 수 있기 때문에, 적절히 설계하지 않으면 캡슐화가 깨질 수 있다.
- 이름 충돌: 이너 클래스와 외부 클래스의 변수 이름이 동일할 경우, this 키워드를 통해 참조를 명확히 해야 한다.
5. 결론
자바의 이너 클래스는 외부 클래스와 밀접한 관계를 가지며, 클래스 간의 논리적 그룹화를 통해 코드의 가독성과 유지보수성을 높인다. 또한, 특정 기능을 캡슐화하여 외부에 노출하지 않고 구현할 수 있다. 이너 클래스는 상황에 따라 적절히 사용하면 코드의 재사용성을 높이고 개발 시간을 단축할 수 있다. 이너 클래스를 사용할 때는 각각의 이너 클래스가 가지는 특성을 이해하고, 메모리 누수나 캡슐화의 문제를 염두에 두고 사용해야 한다.
이너 클래스의 다양한 종류와 그 특징을 이해함으로써, 자바의 객체지향 프로그래밍 패턴을 더욱 효과적으로 활용할 수 있을 것이다.
'JAVA > JAVA 기초' 카테고리의 다른 글
Java Socket 프로그래밍 (0) | 2024.10.16 |
---|---|
Java String 클래스 (0) | 2024.10.15 |
JAVA I/O 입출력 시스템 (0) | 2024.10.13 |
Java 람다 표현식(Lambda Expression)과 스트림(Stream) (0) | 2024.10.12 |
Java Thread 활용 (0) | 2024.10.11 |