4

Since an enclosing class can access the private fields of its inner class, when should be they declared private, default or public for a private inner class?

Ravi
  • 172
  • 2
  • 9
  • Inner classes can also be used by other classes not enclosing it. – Henry Jul 18 '17 at 04:45
  • 1
    Maybe: https://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members?rq=1 –  Jul 18 '17 at 04:59
  • 1
    Is the inner class public or private? – ajb Jul 18 '17 at 06:02
  • Possible duplicate of [Why can outer Java classes access inner class private members?](https://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members) – Raedwald Jul 18 '17 at 08:39
  • 1
    The inner class is private. stackoverflow.com/questions/1801718 tries to give the rationale of why outer class can access inner class' private fields, but not what their access-modifiers should be. As an example, see ArrayList$Sublist. It has 3 fields as private and 1 field as default. – Ravi Jul 18 '17 at 13:56

3 Answers3

4

At first glance, it seems irrelevant to specify an access modifier on the members of inner classes. As you pointed out, the containing class can access all members anyway.

Here are a few additional considerations though:

  • Sometimes inner classes are declared public and serve as part of the interface definition of the containing class. Perhaps the outer class has a method that returns an instance of the inner class. In this case, the inner class is subject to the same best practices for member visibility as top-level classes. It's preferrable to keep implementation details private in this case.
  • Although it wouldn't be enforced by the compiler, marking an inner class's members as private can document for future maintainers that those members are not intended to be accessed directly by the outer class code. Of course, at that point, it might warrant refactoring the inner class to its own top-level class.
  • Sometimes inner classes are used in combination with reflection-based frameworks that only operate on public members. For example, the Jackson JSON serializer by default only operates on public members. It is possible to make it operate on private members by doing a few things like adding a public getter. This is extra work, so it may be more convenient to declare the member public in the first place.
  • If the above points do not apply, and in the absence of any other requirements, the simplest and shortest code is to omit the access modifier entirely (default/package-private). This would be a coding style question for a project to consider.
Chris Nauroth
  • 9,614
  • 1
  • 35
  • 39
0

It's a good style to declare everything private unless there is a reason to use package private or public visibility. And this reason should not be it's more convenient.

Everything that is not private may be used outside of your class and thus changes to any non-private aspect of your code may break other code places or even external code that relies on your code. Making more difficult or sometimes even impossible to do refactorings and change the inner workings of your classes.

In the special case of a private inner class everything is only visible to your containing class. That is the visibility of the inner classes' members is not of importance. To the other extreme, if you are working on a library its common practice to only expose interfaces as contract. Keeping the implementation details completely hidden.

dpr
  • 10,591
  • 3
  • 41
  • 71
0

Not only the outer class but also other classes can access inner class and its members .So when you want to make the inner class members accessible by only its outer class you can declare them as private . consider the fallowing example

There are 2 classes in same package com.exercise.test and classes in it are OtherClass and SampleClassWithInner which contains inner class InnerClass

the members of InnerClass declared as private is not accessible in OtherClass. Where as it is accessible in SampleClassWithInner

refer this code for more clarity

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();
    }

}

and

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);

    }
} 
harsha kumar Reddy
  • 1,251
  • 1
  • 20
  • 32
  • The op is asking what use would the private modifier add to your code it the inner class has already a private modifier. Of course if tbe inner class is public then yeah but if the inner class has the private modifier then there is no use of having and modifier for the var1 and var2 – StudentAccount4 Aug 27 '20 at 04:42