Как доступна эта приватная переменная?
Как компилятор не жалуется, когда я пишу следующий код?
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)
? В конце концов, я пытаюсь получить доступ к частной переменной напрямую.
Код даже работает нормально.
Ответы
Ответ 1
Частный член доступен из любого метода в классе, в котором он объявлен, независимо от того, обращается ли этот метод к своему собственному элементу экземпляра (this
) или к частному пользователю другого экземпляра.
Это указано в JLS 6.6.1:
... В противном случае, если член или конструктор объявлен приватным, доступ разрешен тогда и только тогда, когда он встречается внутри тела класса верхнего уровня (§7.6), который включает объявление члена или конструктора.
Эта функция Java позволяет вам писать методы, которые принимают экземпляр класса в качестве аргумента (например, clone(Object other)
, compareTo(Object other)
), не полагаясь на класс с не частными получателями для всех частных свойств, которые нуждаются в для доступа.
Ответ 2
Частные поля являются закрытыми для класса в целом, а не только для объекта.
Другие классы не знают, что у MyClass есть поле под названием count; однако объект MyClass знает, что другой объект MyClass имеет поле count.
Ответ 3
Аксессоры - это не безопасность! Они являются инкапсуляцией, чтобы другие не знали о коде.
Считайте, если кто-то написал Quantum Bogo Sort, но исчез, как только он отменил последнюю ошибку - понимание кода заставляет его либо удалить из вселенной или сойти с ума.
Несмотря на этот незначительный недостаток, если он правильно инкапсулирован, это должно стать вашим предпочтительным алгоритмом сортировки, поскольку все поля и методы, кроме Sort, должны быть частными.
Вы не знаете, как это работает, и вы не хотите знать, как это работает, но оно работает и этого достаточно. Если, с другой стороны, все является общедоступным, и вы должны понимать, как он делает то, что он делает, чтобы правильно использовать его - что бы очень беспокоиться, я буду придерживаться быстрой сортировки.
Ответ 4
Хотя это экземпляр того же класса, в котором testPrivate написанный, но не должен он через ошибку компилятора в System.out.println(o.count);
Нет. Это никогда не вызовет ошибку компиляции.
Это очень похоже на то, что делает простой getter и setter, или конструктор копирования. Помните, что мы можем получить доступ к 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
членам. Там вам придется использовать метод или сеттер или получатель.
Ответ 5
Методы, переменные и конструкторы, объявленные как private, могут быть доступны только в самом объявленном классе. Проверьте официальную документацию