Почему метод "private" можно получить из другого экземпляра?
Несмотря на то, что это очень простой код, кажется, что в Java есть что-то принципиально ошибочное, или JVM, используемое Eclipse IDE, которое я использовал для запуска кода.
Код работает, хотя он не должен (я думаю)! Код в A.java просто отображает "Hello, я am A!"
Вот он:
import java.lang.*;
import java.util.*;
class A {
private void methodA() {System.out.println("Hello, I am A!");}
public static void main(String[] args) {
A a = new A();
a.methodA(); }
}
Я не понимаю, почему после создания экземпляра класса A main() успешно запускает закрытый метод класса А в этом экземпляре. Да, основной метод принадлежит классу A, но он не обращается к закрытому методу от внутри текущего объекта в контексте ссылки "this". Фактически, поскольку это статический метод, он не может получить доступ к нестационарным членам внутри класса. Вместо метода main() нестатический метод-член мог вызывать метод A() только из внутри. Но это еще одна проблема, поскольку я не определил какой-либо нестатический второй метод.
Теперь, когда речь идет о внутреннем просмотре, вернитесь к точке, внешний вид. Как вы можете видеть, main() пытается вызвать метод methodA из вне объекта и преуспевает! Почему частный не рассматривается как закрытый?
Я тяну свои волосы....
Кто-нибудь, ответьте...
Ответы
Ответ 1
Да, основной метод принадлежит классу A, но он не обращается к частному методу изнутри текущего объекта в контексте ссылки "this".
Это не имеет значения. Это просто не модель доступности, которую использует Java. Что важно для класса, в котором написан код, а не для доступа к ним в одном и том же объекте.
Это очень полезно, так как в противном случае (например) было бы невозможно реализовать метод equals
, используя закрытых членов обоих классов.
Возможно, это не так, как вы бы выбрали язык, но именно так определяется Java. Подробнее о доступности можно узнать в JLS 6.6.1. В частности:
В противном случае, если член или конструктор объявлен приватным, доступ разрешен тогда и только тогда, когда он встречается внутри тела класса верхнего уровня (§7.6), который включает объявление члена или конструктора.
Обратите внимание, что доступ protected
здесь немного нечетный: защищенный экземпляр класса класса SuperClass
доступен только через код в SubClass
посредством выражения либо SubClass
, либо другого подкласса. Но он все равно не должен быть "тем же" объектом.
Ответ 2
частный modifer
Методы, переменные и конструкторы, объявленные как private, могут быть доступны только в объявленном классе.
Ответ 3
private
означает "частный для класса". Не "частный для экземпляра".
Что позволяет реализовать такие вещи, как static factory методы, вызывающие частные конструкторы, или методы equals()
или compareTo()
, сравнивающие частные поля объектов одного и того же класса или конструкторы копирования и т.д.
Частные члены охватывающих классов также доступны из внутренних классов этого охватывающего класса и наоборот.
Ответ 4
После технически правильных ответов здесь мои два цента, почему я думаю, что вполне разумно реализовать private
следующим образом:
Как я вижу, главная причина, по которой существуют методы и атрибуты private
, - это "скрытие реализации". Вы объявляете "Не используйте этот метод вне моего класса (!), Так как он может меняться или исчезать в любое время". Поэтому имеет смысл запретить доступ извне класса. Но если я получаю доступ к нему из другого объекта того же класса я и делаю любые изменения в реализации, я хорошо знаю об изменениях и обращениях частных членов и могу действовать соответственно.
Еще одна вещь, о которой нужно подумать:
Если класс B расширяет класс A, то любой B-объект также является A-объектом, но он не может получить доступ к частным A-методам. Почему это было бы, если частные методы были приватными для объекта?