In the document ".android.com", there is an article about performance, which mentions the use of internal classes. In this article, we recommend that you use the package access permission instead of the private access permission for private internal classes ",
This section describes the internal class access to external class members or methods. If the internal class is private and the external class members are also private, then the compiler adds a static method to the internal class.
Is that true? You only need to give it a try.
Let's use a simple example to test:
public class One {private int a;private class B{public int getA(){return a;}}}
The code above creates a private internal class B for One, and a method in B accesses private member a in One. Compile the above code into a dex file and export the script code and class information of the program.
The export result is as follows:
Processing 'one.dex'...Opened 'one.dex', DEX version '035'Class #0 - Class descriptor : 'LOne$B;' Access flags : 0x0000 () Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne$B;) name : 'this$0' type : 'LOne;' access : 0x1010 (FINAL SYNTHETIC) Direct methods - #0 : (in LOne$B;) name : '
' type : '(LOne;)V' access : 0x10002 (PRIVATE CONSTRUCTOR) code - registers : 2 ins : 2 outs : 1 insns size : 6 16-bit code units0001a0: |[0001a0] One.B.
:(LOne;)V0001b0: 5b01 0000 |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@00000001b4: 7010 0400 0000 |0002: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@00040001ba: 0e00 |0005: return-void catches : (none) positions : 0x0000 line=7 locals : 0x0000 - 0x0006 reg=0 this LOne$B; Virtual methods - #0 : (in LOne$B;) name : 'getA' type : '()I' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 1 insns size : 7 16-bit code units0001bc: |[0001bc] One.B.getA:()I0001cc: 5410 0000 |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@00000001d0: 7110 0300 0000 |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // method@00030001d6: 0a00 |0005: move-result v00001d8: 0f00 |0006: return v0 catches : (none) positions : 0x0000 line=10 locals : 0x0000 - 0x0007 reg=1 this LOne$B; source_file_idx : 10 (One.java)Class #1 - Class descriptor : 'LOne;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne;) name : 'a' type : 'I' access : 0x0002 (PRIVATE) Direct methods - #0 : (in LOne;) name : '
' type : '()V' access : 0x10001 (PUBLIC CONSTRUCTOR) code - registers : 1 ins : 1 outs : 1 insns size : 4 16-bit code units0001dc: |[0001dc] One.
:()V0001ec: 7010 0400 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@00040001f2: 0e00 |0003: return-void catches : (none) positions : 0x0000 line=3 locals : 0x0000 - 0x0004 reg=0 this LOne; #1 : (in LOne;) name : 'access$0' type : '(LOne;)I' access : 0x1008 (STATIC SYNTHETIC) code - registers : 2 ins : 1 outs : 0 insns size : 3 16-bit code units0001f4: |[0001f4] One.access$0:(LOne;)I000204: 5210 0100 |0000: iget v0, v1, LOne;.a:I // field@0001000208: 0f00 |0002: return v0 catches : (none) positions : 0x0000 line=5 locals : Virtual methods - source_file_idx : 10 (One.java)
Haha, we don't see One more method in One, but we don't have One in the source code.
One.access$0:(LOne;)I
Now let's change the source code.
public class One {private int a;class B{public int getA(){return a;}}}
Then compile and export:
Processing 'one.dex'...Opened 'one.dex', DEX version '035'Class #0 - Class descriptor : 'LOne$B;' Access flags : 0x0000 () Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne$B;) name : 'this$0' type : 'LOne;' access : 0x1010 (FINAL SYNTHETIC) Direct methods - #0 : (in LOne$B;) name : '
' type : '(LOne;)V' access : 0x10000 (CONSTRUCTOR) code - registers : 2 ins : 2 outs : 1 insns size : 6 16-bit code units0001a0: |[0001a0] One.B.
:(LOne;)V0001b0: 5b01 0000 |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@00000001b4: 7010 0400 0000 |0002: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@00040001ba: 0e00 |0005: return-void catches : (none) positions : 0x0000 line=7 locals : 0x0000 - 0x0006 reg=0 this LOne$B; Virtual methods - #0 : (in LOne$B;) name : 'getA' type : '()I' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 1 insns size : 7 16-bit code units0001bc: |[0001bc] One.B.getA:()I0001cc: 5410 0000 |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@00000001d0: 7110 0300 0000 |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // method@00030001d6: 0a00 |0005: move-result v00001d8: 0f00 |0006: return v0 catches : (none) positions : 0x0000 line=10 locals : 0x0000 - 0x0007 reg=1 this LOne$B; source_file_idx : 10 (One.java)Class #1 - Class descriptor : 'LOne;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne;) name : 'a' type : 'I' access : 0x0002 (PRIVATE) Direct methods - #0 : (in LOne;) name : '
' type : '()V' access : 0x10001 (PUBLIC CONSTRUCTOR) code - registers : 1 ins : 1 outs : 1 insns size : 4 16-bit code units0001dc: |[0001dc] One.
:()V0001ec: 7010 0400 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@00040001f2: 0e00 |0003: return-void catches : (none) positions : 0x0000 line=3 locals : 0x0000 - 0x0004 reg=0 this LOne; #1 : (in LOne;) name : 'access$0' type : '(LOne;)I' access : 0x1008 (STATIC SYNTHETIC) code - registers : 2 ins : 1 outs : 0 insns size : 3 16-bit code units0001f4: |[0001f4] One.access$0:(LOne;)I000204: 5210 0100 |0000: iget v0, v1, LOne;.a:I // field@0001000208: 0f00 |0002: return v0 catches : (none) positions : 0x0000 line=5 locals : Virtual methods - source_file_idx : 10 (One.java)
There are still additional methods
One.access$0:(LOne;)I
We are modifying it.
public class One {int a;class B{public int getA(){return a;}}}
Compile and export
Processing 'one.dex'...Opened 'one.dex', DEX version '035'Class #0 - Class descriptor : 'LOne$B;' Access flags : 0x0000 () Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne$B;) name : 'this$0' type : 'LOne;' access : 0x1010 (FINAL SYNTHETIC) Direct methods - #0 : (in LOne$B;) name : '
' type : '(LOne;)V' access : 0x10000 (CONSTRUCTOR) code - registers : 2 ins : 2 outs : 1 insns size : 6 16-bit code units000184: |[000184] One.B.
:(LOne;)V000194: 5b01 0000 |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@0000000198: 7010 0300 0000 |0002: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@000300019e: 0e00 |0005: return-void catches : (none) positions : 0x0000 line=7 locals : 0x0000 - 0x0006 reg=0 this LOne$B; Virtual methods - #0 : (in LOne$B;) name : 'getA' type : '()I' access : 0x0001 (PUBLIC) code - registers : 2 ins : 1 outs : 0 insns size : 5 16-bit code units0001a0: |[0001a0] One.B.getA:()I0001b0: 5410 0000 |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@00000001b4: 5200 0100 |0002: iget v0, v0, LOne;.a:I // field@00010001b8: 0f00 |0004: return v0 catches : (none) positions : 0x0000 line=10 locals : 0x0000 - 0x0005 reg=1 this LOne$B; source_file_idx : 9 (One.java)Class #1 - Class descriptor : 'LOne;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LOne;) name : 'a' type : 'I' access : 0x0000 () Direct methods - #0 : (in LOne;) name : '
' type : '()V' access : 0x10001 (PUBLIC CONSTRUCTOR) code - registers : 1 ins : 1 outs : 1 insns size : 4 16-bit code units0001bc: |[0001bc] One.
:()V0001cc: 7010 0300 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.
:()V // method@00030001d2: 0e00 |0003: return-void catches : (none) positions : 0x0000 line=3 locals : 0x0000 - 0x0004 reg=0 this LOne; Virtual methods - source_file_idx : 9 (One.java)
There is no additional method.
If the members of the External class access the package, the internal class is private, and no additional method will be generated.
Internal class External Department members cannot access private members directly. The compiler will add additional auxiliary methods to avoid modifying external class members as package access, the document also mentions that this will damage to a certain extent.
Encapsulation.