Java - частный член против члена по умолчанию частного внутреннего класса

Поскольку объемлющий класс может получить доступ к закрытым полям своего внутреннего класса, когда они должны быть объявлены закрытыми, по умолчанию или общедоступными для частного внутреннего класса?


person Ravi    schedule 18.07.2017    source источник
comment
Внутренние классы также могут использоваться другими классами, не включающими его.   -  person Henry    schedule 18.07.2017
comment
Возможно: stackoverflow.com/questions/1801718/   -  person    schedule 18.07.2017
comment
Является ли внутренний класс публичным или приватным?   -  person ajb    schedule 18.07.2017
comment
Внутренний класс является закрытым. stackoverflow.com/questions/1801718 пытается объяснить, почему внешний класс может получить доступ к закрытым полям внутреннего класса, но не то, какими должны быть их модификаторы доступа. В качестве примера см. ArrayList$Sublist. Он имеет 3 поля как частные и 1 поле по умолчанию.   -  person Ravi    schedule 18.07.2017


Ответы (3)


На первый взгляд кажется неуместным указывать модификатор доступа для членов внутренних классов. Как вы указали, содержащий класс в любом случае может получить доступ ко всем членам.

Однако есть несколько дополнительных соображений:

  • Иногда внутренние классы объявляются public и служат частью определения интерфейса содержащего класса. Возможно, у внешнего класса есть метод, возвращающий экземпляр внутреннего класса. В этом случае на внутренний класс распространяются те же рекомендации по видимости членов, что и на классы верхнего уровня. В этом случае предпочтительнее сохранить детали реализации private.
  • Хотя компилятор не навязывает это, пометка членов внутреннего класса как private может задокументировать для будущих сопровождающих, что эти члены не предназначены для прямого доступа из кода внешнего класса. Конечно, в этот момент может потребоваться рефакторинг внутреннего класса в его собственный класс верхнего уровня.
  • Иногда внутренние классы используются в сочетании с фреймворками на основе отражения, которые работают только с public элементами. Например, сериализатор JSON Jackson по умолчанию работает только с public участниками. Можно заставить его работать с членами private, выполнив несколько действий, таких как добавление геттера public. Это дополнительная работа, поэтому может быть удобнее сначала объявить элемент public.
  • Если вышеуказанные пункты неприменимы и при отсутствии каких-либо других требований, самый простой и короткий код — полностью исключить модификатор доступа (default/package-private). Это будет вопрос стиля кодирования для проекта.
person Chris Nauroth    schedule 18.07.2017

Это хороший стиль объявлять все приватным, если только нет причин использовать приватный или общедоступный пакет. И эта причина не должна быть так удобнее.

Все, что не является частным, может использоваться вне вашего класса, и, таким образом, изменения в любом нечастном аспекте вашего кода могут нарушить работу других мест кода или даже внешнего кода, который зависит от вашего кода. Усложняет, а иногда даже делает невозможным рефакторинг и изменение внутренней работы ваших классов.

В частном случае внутреннего класса private все видно только содержащему его классу. То есть видимость членов внутренних классов значения не имеет. С другой стороны, если вы работаете над библиотекой, обычной практикой является предоставление интерфейсов только как контракт. Сохранение деталей реализации полностью скрытыми.

person dpr    schedule 18.07.2017

Не только внешний класс, но и другие классы могут получить доступ к внутреннему классу и его членам. Поэтому, если вы хотите сделать члены внутреннего класса доступными только для его внешнего класса, вы можете объявить их как частные. рассмотрим следующий пример

В одном пакете com.exercise.test есть 2 класса, а в нем есть классы OtherClass и SampleClassWithInner, которые содержат внутренний класс InnerClass.

члены InnerClass, объявленные как частные, недоступны в OtherClass. Где как это доступно в SampleClassWithInner

обратитесь к этому коду для большей ясности

package com.exercise.test;
//import  com.exercise.test.SampleClassWithInner.InnerClass;

public class OtherClass {
public static void main(String[] args) {
    // TODO Auto-generated method stub
    SampleClassWithInner sampleobj = new SampleClassWithInner();
    SampleClassWithInner.InnerClass innerobj = sampleobj.new InnerClass();

    // innerobj.var1=5; //compile time error
    innerobj.setVar1(5); // ok works
    // System.out.println("value of inner variable declared in other
    // class"+innerobj.var1);// compile time error
    System.out.println("value of inner variable declared in other class " 

+ innerobj.getVar1());
        sampleobj.innerMethodDemo();
    }

}

а также

package com.exercise.test;

public class SampleClassWithInner {

class InnerClass {
    private int var1;
    private int var2;

    public int getVar1() {
        return var1;
    }

    public void setVar1(int var1) {
        this.var1 = var1;
    }

    public int getVar2() {
        return var2;
    }

    public void setVar2(int var2) {
        this.var2 = var2;
    }
}

public void innerMethodDemo() {
    InnerClass obj = new InnerClass();
    obj.var1 = 10;
    System.out.println("this is form the method in outer class " + 

obj.var1);

    }
} 
person harsha kumar Reddy    schedule 18.07.2017
comment
Оператор спрашивает, какое использование частного модификатора добавит в ваш код, если внутренний класс уже имеет частный модификатор. Конечно, если внутренний класс является общедоступным, то да, но если внутренний класс имеет модификатор private, тогда нет смысла иметь модификатор и для var1 и var2. - person StudentAccount4; 27.08.2020