Почему метод "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-методам. Почему это было бы, если частные методы были приватными для объекта?