본문 바로가기
Programming/JAVA

[JAVA] 중첩 클래스의 접근 제한

중첩 클래스의 접근 제한






바깥 필드와 메소드에서 사용제한

멤버 클래스가 인스턴스 또는 정적으로 선언됨에 따라 바깥 클래스의 필드와 메소드에 사용제한이 생긴다.

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
public class A {
    //인스턴스 필드
    B field1 = new B();    // O
    C field2 = new C();    // O
    
    //인스턴스 메소드
    void method1() {
        B var1 = new B();    // O
        C var2 = new C();    // O
    }
    
    //정적 필드 초기화
    static B field3 = new B();    // X
    static C field4 = new C();    // O
    
    //정적 메소드
    static void method2() {
        B var1 = new B();    // X
        C var2 = new C();    // O
    }
    
    //인스턴스 멤버 클래스
    class B {}
    
    //정적 멤버 클래스
    static class C {}
}
 
cs

인스턴스 멤버 클래스(B)는 바깥 클래스의 인스턴스 필드(field1)의 초기값이나 인스턴스 메소드(method1())에서 객체를 생성 할 수 있으나, 정적 필드(field3)의 초기값이나 정적 메소드(method2())에서는 객체를 생성 할 수 없다. 반면 정적 멤버 클래스 (C)는 모든 필드의 초기값이나 모든 메소드에서 객체를 생성 할 수 있다.




● 멤버 클래스에서 사용제한

멤버 클래스가 인스턴스 또는 정적으로 선언됨에 따라 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드를 접근 할 때에도 접근이 따른다.

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() {
            field1 = 10;    // X
            method1();      // X
        
            field2 = 10;
            method2();
        }
    }
 
}
 
cs

인스턴스 멤버 클래스(B) 안에서는 바깥 클래스의 모든 필드와 모든 메소드에 접근 할 수 있지만, 정적 멤버 클래스 (C)안에서는 바깥 클래스의 정적 필드(field2)와 메소드(method2())에만 접근 할 수 있고 인스턴스 필드(field1)와 메소드(method1())는 접근 할 수 없다.




● 로컬 클래스에서 사용제한

로컬 클래스 내부에서는 바깥 클래스의 필드나 메소드를 제한 없이 사용 할 수 있다. 문제는 메소드의 매개 변수나 로컬 변수를 로컬 클래스에서 사용 할 때이다. 로컬 클래스의 객체는 메소드 실행이 끝나도 힙 메모리에 존재해서 계속 사용 될 수 있다. 매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 로컬 객체에서 사용할 경우 문제가 발생한다.


자바는 이 문제를 해결하기 위해 컴파일 시 로컬 클래스에서 사용하는 매개 변수나 로컬 변수의 값을 로컬 클래스 내부에 복사해 두고 사용한다. 그리고 매개 변수나 로컬 변수가 수정되어 값이 변경되면 로컬 클래스에 복사해 둔 값과 달라지는 문제를 해결하기 위해 매개 변수나 로컬 변수를 final로 선언해서 수정을 막는다.

결론적으로 말해서 로컬 클래스에서 사용 가능한 것은 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
28
29
30
public class A {
    //자바 7이전
    public void method(final int arg) {
        final int localVariable = 1;
        //arg = 100 (X)
        //localVaribale = 100; (X)
        
        class B {
            public void method() {
                int result = arg + localVariable;
            }
        }
    }
    
    //자바 8이후
    public void method2(int arg) {
        int localVariable = 1;
        //arg = 100 (X)
        //localVariable = 100; (X)
        
        class B {
            public void method() {
                int result = arg + localVariable;
            }
        }
    }
    
    
}
 
cs

자바 7까지는 반드시 final 키워드를 붙여야 되지만, 자바 8부터는 붙이지 않아도 final 특성을 가지고 있다.




● 중첩 클래스에서 바깥 클래스 참조 얻기

클래스 내부에서 this는 객체 자신의 참조이다. 중첩 클래스에서 this 키워드를 사용하면 바깥 클래스의 객체 참조가 아니라, 중첩 클래스의 객체 참조가 된다. 따라서 중첩 클래스 내부에서 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
public class A {
    String field = "Outter field";
 
    void method() {
        System.out.println("Outter method");
    }
 
    class B {
        String field = "Nested field";
 
        void method() {
            System.out.println("Nested method");
        }
        
        void print() {
            //중첩 객체 참조
            System.out.println(this.field);
            this.method();
            
            //바깥 객체 
            System.out.println(A.this.field);
            A.this.method();
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
public class OutterExample {
    public static void main(String[] args) {
        A a = new A();
        A.B ab = a.new B();
        ab.print();
    }
}
 
cs


'Programming > JAVA' 카테고리의 다른 글

[JAVA] JVM, JRE, JDK  (0) 2018.12.29
[JAVA] 중첩 클래스와 중첩 인터페이스  (3) 2018.06.07
[JAVA] LINKEDLIST를 이용한 성적처리  (3) 2018.04.15
[JAVA] 경로  (1) 2018.04.15
[JAVA] 이칙(+,-) 계산기  (0) 2018.04.15