1

I have read this concept in respect to static inner class : ViewHolder declared as inner class inside the adapter of ListView to enhance the performance of getView().

Consider the below class

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        ic.privateProperty = -98;
    }
}

If inner class contains private properties and an object of inner class is created inside a method of outer class then the inner class private properties can be accessed directly using . 'dot' operator.

I have read somewhere that the private properties of the inner class are accessed using synthetic setter getter methods from outer class

I want to clear my concept regarding the same.

Tobias
  • 9,170
  • 3
  • 24
  • 30
nits.kk
  • 5,204
  • 4
  • 33
  • 55
  • 1
    It is unclear what you are asking. – John B Jun 19 '14 at 16:44
  • Duplicate of: http://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members – Nathan Merrill Jun 19 '14 at 16:46
  • sorry my question is close to the link told but I wanna get clear on the concept of synthetic accessor methods used to access the private properties of inner class from outer class. – nits.kk Jun 19 '14 at 16:50

2 Answers2

4

The compiler generates method to access private members of an inner class. If you compile your example code and examine the bytecode, you will find that it is as if it were written like this:

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
        static int access$002(InnerClass obj, int value) {
            obj.privateProperty = value;
            return value;
        }
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        InnerClass.access$002(ic, -98);
    }
}

This conversion of the line

ic.privateProperty = -98;

into the method call:

InnerClass.access$002(ic, -98);

together with the creation of the static method InnerClass.access$002 is done by the compiler. The static method (named access$002 by my compiler) is an example of a "synthetic setter method" you have read about. As a result, the bytecode for the two classes do not violate Java's access rules.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Thanks Ted, this is the reply I was looking for, can you please give me some links I can go through as I could not find some proper document for the compile time methods created for inner class private properties. But one thing more , I downloaded jd-gui-0.3.6.windows decompiler and tried to read the .class file generated. But still I could not find the accessor methods. – nits.kk Jun 19 '14 at 17:00
  • @nits.kk - You don't need to use jd-gui. After generating the .class files, just run `javap -c OuterClass` and also `javap -c OuterClass$InnerClass` from the command line (assuming that your `PATH` is set up correctly). – Ted Hopp Jun 19 '14 at 20:19
  • @nits.kk - You might also want to take a look at the [Java tutorial on nested classes](http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html). – Ted Hopp Jun 19 '14 at 20:32
0

Your concept is wrong.. Inner classes are meant to use inside the container classes only, This idea coming from the concept that you don't want to expose unnecessery classes to the developer, Which is not relevant to all of the project.

In this case InnerClass will be related to only to OuterClass. In the main you should create new only to OuterClasS and the OuterClass will create instance of InnerClass

So it should be something like this:

public class OuterClass{
private InnerClass in;

public Class OuterClass() {
    in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
    in.setPrivateProperty(x);
}

public class InnerClass{
    private int privateProperty= -2;
    //getters & setters
}

public static void main(String[] args) {
    OuterClass oc = new OuterClass();
    oc.setInnerProperty(98);
}
}

In case you want to change it from the main.. This is the way to do it, but not recomended.

Hope that helps

Aviad
  • 1,539
  • 1
  • 9
  • 24
  • There is nothing at all wrong with generating an instance of an inner class from client code. That's why Java provides the syntax that OP is using--`oc.new InnerClass()`--which provides the outer class context for instantiating an inner class instance. If it were not necessary to expose `InnerClass` to the developer, then it could have been declared `private` to `OuterClass`. – Ted Hopp Jun 19 '14 at 16:55
  • Yes there is.. Java can supply a lot of flexibilty to use it.. But the way that i wrote is the proper way to handle with a problem as you asked.. There is a basics that called Information Hiding. Try to read about it.. There is always a several ways to solve problems. But only few are good solutions.. Stick to the basics always.. It will save you time later – Aviad Jun 20 '14 at 16:21