Essence inner classes - Java programming logic (21)

Inner classes

Before we call the class corresponds to a separate Java source files, but may also be placed inside a class of another class, called the class of internal, relatively speaking, it comprises a class known as external class.

Why should we put it inside another class? In general, the internal class that contains its external class has relatively close relationship, but has little relationship with the other classes, defined inside the class can be achieved on the outside is completely hidden, can have a better encapsulation, also on code implementation often more concise.

However, just like the concept of internal Java compiler for the Java virtual machine, it is the inner class does not know a thing, and inside each category will finally be compiled as a separate class, to generate an independent bytecode file.

That, in fact, inside each class can be replaced with a separate class. Of course, this is purely on the technical implementation, inner classes can easily access the outer class private variables can be declared as private in order to achieve the external completely hidden, the relevant code to write together, and more concise wording, these are inner classes the benefits of.

In Java, the position and define different internal there are four categories:

  • Static inner classes
  • Members of the inner class
  • Method inner class
  • Anonymous inner classes

Methods inner class is defined and used in a way anonymous inner class uses a smaller scale, they can not be used outside, members of the inner class and static inner classes can be used outside, but they can be declared as private, so , it is not the external use.

Next, we introduce one by one these internal grammar class, implement the principles and usage scenarios.

Static inner classes

grammar

Same position as the static inner classes and static variables and methods defined, but also with the static keyword, except that it is the class definition, the following sample code:

Copy the code
public class Outer {
    private static int shared = 100;
    
    public static class StaticInner {
        public void innerMethod(){
            System.out.println("inner " + shared);
        }
    }
    
    public void test(){
        StaticInner si = new StaticInner();
        si.innerMethod();
    }
}
Copy the code

External class Outer, inner static class StaticInner, with the static modifier. Syntactically, static inner classes in addition to another position on the inside of the outer class, it comes with a separate class is not very different, there may be static variables, static methods, member methods, member variables, constructors, and so on.

Static inner classes and outside class contact is not large (compared to other rear inner class). It can access an external static class variables and methods, such as direct access to a shared variable innerMethod, but not access the instance variables and methods. Within the class, the internal static class may be used directly, such as test () method of FIG.

public static internal class can be used externally, but need to use the "external static inner class Class." manner, as follows:

Outer.StaticInner si = new Outer.StaticInner();
si.innerMethod();

The principle

The above code actually generates two classes, one is the Outer, the other Outer $ StaticInner, about their code as follows:

Copy the code
public class Outer {
    private static int shared = 100;
    
    public void test(){
        Outer$StaticInner si = new Outer$StaticInner();
        si.innerMethod();
    }
    
    static int access$0(){
        return shared;
    }
}
Copy the code
public class Outer$StaticInner {
    public void innerMethod() {
        System.out.println("inner " + Outer.access$0());
    }
}

Internal class visited a private static variable shared outside of class, and we know that private variables can not be like external access, Java solution is to automatically generate a non-proprietary access methods access $ 0 for the Outer, which returns this private static variables shared.

scenes to be used

Static inner classes are many usage scenarios, if it is close to the external class, class instance does not depend on the outside, it can be considered as a static inner class defined.

For example, inside a class, if it is necessary to calculate the maximum, but also to calculate the minimum, maximum and minimum values ​​will be calculated in the next iteration, but how to return it? You can define a class Pair, including maximum and minimum, but Pair the name is too common, and it is primarily for internal use class, it can be defined as a static inner classes.

We can also look at some examples using static inner classes in the Java API:

  • Internal Integer class has a private static inner class IntegerCache, for automatically packing support integers.
  • Internal LinkedList class represents a list of private static inner class Node, each node represents a linked list.
  • Internal Character class has a public static inner classes UnicodeBlock, it is used to represent a Unicode block.

These classes we'll introduce in a future article.

Members of the inner class

Syntax
member inner class is not static modifier, one less static modifier, but the meaning there are very different, sample code as follows:

Copy the code
public class Outer {
    private int a = 100;
    
    public class Inner {
        public void innerMethod(){
            System.out.println("outer a " +a);
            Outer.this.action();
        }
    }
    
    private void action(){
        System.out.println("action");
    }
    
    public void test(){
        Inner inner = new Inner();
        inner.innerMethod();
    }
}
Copy the code

Inner member is an internal class, the static inner classes, except for the static variables and methods, the internal member can also directly access the class instance variables and methods outside the class, such as direct access to external innerMethod private class instance variable a. Members of the class can also refer to internal instance variables and methods through the outer class "external class .this.xxx" manner, such as Outer.this.action (), such an approach is generally used in the case of the same name, if not the same name "external class .this." redundant.

Within the outer class, the class with the use of members of the internal static inner classes are the same, be directly used as test () method of FIG. And static inner classes, members of the inner class object is always connected to an external class object, when used externally, it can not create objects directly through new Outer.Inner () way, but will create a first class object Outer code as follows:

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.innerMethod();

