public class Solution {
public static void main(String[] args) {
Car myCar = new Car();
myCar.number = 222;
}
static class Car {
private int number;
public void setNumber(int number) {
this.number = number;
}
public int getNumber(){
return number;
}
}
}
Есть пользовательский класс Car, внутри которого объявлена переменная "number" как private. Как я понимаю доступ к ней есть только внутри самого класса. Плюс я написал сеттер/геттер для чтения и записи в эту переменную.
НО, в линии №4 я смог (ПОЧЕМУ-ТО!) ее поменять НАПРЯМУЮ к ней обратившись!
Помогите разобраться почему так происходит! Заранее благодарю!Олег
22 уровень
Почему есть доступ к переменной с доступом PRIVATE извне?
Решен
Комментарии (10)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
JustinianJudge в Mega City OneMaster
30 августа 2019, 09:06
Давай почитаем насчет инкапсуляции в джава и что такое модификатор private в спецификации языка джава (JLS):
JLS §6.6.1: A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses.
JLS §7.6: A top level type declaration declares a top level class type (§8 (Classes)) or a top level interface type (§9 (Interfaces)).
JLS §8: A top level class is a class that is not a nested class.
Ну и пояснения в книге:
Java in a nutshell 3rd edition, 3.13.1:
As we discussed earlier, a static member class can access all the static members of its containing class. If a static member class does this, the compiler automatically qualifies the member access expression with the name of the containing class. A static member class is even allowed to access the privatestatic fields of its containing class. Since the static member class is compiled into an ordinary top-level class, however, there is no way it can directly access the private members of its container. Therefore, if a static member class uses a private member of its containing class (or vice versa), the compiler automatically generates non-private access methods and converts the expressions that access the private members into expressions that access these specially generated methods. These methods are given the default package access, which is sufficient, as the member class and its containing class are guaranteed to be in the same package.
0
JustinianJudge в Mega City OneMaster
30 августа 2019, 09:06
Итого, для кода:
Здесь два случая.
То что с внутреннего статического класса Car есть доступ к приватной переменной text в принципе логично. Ведь мы же можем использовать в методах класса его приватные переменные? Можем. Геттеры и сеттеры мы для внешних классов пишет. А значит, и внутренние статические классы, которые являются такими же членами класса как и поля, методы, тоже имеют к ним доступ.
Но есть и другой случай, это доступ с внешнего класса, приватных полей и методов внутреннего. Но как было написанно выше в спецификации языка, приватные члены которые находятся в самом классе, или ниже (во вложенных) являются доступными в пределах этого класса.
Про инкапсуляцию мы говорим тогда, когда есть взаимодействие внешних классов.
0
Олег
30 августа 2019, 09:39
Другими словами, чтобы не было доступа к этой переменной, надо класс Car положить в отдельный файл?
0
JustinianJudge в Mega City OneMaster
30 августа 2019, 09:44
Скажем так, если класс Car не будет внутренним классом, то доступа не будет.
Что лучше это уже вопрос ОО дизайна, там много факторов
0
Олег
30 августа 2019, 10:22
Спасибо. Вроде разобрался с этим.
А процессе обучения появился еще вопрос о передаче переменных примитивных и ссылочных типов. Я понял что примитивные типы передают (в метод например) значения, а ссылочные - ссылку. Поэтому при передаче переменной "a" в метод "change" она как бы копируется и при изменении ее копии в методе, с оригинальной переменной ничего не происходит.
Все наоборот со ссылками. При передачи объекта, в метод передается ссылка на него. И там можно менять значения объекта. Так?
0
Олег
30 августа 2019, 10:24
Не понял ТОЛЬКО с ссылками-обертками примитивных классов (Integer, String, Short). Это вроде ссылочные типы. А при передаче в метод передается значение....
0
JustinianJudge в Mega City OneMaster
30 августа 2019, 10:40
Нет.
3000 лет назад Моисей вышел из пещеры со скрижалями, на которых было записано "В джава все передается по значению".
При передаче примитивов, передается значение, например 2, 5.
При передаче в метод change, как ты заметил, изменения не затрагивают оригинальную переменную.
Ссылочные типы тоже передаются по значению, но в качестве значения идет ссылка. В чем же разница тогда, передача ссылки и передача ссылки по значению?
А все тот же метод change.
Запускаем код, и видим, что то что мы всредине метода пытались переприсвоить ссылки на объекты, никак не отобразилось на оригинальных переменных в методе main. Потому что в метод swap не пошли сами ссылки на объекты, а пошли ссылки в виде значений. Мы имеем доступ к объекту, можем его изменять, но мы не можем переназначить ссылки которые были в main. Поскольку имеем дело все с той же копией.
0
Олег
30 августа 2019, 16:46
Спасибо, разжевали все так, что все стало понятно.
Единственное, как быть с ссылками-обертками примитивных классов (Integer, Short...., да и тот же String). Они же вроде считаются ссылочными типами, так? Т.е. в виде значения передается ссылка на объект, так?
А по факту получается, что передается значение...... Вот тут еще пробел в знаниях....
p.s. Извините, за мою ТУПОСТЬ!
0
JustinianJudge в Mega City OneMaster
30 августа 2019, 17:05
самый глупый вопрос, не заданный. Так что все спрашиваешь по делу, и другим полезно будет почитать, так что делаешь общественно-полезную работу.
Но вот в этой части я не совсем понял, что ты имеешь ввиду, "по факту передается значение". приведи пример кода или своими словами расскажи.
Это все тот же объект, просто есть специфика, что классы обертки и Стринг они immutable, то есть при изменении значения создается новый объект и переприсваивается переменной (если для оберток, для стринга чуть сложнее, но принцип тот же).
0
Олег
30 августа 2019, 18:14
Спасибо. Почитал еще статью здесь про Immutable-типы.
Сложно конечно с первого раза, но упорство и труд.....все перетруд!
0