Java Syntax Sugar 4: Inner class

Source: Internet
Author: User

Inner class

The last syntactic sugar, the inner class, the inner class refers to the definition of a class within a class.

The inner class is also a syntactic sugar, because it is just a compile-time concept, Outer.java inside defines an internal class inner, once compiled successfully, will generate two completely different. class files, respectively Outer.class and outer$ Inner.class. So the name of the inner class can be exactly the same as its outer class name .

The inner class is divided into four types: member inner class, local inner class, anonymous inner class, static inner class. Look at the next one, and then see what the benefits of using inner classes are.

member Inner class

The member inner class is the most common inner class, which is to define the class in terms of the general definition class on the basis of the outer class, and see an example:

PublicClassouter{PrivateIntIPublic Outer (Inti) {THIS.I =I }public voidnew Privateinner (). PrintI ();} Span style= "color: #0000ff;" >private class Privateinner { public void PrintI () { System.out.println (i); }} public classprivate int i = 2 public void PrintI () { System.out.println (i); } }} 

The main functions are:

void Main (string[] args) {    new Outer (0); Outer.privateinnergeti (); Outer.publicinner Publicinner = Outer. new Publicinner (); Publicinner.printi ();}    

The result of the operation is:

02

Summarize the points through this example:

1, the member inner class is dependent on its external class and exists, if you want to produce a member inner class, such as having an instance of its outer class

2. There is no static method defined in the member's inner class, not the example does not want to write, but the member inner class cannot define the static method

3, the member inner class can be declared private, the member inner class declared as private is not visible externally, the public method of inner class of private member cannot be called outside

4. The member inner class can be declared public, the inner class of the member declared as public is visible externally, and the public method of the common member inner class can be called externally.

5. The member inner class can access the private property of its outer class, and the property value of the member's inner class will prevail if the property of the member's inner class and the property of its outer class have the same name.

Local inner class

A local inner class is a class defined in a method or a specific scope, and the use of a local inner class is seen:

