Возможен ли доступ к частному полю Java при наличии ссылки?

Сегодня я натолкнулся на следующую «странную» особенность - если у вас есть ссылка на объект из класса A в теле класса A, вы можете получить доступ к закрытым полям этого объекта - т.е.

public class Foo{
   private int bar;
   private Foo foo;
   public void f()
   {
       if(foo.bar == bar) // foo.bar is visible here?!
       {
            //
       }
   }
}

У кого-нибудь есть хорошее объяснение по этому поводу?

 Stephen C27 окт. 2011 г., 15:14
 S.L. Barth27 окт. 2011 г., 15:08
Эта функция очень полезна, когда вам нужно написатьequals метод.

Ответы на вопрос(7)

он имеет право доступа к закрытым членам Foo. Это не удивительно для меня.

 asenovm27 окт. 2011 г., 15:08
дело в том, почему мы можем получить доступ к foo.bar, когда foo является другим экземпляром класса Foo, а bar является частным полем
 LLS27 окт. 2011 г., 15:15
@iLate: я думаю, что дизайнеры просто следовали поведению C ++.
 Jon Skeet27 окт. 2011 г., 15:09
@iLate: Потому что так указан язык ...

Ссылаясь наСпецификация языка Java:

Элемент (класс, интерфейс, поле или метод) ссылочного типа (класс, интерфейс или массив) или конструктор типа класса доступен только в том случае, если тип доступен, а элемент или конструктор объявлен для разрешения доступа:

...(В противном случае), если член или конструктор объявляется закрытым, тогда доступ разрешается тогда и только тогда, когда это происходит в теле класса верхнего уровня (§7.6), который включает в себя объявление члена....
 S.L. Barth27 окт. 2011 г., 15:16
+1 за ссылку JLS.

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

Таким образом, частные Конструкторы работают в Singletons и т. Д.

Решение Вопроса

а не на уровне экземпляра: весь код одного и того же класса может иметь доступ к закрытым членам всех экземпляров класса.

Ничего особенно странного в этом нет.

а не на объект. Так что он просто смотрит и видит: «О, объект класса Foo пытается получить доступ к закрытому объекту в Foo. Ну, это нормально».

@Michaelответ правильный. Поведение одинаково для.NET за@asenovmкод.

Кроме того, то же самое для внутренних классов, а также дляJava, Даже если вы определили переменную как приватную, вы можете получить к ней доступ. Я удивился, когда я столкнулся сначала, потому что это отличается дляC#.

public class WrapperClass
{

  public static  class NotThreadsafe {
        private int x = 0;
       //....          
    }

    public static void main(String[] args) {           
    final NotThreadsafe nts=new NotThreadsafe(); 
     int x = nts.x ; // !!! THIS IS ACCESSIBLE AS WELL FOR JAVA BUT NOT.NET
    }
}

Это не то же самое дляC# вложенные классы. Если вы вставите этот код в Visual Studio, он не будет работать. Компилятор беспокоится об уровнях доступа.

если учесть намерение модификатора «private» скрыть детали реализации.

Попробуйте думать об этом в терминах «это должно быть приватно для этого класса» (что в Java равнозначно «это должно быть приватно для этого исходного файла»), а не «это должно быть приватно для этого экземпляра».

Ваш ответ на вопрос