Create an internal class object syntax is "external object .new inner class ()", as outer.new Inner ().

Internal static class, the internal members of the class may not define the static variables and methods (final variable exception, which is equivalent to a constant), the following method described inner and anonymous inner classes can not be. Why Java have this requirement? The specific reasons unknown, personally think that this provision is not necessary, Java this provision is probably because these classes are internal and external entities linked and should not be used independently, and static variables and methods as the properties and methods of the type generally independent used, within the class of little significance in it, and if the inner class does require static variables and methods can also be moved outside the class.

The principle

Code that generates more than two classes, one is the Outer, the other Outer $ Inner, about their code as follows:

Copy the code
public class Outer {
    private int a = 100;

    private void action() {
        System.out.println("action");
    }

    public void test() {
        Outer$Inner inner = new Outer$Inner(this);
        inner.innerMethod();
    }

    static int access$0(Outer outer) {
        return outer.a;
    }

    static void access$1(Outer outer) {
        outer.action();
    }
}
Copy the code
Copy the code
public class Outer$Inner {

    final Outer outer;
    
    public Outer$Inner(Outer outer){
        ths.outer = outer;
    }
    
    public void innerMethod() {
        System.out.println("outer a "
                + Outer.access$0(outer));
        Outer.access$1(outer);
    }
}
Copy the code

Outer $ Inner class of instance variables outer pointing object outside the class, it is initialized in the constructor, Outer passing current object in the new Outer $ Inner objects to it, due to the internal type of access private variables and methods external class, outer external class generates two non-private static methods, access $ 0 for accessing the variable a, access $ 1 a method for accessing action.
Usage scenarios
if the inner and outer class class close, and an external operation or class instance variables and methods rely on, can be considered as a member of the defined class interior.

Some methods of the outer class return value may be an interface, in order to return to this interface, the external class method may use an internal class that implements this interface, this internal class can be set to private, outside completely hidden.

For example, the LinkedList class in the Java API, and its two methods listIterator descendingIterator return values ​​are interfaces Iterator, the caller can iterate through the list Iterator interface, and internal listIterator descendingIterator members were using inner classes ListItr and DescendingIterator, both inner classes implement the interfaces Iterator. About LinkedList, follow-up article we will introduce.

Method inner class

grammar

Internal class can also define a method body, the sample code is as follows:

Copy the code
public class Outer {
    private int a = 100;
    
    public void test(final int param){
        final String str = "hello";
        class Inner {
            public void innerMethod(){
                System.out.println("outer a " +a);
                System.out.println("param " +param);
                System.out.println("local var " +str);
            }
        }
        Inner inner = new Inner();
        inner.innerMethod();
    }
}
Copy the code

Inner class is defined outside the class test methods, the method can only be used inside the class definition in the method. If the method is an instance method, in addition to the static variables and methods can also directly access an internal class instance variables and methods outside the class, such as direct access to external innerMethod private instance variable a. If the method is a static method, the method can only access the inner class static variables and methods of the outer class.

The method may further class internal parameters and local variables of methods in the direct access method, however, these variables must be declared final, innerMethod as direct access method parameters and local variables param str.

The principle

The system generates about two class code as follows:

Copy the code
public class Outer {
    private int a = 100;

    public void test(final int param) {
        final String str = "hello";
        OuterInner inner = new OuterInner(this, param);
        inner.innerMethod();
    }
    
    static int access$0(Outer outer){
        return outer.a;
    }
}
Copy the code
Copy the code
public class OuterInner {
    Outer outer;
    int param;
    
    OuterInner(Outer outer, int param){
        this.outer = outer;
        this.param = param;
    }
    
    public void innerMethod() {
        System.out.println("outer a "
                + Outer.access$0(this.outer));
        System.out.println("param " + param);
        System.out.println("local var " + "hello");
    }
}
Copy the code

And members of the class internal Similarly, OuterInner class has a outer pointed external object instance variable is initialized in the constructor, a method to access private instance variables is outside Outer by adding to the access $ 0.

Method inner class can access method parameters and local variables, this is achieved by passing parameters in the constructor implemented as OuterInner constructor has parameters int param, in the new OuterInner objects, Outer class parameter passing method to the inner classes, such as OuterInner inner = new OuterInner (this, param) ;. In the above code, String str has not been passed as a parameter, because it is defined to be constant in the generated code, its value may be used directly.

This also explains, why the internal class method to access external method arguments and local variables must be declared as final, because in fact, not external variables inside a method of class action, but its own instance variables , but the value of these variables and external, as these variables, which does not change the external value, to avoid confusion, this is why they must be declared as mandatory final.

If you do need to modify the external variables, the variables can be changed to an array containing only the variable, modify the value of the array, as follows:

Copy the code
public class Outer {
    public void test(){
        final String[] str = new String[]{"hello"};
        class Inner {
            public void innerMethod(){
                str[0] = "hello world";
            }
        }
        Inner inner = new Inner();
        inner.innerMethod();
        System.out.println(str[0]);
    }
}
Copy the code

