❓중첩 클래스란 ?
중첩 클래스는 말 그대로 클래스 안에 클래스를 중첩한 것을 중첩 클래스(Nested Class)라고합니다.
중첩 클래스의 분류는 아래와 같이 나눌 수 있습니다.
중첩 클래스의 선언 위치
정적 중첩 클래스는 정적 변수와 같은 위치에 선언되고 내부 클래스의 경우 인스턴스 변수와 같은 위치에 선언됩니다.
지역 크래스의 경우 지역 변수와 같은 위치에 선언됩니다.
class Outer {
...
//정적 중첩 클래스
static class StaticNested {
...
}
//내부 클래스
class Inner {
...
}
}
또한 정적 중첩 클래스의 경우 정적 변수와 같이 앞에 static이 붙어있고 내부 클래스는 인스턴스 변수와 같이 앞에 static이 붙어있지 않습니다.
class Outer {
public void process() {
//지역 변수
int lcoalVar = 0;
//지역 클래스
class Local {...}
// 클래스 생성
Local local = new Local();
}
}
지역 클래스는 지역 변수와 같이 코드 블럭 안에서 클래스를 정의합니다. 참고로 익명 클래스는 지역 클래스의 특별한 버전입니다.
중첩과 내부는 무슨 차이가 있을까요 ?
중첩은 어떤 다른 것이 내부에 위치하거나 포함되는 구조적인 관계를 의미하며, 내부는 나의 내부에 있는 나를 구성하는 요소를 의미합니다.
간단하게 중첩은 나의 안에 있지만 내것이 아닌 것이고(즉, 단순히 위치만 안에 있는 것), 내부는 나의 내부에서 나를 구성하는 요소를 의미합니다.
중첩 클래스는 언제 사용해야 하나요 ?
내부 클래스를 포함한 모든 중첩 클래스는 특정 클래스가 다른 하나의 클래스 안에서만 사용되거나, 둘이 아주 긴밀하게 연결되어 있는 특별한 경우에만 사용해야합니다. 외부의 여러 클래스가 특정 중첩 클래스를 사용한다면 중첩 클래스로 만들면 안됩니다.
정적 중첩 클래스
정적 중첩 클래스의 간단한 예제를 보면서 특징을 정리해보겠습니다 !
public class NestedOuter {
private static int outClassValue = 3;
private int outInstanceValue = 2;
static class Nested {
private int nestedInstanceValue = 1;
public void print() {
System.out.println(nestedInstanceValue);
System.out.println(outInstanceValue);
System.out.println(NestedOuter.outClassValue);
}
}
}
정적 중첩 클래스의 특징
- 정적 중첩 클래스 앞에는 static이 붙습니다.
- 자신의 멤버에는 당연히 접근할 수 있습니다.
- 바깥 클래스의 인스턴스 멤버에는 접근할 수 없습니다.
- 바깥 클래스의 클래스 멤버에는 접근할 수 있습니다.
- private 접근 제어자는 같은 클래스 안에 있을 때만 접근할 수 있습니다.
- new 바깥클래스.중첩클래스() 로 생성할 수 있습니다.
내부 클래스
정적 중첩 클래스는 바깥 클래스와 서로 관계가 없습니다. 하지만 내부 클래스는 바깥 클래스의 인스턴스를 이루는 요소가 됩니다. 쉽게 이야기해서 내부 클래스는 바깥 클래스의 인스턴스에 소속이됩니다.
간단한 예제를 보면서 특징을 정리해보겠습니다 !
public class InnerOuter {
private static int outClassValue = 3;
private int outInstanceValue = 2;
class Inner {
private int innerInstanceValue = 1;
public void print() {
System.out.println(innerInstanceValue);
System.out.println(outInstanceValue);
System.out.println(InnerOuter.outClassValue);
}
}
}
내부 클래스의 특징
- static이 붙지 않습니다.
- 바깥 클래스의 인스턴스에 소속됩니다.
- 자신의 멤버에는 당연히 접근할 수 있습니다.
- 바깥 클래스의 인스턴스 멤버에 접근할 수 있습니다.
- 바깥 클래스의 멤버에 접근할 수 있습니다.
- private 접근 제어자는 같은 클래스 안에 있을 때만 접근할 수 있습니다.
- 내부 클래스는 바깥 크래스의 인스턴스 참조.new 내부클래스()로 생성할 수 있습니다.
지역 클래스
지역 클래스는 내부 클래스의 특별한 종류의 하나입니다. 따라서 내부 클래스의 특징을 그대로 가지고 있고, 지역 변수와 같이 코드 블럭 안에서 정의됩니다.
지역 클래스가 접근하는 지역 변수는 절대로 중간에 값이 변하면 안됩니다. 따라서 final로 선언하거나 사실상 final이어야 합니다. 이것은 자바 문법이고 규칙으로 정의되어 있습니다.
지역 클래스의 지역 변수 캡처
지역 클래스로 만든 객체도 인스턴스이기 때문에 힙 영역에 존재합니다. 따라서 GC 전까지 생존합니다.
지역 클래스에서 해당 클래스에 있는 지역 변수를 사용하고 있을 경우 즉, 스택 영역에 존재하는 지역 변수를 힙 영역에 있는 인스턴스가 접근하는 것을 생각처럼 단순하지 않습니다.
자바는 이러한 문제를 해결하기 위해 지역 클래스의 인스턴스를 생성하는 시점에 필요한 지역 변수를 복사해서 생성한 인스턴스에 함꼐 넣어 줍니다. 이러한 과정을 변수 캡처(Capture)라고 합니다.
따라서 지역 클래스가 접근하는 지역 변수는 절때로 중간에 값이 변하면 안되고, 위에서 언급한 것과 같이 final로 선언하거니 또는 사실상 final이어야합니다.
사실상 final이란 ?
영어로 effectively final이라고 합니다. 사실상 final 지역 변수는 지역 변수이 final 키워드를 사용하지는 않았지만, 값을 변경하지 않는 지역 변수를 뜻합니다. final 키워드를 넣지 않았을 뿐이지, 실제로는 final 키워드를 넣은 것 처럼 중간에 값을 변경하지 않는 지역 변수입니다. 따라서 사실상 final 지역 변수는 final 키워드를 넣어도 동일하게 작동해야합니다.
익명클래스
익명클래스(anonymous class)는 지역 클래스의 특별한 종류의 하나입니다.
익명 클래스는 지역 클래스이고, 클래스의 이름이 없다는 특징이 있습니다 !
또한 특정 부모 클래스(인터페이스)를 상속 받고 바로 생성하는 경우 사용됩니다. 지역 클래스가 일회성으로 사용되는 경우나 간단한 구현을 제공할 때 사용합니다.
익명 클래스의 예제를 간단히 보고 넘어가겠습니다 !
// 부모 클래스
class Animal {
public String bark() {
return "동물이 웁니다";
}
}
public class Main {
public static void main(String[] args) {
// 익명 클래스 : 클래스 정의와 객체화를 동시에. 일회성으로 사용
Animal dog = new Animal() {
@Override
public String bark() {
return "개가 짖습니다";
}
}; // 단 익명 클래스는 끝에 세미콜론을 반드시 붙여 주어야 한다.
// 익명 클래스 객체 사용
dog.bark();
}
}
정리
중첩 클래스란 클래스 안에 클래스를 중첩한 것을 의미합니다.
중첩 클래스는 크게 정적 중첩 클래스와 내부 클래스로 나눌 수 있고, 정적 중첩 클래스는 클래스 내부에 다른 클래스가 있지만 내부에 있는 클래스가 바깥 클래스에 영향을 미치지 않는 것, 즉 위치만 내부에 있는 클래스인 것을 의미합니다. 그리고 정적 중첩 클래스의 경우 static이 붙습니다.
내부 클래스의 경우 클래스 내부에 있는 클래스가 바깥 클래스의 구성 요소가 될 때 내부 클래스라고 정의할 수 있고, static이 붙지 않습니다.
지역 클래스의 지역 변수는 절때 값이 변경되면 안되고 final 또는 사실상 final로 설정되어야합니다.
익명 클래스의 경우 지역 클래스에 속해있는 클래스이고 지역 클래스가 일회성으로 사용되는 경우 사용됩니다.
중첩 클래스는 해당 클래스에서만 사용할 경우에만 사용되며, 다른 외부 클래스에서 사용할 경우 재사용성을 높이기 위해 반드시 중첩 클래스가 아닌 다른 클래스로 분리하여 사용하시길 바라겠습니다 !
지역 클래스의 캡처 부분이 조금 이해하기 어려웠습니다......글에는 간단하게 작성해 놓은 느낌이 있지만 강의를 돌려보면서 자세하게 이해할 수 있었습니다 !
'프로그래밍 > Java' 카테고리의 다른 글
[Java, Spring] @ControllerAdvice, @RestControllerAdvice란 ? (5) | 2024.09.01 |
---|---|
[Java, 자바] 예외 처리란 ? (0) | 2024.07.31 |
[Java, Spring] Logging, @Slf4j란 ? (0) | 2024.07.29 |
[Java, Spring] application.properties란 ? (0) | 2024.07.29 |
[Java, 자바] 날짜와 시간 클래스에 대하여 (0) | 2024.07.19 |
개발의 모든 것 !
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!