void Main (string[] args) {    int i = 0classvoid print () {System.out.println ("AAA, i =" +new
                 
                   A (); A.print ();} 
                      

Note that the local inner class does not have an access modifier, and another local inner class accesses an external variable or object, and the reference to the variable or object must be a final decorated

Anonymous inner class

This should be the most used, because it is convenient to use the anonymous inner class in the code example in the multithreaded module, to find a section:

PublicStaticvoid Main (string[] args)Throwsinterruptedexception{Final ThreadDomain44 td =NewThreadDomain44 (); Runnable Runnable =new Runnable () { public void Run () {Td.testmethod ();}}; thread[] Threads = new thread[10]; For (int i = 0; i < i++) threads[i] = new Thread (runnable); For (int i = 0; i < i++) Threads[i].start (); Thread.Sleep (+); System.out.println ("with" + td.lock.getQueueLength () "Threads are waiting! ");}

Anonymous inner classes are the only classes that do not have constructors, have a limited scope of use, and are generally used to inherit abstract classes or implement interfaces (note that only abstract classes are inherited, not ordinary classes), and anonymous inner classes are automatically named Xxx$1.classs. In addition, as with local inner classes, TD must be final decorated.

Static Inner class

The inner class that is decorated with static is the static inner class, which looks at the following example:

PublicClass outer{private static Span style= "color: #0000ff;" >final int i = 1;static classpublic void  Notstaticprint () {System.out.println ("Outer.staticInner.notStaticPrint (), i =" +< Span style= "color: #000000;" > i); } public static void< Span style= "color: #000000;" > Staticprint () {System.out.println ("Outer.staticInner.staticPrint ()"    
void Main (string[] args) {    new Outer.staticinner (); Os.notstaticprint (); Outer.staticInner.staticPrint ();}  

The result of the operation is:

Outer.staticInner.notStaticPrint (), i = 1Outer.staticInner.staticPrint ()

Summarize the points through this example:

1, static internal classes can have static methods, can also have non-static methods

2. Static Internal classes can only access static members and static methods of their external classes

3, as with ordinary classes, to access static methods of static internal classes, you can directly "." Does not require a class instance; To access a non-static method of a static inner class, you must get an instance object of a static inner class

4. Note the differences in how to instantiate a member's inner class and instantiate a static inner class when two different inner classes

(1) member Inner class: Outer class. Inner Class XXX = external class. New inner Class ();

(2) Static inner class: Outer class. Inner class XXX = new External class. Inner class ();

Why members inner classes can access external class members

Use the "JAVAP" command to decompile the inner class privateinner of the first example:

Take a look at the symbol references in the constant pool in this inner class to know:

Constant Pool: #1 = Class #2//Com/xrq/test29/outer$privateinner #2 = Utf8 com/xrq/test29/Outer$privateinner #3 = Class #4//Java/lang/object #4 = Utf8 java/lang/Object #5 = Utf8This$0#6 = Utf8 lcom/xrq/test29/Outer; #7 = Utf8 <init>#8 = Utf8 (lcom/xrq/test29/Outer;) V #9 =Utf8 Code #10 = Fieldref #1. #11//Com/xrq/test29/outer$privateinner.this$0:lcom/xrq/test29/Outer; #11 = Nameandtype #5: #6//This$0:lcom/xrq/test29/outer; #12 = MethodRef #3. #13//Java/lang/object. " <init>:() V #13 = Nameandtype #7: #14//"<init>":() V #14 =Utf8 () V #15 =Utf8 linenumbertable #16 =Utf8 localvariabletable #17 = Utf8This#18 = Utf8 lcom/xrq/test29/Outer$privateinner; #19 =Utf8 PrintI #20 = Fieldref #21. #23//Java/lang/system.out:ljava/io/prinTStream; #21 = Class #22//Java/lang/system #22 = Utf8 java/lang/System #23 = Nameandtype #24: #25//Out:ljava/io/printstream; #24 =Utf8 out #25 = Utf8 ljava/io/PrintStream; #26 = MethodRef #27. #29//Com/xrq/test29/outer.access$0: (lcom/xrq/test29/Outer;) I #27 = Class #28//Com/xrq/test29/outer #28 = Utf8 com/xrq/test29/Outer #29 = Nameandtype #30: #31//Access$0: (lcom/xrq/test29/outer;) I#30 = Utf8 access$0#31 = Utf8 (lcom/xrq/test29/Outer;) I #32 = MethodRef #33. #35//Java/io/printstream.println: (I) V #33 = Class #34//Java/io/printstream #34 = Utf8 java/io/printstream #35 = Nameandtype #36: #37 // println: (i) v #36 = Utf8 println #37 = Utf8 (I) v #38 = Utf8 ( Lcom/xrq/test29/outer; Lcom/xrq/test29/outer$privateinner;) V #39 = MethodRef #1. #40 // Com/xrq/test29/outer$privateinner. " <init> ":(Lcom/xrq/test29/outer;) V #40 = Nameandtype #7: #8 // #41 =< Span style= "color: #000000;" > Utf8 sourcefile #42 = Utf8 Outer.java #43 = Utf8 Innerclasses #44 = Utf8 privateinner            

The key place is two:

1, Lines 5th and 6th, Outer$privateinner inside there is a this$0, it is a lcom/xrq/test29/outer, the beginning of the L represents a compound object. This indicates that there is a reference to its outer class in the inner class

Lines 2, 7th, and 8th, representing the this$0 this reference is assigned through the constructor function

By the way, a static inner class does not hold a reference to its outer class

The reason that local inner classes and anonymous inner classes can only access final local variables

That's how I understand the problem:

At the beginning, the inner class is a kind of syntactic sugar, the so-called syntax sugar, is the Java compiler during the compilation of hands and feet, since it is done during compilation, so how to know how to determine the value of a local variable during the Run method? Make clear two points first:

1. Anonymous inner class is the only class without constructors

2, the local inner class has a constructor, through the constructor to the external variables into the local internal class re-use is completely possible

What if there is no constructor in the local inner class to pass in the local variable? At this time, Java thought of a way to modify the local variable to final, the final modified variable is equivalent to a constant, compile can be determined and put into a constant pool. So even if the anonymous inner class does not have a constructor, the local inner class does not define a parameter constructor, it does not matter, anyway, the variable to use the compile time has been determined, then go to the constant pool inside to take a look.

Since the above is said to "go to a constant pool inside to take a bit," then the local internal class, anonymous inner class to use the local variable set to static is also possible (but static can not be modified local variables, can be placed outside the method), you can try it yourself

Benefits of using internal classes

Finally, let's summarize the benefits of using internal classes:

1, Java allows the implementation of multiple interfaces, but does not allow the inheritance of multiple classes, using the member inner class can solve the Java does not allow the inheritance of multiple classes. Write a member inner class inside a class, you can let this member inner class inherit some original class, and this member inner class can directly access all the properties and methods in its outer class, is it equivalent to multiple inheritance?

2. The member inner class can directly access the private property of its external class, and a new external class must access the private property of the class through Setter/getter

3, some classes clearly know that in addition to a fixed place in the program there will be no other place to use this class, for this one-time class to define an external class is obviously not necessary, so you can define a local inner class or member inner class, write a piece of code to use the good

4, the internal class to some extent effectively hide their own, such as our common development tools eclipse, MyEclipse, see the code is generally used are packge this navigator, Only. java files under the package, we don't see the. java file for the defined inner class.

5. Use inner classes to make the logical connection between classes and classes more tightly

Java Syntax Sugar 4: Inner class

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.