str is an array with only one element.

scenes to be used

The method of internal class can be used instead of the internal class members, as for the method parameters may be transmitted to the inner member of the class as a parameter. However, if the class is only used in a method, a method using an internal class, encapsulation may be achieved better.

Anonymous inner classes

grammar

Anonymous inner classes have no name, in the same time to create an object class definitions, syntax is as follows:

new parent (parameter list) { 
   // anonymous inner classes achieve some 
}

or

new parent interface () { 
   // anonymous inner classes achieve some 
}

New anonymous inner classes is associated, in the creation of an object class definition, behind the new parent is the parent class or interface is then parentheses (), which may be a parameter of the parent class constructor is passed to, and finally braces { }, which is the definition of the class.

To see a specific code:

Copy the code
public class Outer {
    public void test(final int x, final int y){
        Point p = new Point(2,3){                
                                               
            @Override                              
            public double distance() {             
                return distance(new Point(x,y));     
            }                                      
        };                                       
                                                 
        System.out.println(p.distance());        
    }
}
Copy the code

Point object created when a defined anonymous inner classes, this class is the parent class Point, when the object is created, the parent class passed to the constructor parameter 2 and 3, the rewriting distance () method, access method, the method of the final external parameters x and y.

Anonymous inner classes can only be used once, to create an object. It has no name, no constructor, but according to the parameter list, call the parent class constructor corresponding. It can define the instance variables and methods, may block initialization, initialization code block may function construction method, but the method can be configured with a plurality, but only one initialization code block.

Because there is no constructor that they can not accept the parameters, if the parameters have to be, you should use a different internal class.

Method and internal classes, anonymous inner classes can access all methods and variables outer class method access final parameters and local variables

The principle

Each anonymous inner classes are also generated to a separate class, but other than the name of the class category with figures, there is no meaningful name. In the above example, and it produced two classes Outer Outer $. 1, about the code as follows:

Copy the code
public class Outer {
    public void test(final int x, final int y){
        Point p = new Outer$1(this,2,3,x,y);                                            
        System.out.println(p.distance());        
    }
}
Copy the code
Copy the code
public class Outer$1 extends Point {
    int x2;
    int y2;
    Outer outer;
    
    Outer$1(Outer outer, int x1, int y1, int x2, int y2){
        super(x1,y1);
        this.outer = outer;
        this.x2 = x2;
        this.y2 = y2;
    }
    
    @Override                              
    public double distance() {             
        return distance(new Point(this.x2,y2));     
    }   
}
Copy the code

Class and method similar internal and external the this example, the method parameters x and y are passed as parameters to the constructor internal class. Furthermore, parameters 2 and 3 are also passed to the new method of construction, the internal class constructor which in turn passed to a parent class constructor.

scenes to be used

Anonymous inner classes do, methods, inner classes can do. But if the object is created only once, and do not need to accept constructor parameters, you can use anonymous inner classes, more concise on writing code.

When calling the method, the method requires a lot of interface parameters, such as Arrays.sort method, it can accept an array, and a Comparator interface parameters, there is a way to compare Comparator used to compare two objects.

For example, we want to a case-insensitive string array sorting Arrays.sort methods may be used, but the need to pass an object that implements Comparator interface, then anonymous inner classes can be used, code as follows:

Copy the code
public void sortIgnoreCase(String[] strs){
    Arrays.sort(strs, new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            return o1.compareToIgnoreCase(o2);
        }
    });
}
Copy the code

Comparator behind <Stirng> generic and related objects of comparison are represented by a string type, a subsequent article will explain the generic.

Anonymous inner classes are also often used for event handler, in response to an event, such as a Button, code that handles click event might look like this:

Copy the code
Button bt = new Button();
bt.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        //处理事件
    }
});
Copy the code

AddActionListener call an event handler registered to the Button object bt, when the event occurs, calls the actionPerformed method, passing the event details ActionEvent as a parameter.

An example of a programming interface for example, in addition, they are also one kind or more callback Button Arrays.sort and are mentioned in the previous section. The so-called callback is positive relative to the general call, the call usually are generally positive, but Comparator object passed Arrays.sort in its compare method is not the time to write the code is called, but Arrays. internal sort of come back to a place called. Button ActionListener object passed in its actionPerformed method, too, is at the time of the incident back to the call.

The program is divided into the main frame remains unchanged, and the logic variable for specific situations, by collaborating callback mode is a common practice in the computer program. Anonymous inner classes is an easy way to implement callback interface.

summary

In this section, we discuss the various internal grammar class, implement the principle, and the use of scenarios, the interior will be converted to a separate class nature of the class, but in general, they can achieve better packaging, the code is also more concise.

We have not discussed an important issue, where classes in? Class files are organized? In this section, the auto-generated methods such as access $ 0 no visibility modifiers, what's that visibility that? These are related with the package, so our next section to explore.

 

Guess you like

Origin www.cnblogs.com/ivy-xu/p/12387537.html