접근 제어자는 위 그림과 같이 절대 단순하지 않다. 특히 객체 멤버에 대한 접근인가, 정적 멤버에 대한 접근인가에 따라 생각할 것이 많아진다.그리고 protected 가 자신과 상속 관계에 있는 서브 클래스만 접근 가능한 걸로 착각하는 경우가 많은데, 같은 패키지라면 한 집에 산다고 생각하기에 접근 가능하다는 사실도 꼭 기억해야 한다. 결과를 확인해보면 아래와 같다. 하나씩 살펴보자.
- 같은 패키지 / ClassA / Instance Method : public / protected / default / private 모두 접근 가능하다. - 같은 패키지 / ClassA / Static Method : public / protected / default / private 모두 접근 가능하다. - 같은 패키지 / Subclass of ClassA /InstanceMethod : public / protected / default 접근 가능하다. - 같은 패키지 / Subclass of ClassA /StaticMethod : public / protected / default 접근 가능하다. - 같은 패키지 / NonSubclass of ClassA /InstanceMethod : public / protected / default 접근 가능하다. - 같은 패키지 / NonSubclass of ClassA /StaticMethod : public / protected / default 접근 가능하다. - 다른 패키지 / Subclass of ClassA /InstanceMethod : public / protected 접근 가능하다. - 다른 패키지 / Subclass of ClassA /StaticMethod : public 접근 가능하다.protected 접근 불가능하다. - 다른 패키지 / NonSubclass of ClassA /InstanceMethod : public 접근 가능하다. - 다른 패키지 / NonSubclass of ClassA /StaticMethod : public 접근 가능하다.
위 결과를 보면다른 패키지에 있는 상속받은 클래스의 경우 예상과는 다른 결과가 나오는 것을 알 수 있다.상속 받았으니까 protected 는 당연히 접근 가능해야 하는 거 아닌가 싶지만, Instance Method 에서만 접근 가능하고, Static Method 에서는 접근이 불가능하다.protected 에 대한 내용은 하단 블록에서 이어서 설명하겠다.
습관적으로 private 아니면 public 만 사용하거나, 그냥 아무 표시도 하지 않는 [default] 만 사용해 왔다면 반성이 필요한 대목이다. protected 가 같은 패키지 내의 모든 클래스에서 접근이 가능하다고 하면또 깊이 생각해 볼 문제가 하나 더 있다.aaa.jar 파일 안에 packageOne 패키지가 있고, bbb.jar 파일 안에 같은 이름을 가진 packageOne 패키지가 있다면어떻게 될까?bbb.jar 파일 내부의 packageOne 패키지 내 클래스나 객체에서 aaa.jar 파일 내부의 packageOne 패키지 내 클래스나 객체가 가진 public 멤버뿐만 아니라 default 멤버와 protected 멤버에 자유롭게 접근할 수 있다. 보안과 관련해서 갑자기 많은 생각이 스쳐 지나갈 것이다.
Protected 는 왜 예상과 다르게 동작했을까?
Java 에서 Protected 가 어떻게 동작하는지 다시 살펴보자. 1)같은 패키지에서 접근 가능하다. (like default) 2)다른 패키지에 있더라도 하위 클래스(상속)라면 접근 가능하다.단, 다른 패키지에서는 Instance Method 에서만 접근가능하다.
이것을 코드로 살펴보면 아래와 같다.왜 Inheritance Method 에서만 접근 가능한지는 코드를 보면서 천천히 생각해보면 이해할 수 있다.protected 는 다른 패키지에 있는 경우라도 '상속'했다면 접근 가능하다고 했다.Instance Method 에서는 SubClass 를 생성하고 this 를 통해서 상속받은 변수에 접근하기 때문에 상속을 통한 접근을 하게 된다.그렇기 때문에 protected 의 조건을 통과하여 무사히 접근할 수 있는 것이다.
반대로, Static Method 에서는 객체 생성 없이 접근을 해야 하기 때문에 this 키워드를 사용할 수 없다. 따라서 Static Method 안에서 SuperClass 의 변수에 접근하기 위해서는 SuperClass 를 직접 생성해서 접근해야 하며,이 경우그냥 단순하게다른 패키지에서 SuperClass 를 생성해서 접근하려는 것이기 때문에,상속을 통한 접근이 아니므로 protected 의 조건을 통과하지 못하게 된다.