2011-10-27 5 views
9

는 오늘 다음 "이상한"기능을 통해 온 - 예 - 당신은 클래스 A의 몸에서 클래스 A에서 개체에 대한 참조가있는 경우이 객체의 private 필드에 액세스 할 수 있습니다자바 개인 필드 액세스가 가능하면 참조 할 수 있습니까?

public class Foo{ 
    private int bar; 
    private Foo foo; 
    public void f() 
    { 
     if(foo.bar == bar) // foo.bar is visible here?! 
     { 
      // 
     } 
    } 
} 

누구든지 이에 대해 좋은 설명이 있습니까?

+2

이 기능은 'equals' 메소드를 작성해야 할 때 매우 유용합니다. –

+2

같은 질문은 다음과 같습니다. http://stackoverflow.com/questions/2126984/why-is-the-access-to-a-private-field-not-forbidden, http://stackoverflow.com/questions/4340129/accessing -private-field-in-java, http://stackoverflow.com/questions/312168/java-private-field-visibility –

답변

19

액세스 한정자는 인스턴스 수준이 아니라 클래스 수준에서 작동합니다. 동일한 클래스의 모든 코드는 클래스의 모든 인스턴스의 개인 멤버에 액세스 할 수 있습니다.

특히 이상한 점은 없습니다.

3

f()는 Foo의 멤버이기 때문에 Foo의 private 멤버에 액세스 할 수있는 권한이 있습니다. 나에게 놀랄 일이 아니다.

+0

foo가 Foo 클래스 및 bar의 다른 인스턴스 일 때 foo.bar에 액세스 할 수있는 이유가 여기에 있습니다. 개인 필드입니다 – asenovm

+1

@iLate : 언어가 지정되는 방식이기 때문에 ... –

+0

@iLate : 디자이너가 방금 C++의 동작을 따랐습니다. – LLS

0

private은 Object 외부에서 비공개가 아니라 다른 클래스의 비공개를 의미하기 때문에. 당신은 Foo의 내부에 있으므로 바를 볼 수 있습니다.

그 방법

개인 생성자 등 싱글 톤

0

그 키워드가 클래스 지향적에서 작동 할, 객체 지향하지. 그래서 단지 "Foo 클래스의 객체가 Foo의 개인 객체에 액세스하려고 시도하고 있습니다."라는 표정을 짓고 있습니다.

5

이 방법을 사용합니다.

Java Language Specification 인용 :

멤버 (클래스, 인터페이스, 필드 또는 메소드)를 기준 (클래스, 인터페이스, 또는 어레이) 타입 또는 클래스 타입의 생성자하는 액세스 만하다면 회원 또는 생성자는 다음 액세스가 내에서 발생하는 경우에만 경우 경우 허용, 개인 선언 된 경우 (그렇지 않으면)

  • ...

    • : 유형에 액세스 할 수 있으며 회원 또는 생성자 액세스 허용 선언 최상위 레벨의 몸 ss (§7.6)는 회원의 선언을 둘러 쌉니다.
    • ...
    +2

    +1에 대한 JLS 참조. –

    1

    당신이 구현 세부 사항을 숨길 수있는 '개인'변경의 의도를 고려한다면 그것은 의미가 있습니다.

    "이 클래스에 비공개 여야합니다"(자바에서는 "이 소스 파일에 대해 비공개 여야 함"과 같은 개념)로 생각해보십시오. "이 인스턴스에 비공개 여야 함"이 아닙니다.

    0

    @Michael 님의 답변이 맞습니다. @asenovm의 코드에 대한 동작은 .NET과 동일합니다.

    또한 내부 클래스도 마찬가지입니다. Java입니다. 변수를 비공개로 정의하더라도 액세스 할 수 있습니다. C#과 다른 점 때문에 처음에 만났을 때 나는 놀랐습니다.

    public class WrapperClass 
    { 
    
        public static class NotThreadsafe { 
         private int x = 0; 
         //....   
        } 
    
        public static void main(String[] args) {   
        final NotThreadsafe nts=new NotThreadsafe(); 
        int x = nts.x ; // !!! THIS IS ACCESSIBLE AS WELL FOR JAVA BUT NOT.NET 
        } 
    } 
    

    C# 중첩 된 클래스와 동일하지 않습니다. 이 코드를 Visual Studio에 붙여 넣으면 작동하지 않습니다. 컴파일러는 액세스 수준에 신경을 씁니다.