Java programming ideas - detail Java inner classes (on)

  • A class placed inside another class is an inner class
  • The inner class knows about the outer class and can communicate with the outer class
  • Inner class and composition are not the same concept

First, the creation of inner classes

Small example of inner class:

class A{
  class B{ //The method body of the inner class is the same as the ordinary class
     private int num=0;
     B(){}
     void f(){}
  }
  private String name="Hello";
  public void setName(String name){
    this.name=name;
  }
}

The outer class calls the inner class:

class A{
   class B{ //Inner class (inner structure is the same as ordinary class)
      private String name;
      B(String name){
	this.name=name;
      }
     public String getName(){
        return name;
     }
   }
   public B getB(String name){
     return new B(name);
   }
}
public class C{
  public static void main(String[] args)
  {
     A a=new A();
     A.B b=a.getB("Hello Java!");
     System.out.print(b.getName());
  }
}

Decompile the above example to see the code style compiled by the compiler:


It can be seen that the inner class will also be compiled into a separate .class file, but the inner class will also be included in the compiled file of the class where it is located.

2. External communication

When an object of an inner class is generated, there is a connection between this object and the surrounding object that constructs it, so it can access all members of the surrounding object (including private members) without any special conditions. (Inner classes in C++ are just a simple name-hiding mechanism and cannot be associated with surrounding objects, nor do they have implicit access rights).

A small example:

public class Test{
   private static Object[] obj;
   private static int i=0;
   private void add(int i){
	  obj[this.i]=i;
	  this.i++;
   }
   class RunTest{
     public void insertValues(){
	obj=new Object[10];//Use the private members of the enclosing class
	for (int ind = 0; ind <10; ind ++) {
	    add(ind);//Use the private method of the enclosing class
	}
      }
   }
   public RunTest getRunTest(){
	   return new RunTest();
   }
    public static void main(String[] args){
	   Test test=new Test();
	   Test.RunTest t=test.getRunTest();
	   t.insertValues();
       for(int i=0;i<obj.length;i++){
          System.out.print(obj[i]+" ");
       }
    }
}

The decompiled inner class is as follows:

class Test$RunTest
{
  Test$RunTest(Test paramTest) {}
  public void insertValues()
  {
    Test.access$002(new Object[10]);
    for (int i = 0; i < 10; i++) {
      Test.access$100(this.this$0, i);
    }
  }
}
It can be seen that when the inner class accesses the members and private methods of the outer class, it will automatically obtain the reference of the outer class and access the members and methods by reference.

**How ​​to get the reference objects of inner and outer classes in other ways? **

  • The inner class gets the outer class object - through ".this"
  • The outer class gets the inner class object - through ".new"
public class A{
   class B{
     public A getA(){
         //Get a reference to A
         return A.this;
      }
   }
    public B getB(){
       //Get the object of B through the method
       return new B();
    }
   public static void main(String[] args){
      //Get the object reference of A through the constructor
      A a=new A();
      //Clearance method call to get inner class object
      A.B b=a.getB();
      //Get the inner class object through ".new"
      A.B b2=a.new B();
      //Get a reference to A by calling the inner class method
      A a2=b2.getA();
   }
}

* Let's see what the compiled versions of these creation methods look like:

//".this"——this.this$0
public A getA()
{
  return this.this$0;
}     
//".new"——
{
  tmp18_17 = localA1;
  tmp18_17.getClass();
  A.B localB2 = new A.B(tmp18_17);
  localB2.g();
}
"this$0" - a reference to the outer class where the inner class is located

From these we know:

      To directly create an object of an inner class, you cannot leave the outer class , but you must use an object of the outer class to create the inner class object, because the inner class object is implicitly connected to the outer class object that created it. But there is a special case of static inner class , which does not need a reference to the outer class object, and creates the object directly through new.

3. Inner classes in each domain

     The above inner classes are defined in the outer class and have the same status as methods and member variables. In fact, the inner class can be placed in any scope of the outer class, as shown in the following example:

public class A{
  //Define the inner class in parallel with the method
  class class B{}
  public void show(){
     //define the inner class inside the method
     class C{
        System.out.print("Hello");
     }
  }
  public void isShow(){
     if(true){
        //Create an inner class in the domain of the judgment statement
        class D{}
     }
  }
}

Notice:

      No matter which domain we define the inner class in, it is compiled by the compiler at the same time as all the classes, so the class D under the conditional if is not created when the condition is met. The only difference is that these inner classes are only valid within their own domain, and not available elsewhere.

public class A{
   public void show(){
      if(true){
          class B{
              public void isShow(){
                 System.out.print("is if class");
              }
          }
        B b=new B();
        b.isShow();
      }
        //Use B outside the if field to report an error that the symbol B cannot be found
        //B b=new B();
        //b.isShow();
   }
}

Also, upcasting for inner classes is the same as for other normal classes.

To be continued. . . . . .


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325944999&siteId=291194637
Recommended