From 80b6865f302ac37dddb8f50ac8f53b96797ab14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=AD=EC=A3=BC=EB=8A=94=EC=82=AC=EA=B3=BC=EC=95=84?= =?UTF-8?q?=EB=8B=98?= Date: Tue, 5 Mar 2024 16:40:38 +0900 Subject: [PATCH] =?UTF-8?q?`Chapter=2016=20:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=95=88=EC=97=90=20=ED=81=B4=EB=9E=98=EC=8A=A4=EA=B0=80=20?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EA=B0=88=20=EC=88=98=EB=8F=84=20=EC=9E=88?= =?UTF-8?q?=EA=B5=AC=EB=82=98`=20=EA=B3=B5=EB=B6=80=20=EB=82=B4=EC=9A=A9?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `Chapter 16 : 클래스 안에 클래스가 들어갈 수도 있구나` 공부 내용 정리 완료 --- images/ch16/GC_behavior_diagram.png | Bin 0 -> 31701 bytes images/ch16/nested_class_diagram.png | Bin 0 -> 13425 bytes scripts/ch_16/README.md | 19 + scripts/ch_16/code/InputBox.java | 20 + scripts/ch_16/code/KeyEventListener.java | 6 + scripts/ch_16/code/MyPage.java | 39 ++ scripts/ch_16/code/README.md | 57 +++ scripts/ch_16/code/solution.md | 12 + scripts/ch_16/section_01_04.md | 501 +++++++++++++++++++++++ 9 files changed, 654 insertions(+) create mode 100644 images/ch16/GC_behavior_diagram.png create mode 100644 images/ch16/nested_class_diagram.png create mode 100644 scripts/ch_16/README.md create mode 100644 scripts/ch_16/code/InputBox.java create mode 100644 scripts/ch_16/code/KeyEventListener.java create mode 100644 scripts/ch_16/code/MyPage.java create mode 100644 scripts/ch_16/code/README.md create mode 100644 scripts/ch_16/code/solution.md create mode 100644 scripts/ch_16/section_01_04.md diff --git a/images/ch16/GC_behavior_diagram.png b/images/ch16/GC_behavior_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..051812a4e6de24a5b645864f93561846448bcac8 GIT binary patch literal 31701 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 H&piJN&_veT literal 0 HcmV?d00001 diff --git a/images/ch16/nested_class_diagram.png b/images/ch16/nested_class_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0c6423a2520cdf2aa25b75c725a07206393d5851 GIT binary patch literal 13425 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 Ve5q><{tpp}p0*L}m8Nsz{{q>Uws-&l literal 0 HcmV?d00001 diff --git a/scripts/ch_16/README.md b/scripts/ch_16/README.md new file mode 100644 index 0000000..f0dd602 --- /dev/null +++ b/scripts/ch_16/README.md @@ -0,0 +1,19 @@ + +### Chapter 16 : 클래스 안에 클래스가 들어갈 수도 있구나 + +- [`1. 클래스 안의 클래스`](./section_01_04.md#1-클래스-안의-클래스) +- [`2. static nested 클래스의 특징`](./section_01_04.md#2-static-nested-클래스의-특징) +- [`3. 내부 클래스와 익명 클래스`](./section_01_04.md#3-내부-클래스와-익명-클래스) +- [`4. Nested 클래스의 특징은 꼭 알아야 한다`](./section_01_04.md#4-nested-클래스의-특징은-꼭-알아야-한다) + +--- + +### What I learned from this chapter + +이번 챕터에는 `Nested Class` 에 대해 배웠다. 중첩 클래스는 **잘** 만들면 코드의 가독성, 유지보수성을 높일 수 있는 좋은 전략이다. + +이러한 `Nested Class` 를 어렴풋이 알고 있었지만 이를 형식으로 갖추어 배운적은 처음이다. 그래서 큰 내용을 어렵지 않았지만 세부적으로 몰랐던 내용들이 종종 있었다. + +`Static Nested Class`, `Nested Class 종류에 따른 참조 스코프 범위`, 그리고 `익명 클래스` 등이 그러했다. + +결과적으로 현 챕터에 관한 내용은 그냥 알고있는게 중요한게 아니라 실제로 적용해보면서 체감하는게 중요하다. 어서 프로젝트에서 써먹어 볼 수 있으면 좋겠다. diff --git a/scripts/ch_16/code/InputBox.java b/scripts/ch_16/code/InputBox.java new file mode 100644 index 0000000..d56089e --- /dev/null +++ b/scripts/ch_16/code/InputBox.java @@ -0,0 +1,20 @@ +package scripts.ch_16.code; + +public class InputBox { + public static final int KEY_DOWN = 2; + public static final int KEY_UP = 4; + KeyEventListener listener; + + public void setKeyListener(KeyEventListener listener) { + this.listener = listener; + } + + public void listenerCalled(int eventype) { + if (eventype == KEY_DOWN) { + listener.onKeyDown(); + } + else if (eventype == KEY_UP) { + listener.onKeyUp(); + } + } +} diff --git a/scripts/ch_16/code/KeyEventListener.java b/scripts/ch_16/code/KeyEventListener.java new file mode 100644 index 0000000..865af73 --- /dev/null +++ b/scripts/ch_16/code/KeyEventListener.java @@ -0,0 +1,6 @@ +package scripts.ch_16.code; + +public interface KeyEventListener { + public void onKeyDown(); + public void onKeyUp(); +} diff --git a/scripts/ch_16/code/MyPage.java b/scripts/ch_16/code/MyPage.java new file mode 100644 index 0000000..ca0d986 --- /dev/null +++ b/scripts/ch_16/code/MyPage.java @@ -0,0 +1,39 @@ +package scripts.ch_16.code; + +public class MyPage { + + public static InputBox input; + + static { + input = new InputBox(); + } + + public static void main(String[] args) { + MyPage testMyPage = new MyPage(); + + testMyPage.setUI(); + testMyPage.pressKey(); + } + + public void setUI() { + KeyEventListener listener = new KeyEventListener() { + @Override + public void onKeyDown() { + System.out.println("Key Down"); + } + + @Override + public void onKeyUp() { + System.out.println("Key Up"); + } + }; + + MyPage.input.setKeyListener(listener); + } + + public void pressKey() { + MyPage.input.listenerCalled(InputBox.KEY_DOWN); + MyPage.input.listenerCalled(InputBox.KEY_UP); + } + +} diff --git a/scripts/ch_16/code/README.md b/scripts/ch_16/code/README.md new file mode 100644 index 0000000..7655d96 --- /dev/null +++ b/scripts/ch_16/code/README.md @@ -0,0 +1,57 @@ + +### Chapter 16 : 클래스 안에 클래스가 들어갈 수도 있구나 - 정리해 봅시다. + +--- + +#### 직접 해봅시다 + +여러분들은 자바 기반의 `UI` 를 처리하려고 한다. `InputBox` 라는 클래스는 다음과 같이 구현되어 있다. + +```java +package c.inner.practice; + +public class InputBox { + public InputBox() {} + + KeyEventListener listener; + public void setKeyListener(KeyEventListener listener) { + this.listener = listener; + } + + public static final int KEY_DOWN = 2; + public static final int KEY_UP = 4; + public void listenerCalled(int eventType) { + if (eventType == KEY_DOWN) { + listener.onKeyDown(); + } + else if (eventType == KEY_UP) { + listener.onKeyUp(); + } + } +} +``` + +그리고 `setKeyListener` 에서 사용하는 `KeyEventListener` 인터페이스는 다음과 같이 정의되어 있다. + +```java +package c.inner.practice; + +public interface KeyEventListener { + public void onKeyDown(); + public void onKeyUp(); +} +``` + +- `[1]` : `c.inner.practice` 패키지에 `MyPage` 라는 클래스를 만들고 `main()` 메서드를 추가하자. +- `[2]` : `MyPage` 클래스에 `input` 이라는 이름의 `InputBox` 클래스 변수를 선언하자. +- `[3]` : `MyPage` 클래스에 `setUI()` 라는 리턴값이 없는 메서드를 만들자. +- `[4]` : `setUI()` 메서드에서 `input` 객체를 초기화하자. +- `[5]` : `setUI()` 메서드에 `KeyEventListener` 인터페이스를 구현한 익명 클래스를 만들자. `onKeyDown()` 메서드가 호출되었을 때에는 `"Key Down"` 이, `onKeyUp()` 메서드가 호출되었을 때에는 `"Key Up"` 이 출력되도록 하자. +- `[6]` : `setUI()` 메서드에서 `[5]` 에서 생성한 `listener` 를 `input` 객체의 `setKeyListener()` 메서드에 매개 변수로 넣어주자. +- `[7]` : `MyPage` 클래스에 `pressKey()` 메서드를 추가하자. 이 메서드 내에서는 `InputBox` 클래스에 선언된 `listenerCalled()` 메서드를 호출하여 `onKeyDown()` 이벤트와 `onKeyUp()` 이벤트가 수행되도록 하자. +- `[8]` : `MyPage` 클래스의 `main()` 메서드에서는 `setUI()` 메서드와 `pressKey()` 메서드를 차례로 호출하도록 하자. 이제 컴파일 및 실행을 해보자. 결과는 다음과 같다. + +``` +Kye Down +Key Up +``` diff --git a/scripts/ch_16/code/solution.md b/scripts/ch_16/code/solution.md new file mode 100644 index 0000000..1c3175d --- /dev/null +++ b/scripts/ch_16/code/solution.md @@ -0,0 +1,12 @@ + +### Chapter 16 : 클래스 안에 클래스가 들어갈 수도 있구나 - 정리해 봅시다. + +- [`문제 설명`](./README.md) + +--- + +문제의 설명을 따라 차근차근 진행하면 어렵지 않게 해결할 수 있다. + +다만 문제 `[2]` 에서 `"input 이라는 InputBox 클래스 변수 를 선언"` 하라 하였는데, 이후 문제를 보면 `클래스 변수` 가 아니라 인스턴스 변수로 선언해야 한다. + +나는 그냥 `클래스 변수` 로 만들었다. diff --git a/scripts/ch_16/section_01_04.md b/scripts/ch_16/section_01_04.md new file mode 100644 index 0000000..0035787 --- /dev/null +++ b/scripts/ch_16/section_01_04.md @@ -0,0 +1,501 @@ + +### Chapter 16 : 클래스 안에 클래스가 들어갈 수도 있구나 + +- [`1. 클래스 안의 클래스`](#1-클래스-안의-클래스) +- [`2. static nested 클래스의 특징`](#2-static-nested-클래스의-특징) +- [`3. 내부 클래스와 익명 클래스`](#3-내부-클래스와-익명-클래스) +- [`4. Nested 클래스의 특징은 꼭 알아야 한다`](#4-nested-클래스의-특징은-꼭-알아야-한다) + +--- + +### `1. 클래스 안의 클래스` + +`Java` 에도 클래스 안에 클래스가 들어갈 수 있다. 이러한 클래스를 `"Nested Class"` 라 부른다. `Nested Class` 선언 방식에 따라 `Static Nested Class`, `Inner Class` 로 나눌 수 있다. `Inner Class` 는 말 그대로 클래스 속에 정의된 클래스이고, `Static Nested Class` 는 이를 정적으로 정의한 클래스이다. + +`Nested Class` 형태를 사용하는 가장 큰 이유는 코드를 간단히 표현하기 위함이다. +- 역할에 따라 클래스를 모아두어 코드가 보기 편함 `(Static Nested Class)` +- 캡슐화를 이용해 좀 더 안전한 코드를 만들 수 있음 `(Inner Class)` +- 이를 통해 코드의 가독성과 유지보수성을 높임 + +`Java` 에서 `Nested Class` 는 대개 `Java` 기반의 `UI` 를 처리할 때, 사용자의 입력이나 외부 이벤트에 대한 처리를 할 때 사용된다. + +`Inner Class` 는 또 2 가지로 나눌 수 있는데, `Local Inner Class`, `Anonymous Inner Class` 이다. + +

+ +

+ +`Nested Class` 는 쉽게말해 `"Outer Class 를 어느정도 사용할 수 있는 package"` 라 할 수 있다. + +다음 예시를 보자. + +```java +class OuterClass { + public int OuterValue = 10; + public InnerClass inner = new InnerClass(); + + class InnerClass { + public int InnerValue; + + public void innerMethod() { + System.out.println("can access to OuterValue\t: " + OuterValue); + } + } + + public void outerMethod() { + System.out.println("OuterClass can not access to InnerValue"); + System.out.print("But InnerClass "); + inner.innerMethod(); + } +} + +OuterClass outerClass = new OuterClass(); +OuterClass.InnerClass innerClass = outerClass.new InnerClass(); + +outerClass.OuterValue = 5; +outerClass.outerMethod(); System.out.println(); + +innerClass.innerMethod(); System.out.println(); + +System.out.println("hashCode\tidentityHashCode"); +System.out.println( + String.format("0x%8x", outerClass.inner.hashCode()) + "\t" + + String.format("0x%8x", System.identityHashCode(outerClass.inner)) +); +System.out.println( + String.format("0x%8x", innerClass.hashCode()) + "\t" + + String.format("0x%8x", System.identityHashCode(innerClass)) +); +``` +``` +OuterClass can not access to InnerValue +But InnerClass can access to OuterValue : 5 + +can access to OuterValue : 5 + +hashCode identityHashCode +0x2f2c9b19 0x2f2c9b19 +0x7cca494b 0x7cca494b +``` + +`InnerClass` 에서는 `OuterClass` 의 필드에 접근할 수 있다. 반면 `OuterClass` 에서는 `InnerClass` 의 필드에 접근할 수 없다. + +`innerClass` 객체는 `outerClass` 로 인해 생성되었으므로, `OuterValue` 의 참조가 유지된다. 그래서 `OuterValue` 가 `5` 로 바뀌었음에도 그대로 유지됨을 볼 수 있다. + +`(OuterValue 의 참조만 유지될 뿐, outerClass.inner 인스턴스와 innerClass 객체가 동일하다는 것은 아니다)` + +--- + +### `2. static nested 클래스의 특징` + +`Static Nested Class` 는 `static` 키워드를 이용해 정의한 `Inner Class` 이다. + +하지만 이로 인해 시스템 성능에 큰 차이를 이끌 수 있는데, `Outer Class` 가 `GC` 에 의해 수거될 수도 있고 아닐 수 있기 때문이다. + +일반적으로 `Java` 의 `GC` 는 어느 객체가 `"닿을 수 없는"` `(Unreachable)`, 즉 객체가 어디에서도 참조되지 않을 때 `어느순간` 해당 객체가 존재하는 메모리를 청소한다. + +

+ +

+ +그런데 `Inner Class` 는 항상 어느 `Outer Class` **객체에 대한** 참조를 가지고 있다. 때문에 `Outer Class` **객체**가 다른 객체에 의한 참조가 없더라 해도, `Inner Class` 객체가 어딘가에서 `Reachable` 한 이상 `GC` 에 의해 수거되지 않는다. `(Inner Class, Outer Class 모두 Unreachable 해야 수거된다)` + +반면 `Static Nested Class` 의 경우 `Outer Class` **객체**의 참조를 가지고 있지 않다. 따라서 `Inner Class` 의 경우와 다르게 `GC` 의 수거대상에 올라간다. + +또한 `Static Nested Class` 는 `"Outer Class 에 대한 static 한 참조를 가질 뿐, static 하지 않은"` 점에 유의해야 한다. + +```java +class OuterClassStatic { + public static int OuterValueStatic = 15; + public InnerClassStatc inner = new InnerClassStatc(); + + static class InnerClassStatc { + public int InnerValue; + + public void innerMethod() { + System.out.println("can only access to OuterValueStatic\t: " + OuterValueStatic); + } + } + + public void outerMethod() { + System.out.println("OuterClassStatic can not access to InnerValue"); + System.out.print("But InnerClassStatc "); + inner.innerMethod(); + } +} + +OuterClassStatic outerClassStatic = new OuterClassStatic(); +OuterClassStatic.InnerClassStatc innerClassStatc = new OuterClassStatic.InnerClassStatc(); + +OuterClassStatic.OuterValueStatic = 10; +outerClassStatic.outerMethod(); System.out.println(); + +innerClassStatc.innerMethod(); System.out.println(); + +System.out.println("hashCode\tidentityHashCode"); +System.out.println( + String.format("0x%8x", outerClassStatic.inner.hashCode()) + "\t" + + String.format("0x%8x", System.identityHashCode(outerClassStatic.inner)) +); +System.out.println( + String.format("0x%8x", innerClassStatc.hashCode()) + "\t" + + String.format("0x%8x", System.identityHashCode(innerClassStatc)) +); +``` +``` +OuterClassStatic can not access to InnerValue +But InnerClassStatc can only access to OuterValueStatic : 10 + +can only access to OuterValueStatic : 10 + +hashCode identityHashCode +0x2f2c9b19 0x2f2c9b19 +0x7cca494b 0x7cca494b +``` + +만약 `OuterClassStatic.InnerClassStatc` 클래스가 여타 `static` 필드와 같았다면, `outerClassStatic.inner` 객체와 `innerClassStatc` 객체의 `identityHashCode` 가 동일해야 한다. + +하지만 이 둘은 다르다. `OuterClassStatic.InnerClassStatc` **클래스** 는 `OuterClassStatic` **클래스** 에 대한 참조를 가지고 있을 뿐, 그저 **객체간 참조와 다르다는 것이다.** + +`(OuterValueStatic 는 애초에 그냥 static 필드이므로 이를 공유하는 것은 당연하다)` + +--- + +### `3. 내부 클래스와 익명 클래스` + +#### `내부 클래스` `(Inner Class)` + +앞서 [`1. 클래스 안의 클래스`](#1-클래스-안의-클래스) 에서 `Inner Class` 에 대한 예시를 보았다. `Inner Class` 객체를 생성하기 위해선 다음과 같이 만들 수 있다. + +```java +class OuterClass { + class InnerClass {} +} + +OuterClass outer = new OuterClass(); +OuterClass.InnerClass inner1 = outer.new InnerClass(); +OuterClass.InnerClass inner2 = new OuterClass().new InnerClass(); +``` + +위 문법에서 `Inner Class` 에 대한 특징을 잘 보여준다. `OuterClass` 타입 객체를 생성하지 않고는 `OuterClass.InnerClass` 타입 객체를 생성할 수 없기 때문이다. + +때문에 이를 생성하기 위해선 `OuterClass` 타입 객체를 생성한 후 `outer.new InnerClass()`, `new OuterClass().new InnerClass()` 와 같이 생성할 수밖에 없다. + +`익명 클래스` 의 경우, 교재에서 마음에 드는 정의가 없어 추가로 찾아봤다. 그 결과 `익명 내부 클래스` `(Anonymous Inner Class)` 와 `익명 클래스` `(Anonymous Class)` 가 비슷하면서도 다른 것을 확인하였다. + +--- + +#### `익명 클래스` `(Anonymous Class)` + +`익명 클래스` 는 `interface`, `추상 클래스` 등을 클래스 선언 없이 확장 `(extends)` 하거나 구현 `(implements)` 한 클래스이다. + +```java +interface SomeInterface { + default public void method1() { + System.out.println("SomeInterface method1 origin"); + } + public void method2(); +} + +abstract class SomeClass { + public abstract void method1(); + public void method2() { + System.out.println("SomeClass method2 origin"); + } +} + +SomeInterface anonymousClass1 = new SomeInterface() { + @Override + public void method2() { + System.out.println("SomeInterface method2 modified"); + } +}; + +SomeClass anonymousClass2 = new SomeClass() { + @Override + public void method1() { + System.out.println("SomeClass method1 modified"); + } +}; + +anonymousClass1.method1(); +anonymousClass1.method2(); System.out.println(); +anonymousClass2.method1(); +anonymousClass2.method2(); +``` +``` +SomeInterface method1 origin +SomeInterface method2 modified + +SomeClass method1 modified +SomeClass method2 origin +``` + +이전 `interface`, `추상 클래스` 에서는 이를 상속하여 새로운 클래스를 만들거나 하였다. 하지만 굳이 새로운 클래스를 만들지 않아고 특정 메서드만 `Override` 하면 되는 경우, 위처럼 `익명 클래스` 방법을 사용해 좀더 간결한 코드를 만들 수 있다. + + +--- + +#### `익명 내부 클래스` `(Anonymous Inner Class)` + +`익명 내부 클래스` 는 위 `interface`, `추상 클래스` 등이 `Inner Class` 로 바뀐 것일 뿐이다. + +```java +class OuterClass { + class InnerClass { + public void someInnerMethod() { + System.out.println("Inner Method origin"); + } + } + + public void someMethod(InnerClass input) { + if (input.getClass() != InnerClass.class) return; + System.out.println("Outer Method origin"); + } +} + +OuterClass outer = new OuterClass() { + @Override + public void someMethod(InnerClass input) { + System.out.println("Outer Method modified"); + } +}; +OuterClass.InnerClass anonymousInnerClass = new OuterClass().new InnerClass() { + @Override + public void someInnerMethod() { + System.out.println("Inner Method modified"); + } +}; + +outer.someMethod(new OuterClass().new InnerClass()); +anonymousInnerClass.someInnerMethod(); +``` + +이전 `익명 클래스` 에서와 동일하게 어느 메서드를 `Override` 할 수 있다. + + +이처럼 `"뭔가를 만들어야 됐었는데 만들지 않거나, 객체를 숨기는 방식"` 이기 때문에 `익명` 이라는 단어가 붙은 것 같다. + +--- + +### `4. Nested 클래스의 특징은 꼭 알아야 한다` + +지금까지 클래스의 선언 방식에 따른 `Nested Class` 을 알아 보았다. 그러면서 잠시 `Nested Class` 에서 `Outer Class` 의 필드를 참조하는 것을 보았고, 그 반대는 할 수 없는 것을 보았다. + +이를 제대로 알아보자. + +--- + +#### `Static Nested Class 에서 참조 가능한 범위` + +`Static Nested Class` 는 접근제한자에 상관 않고 `Outer Class` 의 `Static` 필드에만 접근할 수 있다. 이는 `Outer Class` 또한 마찬가지이다. + +```java +class OuterClass { + public String publicScope = "publicScope"; + public static String pubStaticScope = "pubStaticScope"; + + String packScope = "packScope"; + static String packStaticScope = "packStaticScope"; + + protected String proScope = "proScope"; + protected static String proStaticScope = "proStaticScope"; + + private String priScope = "priScope"; + private static String priStaticScope = "priStaticScope"; + + static class StaticNestedClass { + public String publicInnerScope = "publicInnerScope"; + public static String pubStaticInnerScope = "pubStaticInnerScope"; + + String packInnerScope = "packInnerScope"; + static String packStaticInnerScope = "packStaticInnerScope"; + + protected String proInnerScope = "proInnerScope"; + protected static String proStaticInnerScope = "proStaticInnerScope"; + + private String priInnerScope = "priInnerScope"; + private static String priStaticInnerScope = "priStaticInnerScope"; + public void method() { + System.out.println("StaticNestedClass can only access to static fields: "); + System.out.println(pubStaticScope); + System.out.println(packStaticScope); + System.out.println(priStaticScope); + System.out.println(proStaticScope); + // System.out.println(publicScope); compile error: non-static variable priScope cannot be referenced from a static context + // System.out.println(packScope); + // System.out.println(proScope); + // System.out.println(priScope); + } + } + + public void method() { + System.out.println("OuterClass can only access to static inner fields:"); + System.out.println(OuterClass.StaticNestedClass.pubStaticInnerScope); + System.out.println(OuterClass.StaticNestedClass.packStaticInnerScope); + System.out.println(OuterClass.StaticNestedClass.priStaticInnerScope); + System.out.println(OuterClass.StaticNestedClass.proStaticInnerScope); + // System.out.println(OuterClass.StaticNestedClass.publicInnerScope); compile error: non-static variable publicInnerScope cannot be referenced from a static context + // System.out.println(OuterClass.StaticNestedClass.packInnerScope); + // System.out.println(OuterClass.StaticNestedClass.proInnerScope); + // System.out.println(OuterClass.StaticNestedClass.priInnerScope); + } +} + +OuterClass outerClass = new OuterClass(); +OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass(); + +staticNestedClass.method(); System.out.println(); +outerClass.method(); +``` +``` +StaticNestedClass can only access to static fields: +pubStaticScope +packStaticScope +priStaticScope +proStaticScope + +OuterClass can only access to static inner fields: +pubStaticInnerScope +packStaticInnerScope +priStaticInnerScope +proStaticInnerScope +``` + +만약 `non-static` 한 필드에 접근할 시, `static context` 에서 접근할 수 없다는 컴파일 에러를 뱉어낸다. + +--- + +#### `Inner Class 에서 참조 가능한 범위` + +반면 `Inner Class` 의 경우 많이 다른데, `Inner Class` 에서 `Outer Class` 의 필드를 접근하는데는 아무런 제한도 없지만, `Outer Class` 에서 `Inner Class` 의 경우 상당히 제한된다. + +```java +class OuterClass { + public String publicScope = "publicScope"; + public static String pubStaticScope = "pubStaticScope"; + + String packScope = "packScope"; + static String packStaticScope = "packStaticScope"; + + protected String proScope = "proScope"; + protected static String proStaticScope = "proStaticScope"; + + private String priScope = "priScope"; + private static String priStaticScope = "priStaticScope"; + + class InnerClass { + public String publicInnerScope = "publicInnerScope"; + public static String pubStaticInnerScope = "pubStaticInnerScope"; + + String packInnerScope = "packInnerScope"; + static String packStaticInnerScope = "packStaticInnerScope"; + + protected String proInnerScope = "proInnerScope"; + protected static String proStaticInnerScope = "proStaticInnerScope"; + + private String priInnerScope = "priInnerScope"; + private static String priStaticInnerScope = "priStaticInnerScope"; + public void method() { + System.out.println("InnerClass can access to every field: "); + System.out.println(pubStaticScope); + System.out.println(packStaticScope); + System.out.println(priStaticScope); + System.out.println(proStaticScope); + System.out.println(publicScope); + System.out.println(proScope); + System.out.println(priScope); + } + } + + public void method() { + System.out.println("OuterClass can only access to static inner field bypass:"); + System.out.println(OuterClass.InnerClass.pubStaticInnerScope); + System.out.println(OuterClass.InnerClass.packStaticInnerScope); + System.out.println(OuterClass.InnerClass.proStaticInnerScope); + System.out.println(OuterClass.InnerClass.priStaticInnerScope); + } +} + +OuterClass outerClass = new OuterClass(); +OuterClass.InnerClass innerClass = new OuterClass(). new InnerClass(); + +innerClass.method(); System.out.println(); +outerClass.method(); System.out.println(); + +System.out.println("Outside of class, can not access to private-static field"); +// System.out.println(OuterClass.InnerClass.priStaticInnerScope); compile error: priStaticInnerScope has private access in OuterClass.InnerClass +``` +``` +InnerClass can access to every field: +pubStaticScope +packStaticScope +priStaticScope +proStaticScope +publicScope +proScope +priScope + +OuterClass can only access to static inner field bypass: +pubStaticInnerScope +packStaticInnerScope +proStaticInnerScope +priStaticInnerScope + +Outside of class, can not access to private-static field +``` + +예시를 보면 `InnerClass` 에서는 모든 필드에 접근 가능하다. 하지만 `OuterClass` 에서는 어떠한 인스턴스 필드에 접근이 불가능하고 오직 `static` 필드만 접근 가능하다. + +\+ 사실 위 `OuterClass` 에서 `InnerClass` 필드에 접근할 수 있는 방법이 하나 있다. 그리고 이는 `Static Nested Class` 의 경우에도 적용 가능하다. + +```java +class OuterClass { + public String var = "String origin"; + + static class StaticNested { + private String staticPrivate = "staticPrivate"; + } + class Inner { + private String innerPrivate = "innerPrivate"; + public void method() { + System.out.println(var); + } + } + + public void method() { + System.out.println("Actually, we can access(?) to those fields like this :"); + + OuterClass.StaticNested staticNested = new OuterClass.StaticNested(); + OuterClass.Inner inner1 = new OuterClass(). new Inner(); + OuterClass.Inner inner2 = new Inner(); + + System.out.println(staticNested.staticPrivate); + System.out.println(inner1.innerPrivate); System.out.println(); + + inner1.method(); + inner2.method(); + } +} + +OuterClass outerClass = new OuterClass(); +outerClass.var = "String modified"; + +outerClass.method(); +``` +``` +Actually, we can access(?) to those fields like this : +staticPrivate +innerPrivate + +String origin +String modified +``` + +어찌 생각하면 좀 당연한 논리이다. 새롭게 생성한 객체기는 하지만 여전히 `OuterClass` 안에 있기 때문이다. + +또한 여기서 한가지 새로운 사실을 알아내었는데, `inner1` 와 `inner2` 의 차이이다. + +`inner1` 은 새로운 `OuterClass` 에서 파생된 `Inner` 객체이다. 반면 `inner2` 는 현재 메서드가 실행되고 있는 `OuterClass` 에서 파생된 객체이다. + +때문에 `inner1.method()`, `inner2.method()` 를 비교해보면 서로 다름을 알 수 있다. `outerClass.method()` 를 호출하기 전, `outerClass.var` 의 값을 바꿔, `inner2` 가 참조하는 `var` 가 바뀌었기 때문이다.