2014-12-15 7 views
41

Как компилятор не жалуется, когда я пишу следующий код?Как эта доступная переменная доступна?

public class MyClass 
{ 
    private int count; 

    public MyClass(int x){ 
     this.count=x; 
    } 

    public void testPrivate(MyClass o){ 
     System.out.println(o.count); 
    } 
} 

Даже если это экземпляр одного и того же класса, в котором testPrivate написано, она не должна давать ошибку компиляции в System.out.println(o.count)? В конце концов, я пытаюсь получить доступ к частной переменной напрямую.
Код даже работает нормально.

+2

Класс MyClass знает переменную count, поэтому никаких проблем – SaintLike

+18

Это частный класс, а не экземпляр. Java не пытается остановить вашу левую руку от удара правой рукой. ;) –

+0

Создайте с помощью методов хэша Eclipse или IDEA hashCode и equals, они всегда выглядят таким образом – Maksym

ответ

56

Закрытый член доступен из любого метода в классе, в котором он объявлен, независимо от того, обращается ли этот метод к своему собственному члену экземпляра() или к частному члену другого экземпляра.

Об этом говорится в JLS 6.6.1:

... В противном случае, если член или конструктор объявлен частным, то доступ разрешен, если и только если оно происходит в теле класса верхнего уровня (§ 7.6), который включает объявление члена или конструктора.

Эта особенность Java позволяет создавать методы, которые принимают экземпляр класса в качестве аргумента (например - clone(Object other), compareTo(Object other)), не полагаясь на класс, имеющий не являющихся частными добытчиками для всех частных свойств, которые должны доступ к ним.

+1

TBH, я не осознавал это сознательно, но на самом деле это явно указано как предостережение для частного в томе Java на моем столе (листинг 9.6 на стр. 200 в Krüger, Hansen: «Handbuch der Java-Programmierung», Addison -Wesley, 2012). На первый взгляд не упоминается в Venners «Внутри виртуальной машины JAVA», т. Спасибо за вопрос и ответы. – hiergiltdiestfu

+0

Спасибо, теперь это имеет смысл. Я всегда использовал 'compareTo' и' equals' с геттерами. Это было странно, когда я заметил, что мы можем получить к нему доступ без геттеров. –

12

Закрытые поля являются закрытыми для класса в целом, а не только для объекта.

Другие классы не знают, что MyClass имеет поле под названием count; однако объект MyClass знает, что другой объект MyClass имеет поле count.

+0

приятное дополнение и просто объяснение мне было необходимо –

0

Методы, переменные и конструкторы, объявленные как private, могут быть доступны только в самом объявленном классе. Проверьте official documentation

3

Хотя это экземпляр того же класса, в котором testPrivate написано , но не следует это через ошибки компилятора в System.out.println (o.count);

No. Это никогда не вызовет ошибку компиляции.

Это очень похоже на то, что делает простой геттер и сеттер или конструктор копирования. Помните, что мы можем получить доступ к private пользователей с помощью this.

public MyClass { 
    private String propertyOne; 
    private String propertyTwo; 

    // cannot access otherObject private members directly 
    // so we use getters 
    // But MyClass private members are accessible using this. 
    public MyClass(OtherClass otherObject) { 
     this.propertyOne = otherObject.getPropertyOne(); 
     this.propertyTwo = otherObject.calculatePropertyTwo(); 
    } 

    public void setPropertyOne(String propertyOne) { 
     this.propertyOne = propertyOne; 
    } 

    public String getPropertyOne() { 
     return this.propertyOne; 
    } 
} 

Ваш метод testPrivate принимает экземпляр MyClass. Поскольку testPrivate - это метод внутри MyClass, он будет иметь доступ к private свойствам.

public void testPrivate(MyClass o) { 
     this.propertyOne = o.propertOne; 
    } 

Методы, определенные в классе всегда будет иметь доступ к его private членов, через this. и переменную экземпляра.

Но если вы укажете testPrivate за пределами MyClass, значит у вас не будет доступа к private пользователей.Там вам придется использовать метод или сеттер или геттер.

6

Аксессуры не являются защитой! Это инкапсуляция, чтобы другие не знали о коде.

Рассмотрите, если кто-то написал Quantum Bogo Sort, но исчез, как только он отменил последнюю ошибку - понимание кода заставляет его либо удаляться из вселенной, либо сойти с ума.

Несмотря на этот незначительный недостаток, если он правильно инкапсулирован, это должно стать вашим предпочтительным алгоритмом сортировки, поскольку все поля и методы, кроме Sort, должны быть закрытыми.

Вы не знаете, как это работает, и вы не хотите знать, как это работает, но оно работает, и этого достаточно. Если, с другой стороны, все является общедоступным, и вы должны понимать, как он делает то, что он делает, чтобы правильно использовать его - это просто очень беспокоит, я буду придерживаться быстрой сортировки.

Смежные вопросы