중첩클래스의 접근 제한 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class A { int field1; void method1 ( ) { } static int field2; static void method2 ( ) { } class B { void method ( ) { field1 = 10 ; method1( ); field2 = 10 ; method2( ); } } static class C { void method ( ) { field2 = 10 ; method2( ); } } }
로컬클래스(메소드 안에 클래스 생성)에서 사용 가능한 것은 final로 선언된 매개 변수와 로컬 변수뿐이다. 자바 7 이전에는 final이 붙어있지 않은 매개변수 혹은 변수를 로컬 클래스안에서 사용하고자 하면 컴파일 에러가 발생하였다. 하지만 자바 8부터는 컴파일 에러가 발생하지 않는다. 즉 내부적으로는 final의 특성(값을 변경할 수 없는)을 갖으며 final의 유무로 로컬클래스 내 복사 위치가 결정된다.(복사위치에 대해선 아래 설명) 다음은 7,8버전의 final 유무에 따른 접근관련 이슈이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Outter { public void method1 (final int arg) { final int localVariable = 1 ; class Inner { public void method ( ) { int result = arg + localVariable; } } } public void method2 (int arg) { int localVariable = 1 ; class Inner { public void method ( ) { int result = arg + localVariable; } } } }
위의 코드와 같이 final이 없더라도 값 변경은 허용하지 않는다는것이다.
※ final의 유무로 로컬클래스 내 복사 위치가 결정된다? 먼저 다음과 같은 코드가 있다고 가정하자.
1 2 3 4 5 6 7 8 9 10 11 12 void outMethod (final int arg1, int arg2) { final int var1 = 1 ; int var2 = 2 ; class LocalClass { void method () { int result = arg1+arg2+var1+var2; } } }
위의 LocalClass에 복사된 변수를 보면 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 class LocalClass { int arg2 = 매개값; int var2 = 2 ; void method ( ) { int arg1 = 매개값; int var1 = 1 ; int result = arg1 + arg2+ var1+ var2; } }
복사된 영역을 신경쓸 필요는 없으나 알고 있는것이 좋겠다!
중첩클래스에서 바깥 클래스 참조 얻기 중첩 클래스 내부에서 this키워드를 사용하면 어떻게 될까? 말 그대로 중첩클래스가 this가 되게된다. 그렇다면 바깥 클래스를 가르키기 위해선 어떻게 해야될까. 정답은 바깥클래스.this 를 활용하면 된다. 아래를 참고하자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class Outter { String field = "Outter-filed" ; void method ( ) { System.out.println("Outter-method" ); } class Nested { String field = "Nested-field" ; void method () { System.out.println("Nested-method" ); } } void print ( ) { System.out.println(this .field); this .method( ); System.out.println(Outter.this .field); Outter.this .method( ); } } } public class OutterExample { public static void main (String[] args) { Outter outter = new Outter ( ); outter.Nested nested = outter.new Nested ( ); nested.print( ); } }