Constructor of anonymous inner class

Keywords: Java

Here's an example:

class A{
    public B f() {
        return new B() {
            {
                setName("annoyInner");    //Non static initial block, equivalent to construction method
            }
            //. . . 
            //You can customize member variables and member methods
            //Can override parent methods
        };
    }
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.f().getName());  
    }
}
class B{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public B() {
        System.out.println("B Nonparametric structure of");
    }
}

Print results:

B Nonparametric structure of
annoyInner

In anonymous classes, curly braces can be used to perform some necessary initialization operations, representing non static initialization blocks, which is equivalent to construction methods. Since there is no method name, this constructor does not distinguish whether there are parameters or not. How to use parameters in anonymous constructor?

class A{
    public B f() {
        String name = "annoyInner";
        return new B() {
            {
                setName(name);  //Using local variables directly
            }
            //. . . 
            //You can customize member variables and member methods
            //Can override parent methods
        };
    }
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.f().getName());
    }
}
class B{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public B() {
        System.out.println("B Nonparametric structure of");
    }
}

The printing result is the same as above. In anonymous classes, local variables or member variables can be used directly, which is equivalent to the parametric constructors of anonymous classes (local internal classes and local variables accessed by anonymous internal classes in Java must be modified by final to ensure the data consistency between internal classes and external classes. But starting from Java 8, we have added the effective final function. We can add it by default without the final modifier. Details can be found at< Effective final of new Java 8 features >Learn.)

Then there is another question: can the constructor of anonymous class be overloaded?

The answer is no, or the anonymous class has no name, and there is no place to assign parameters, but you can write as follows:

class A{
    public B f() {
        return new B() {
            {
                setName("annoyInner1");
            }
            {
                setName("annoyInner2");
            }
            {
                setName("annoyInner3");
            }
            //...
        };
    }
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.f().getName());
    }
}

The printing result is annoyInner3, which is equivalent to multiple initialization blocks, which will be executed in turn, not the overload of the constructor, but there is no difference between writing in this way and writing in an initialization block.

We all know that when an anonymous class is instantiated, it will call the nonparametric construction of the parent class by default. How can we call the parametric construction of the parent class? It's not good to add super(name):

class A{
    public B f() {
        return new B("annoyInner") {
            {
                //super(name);  //Compile error
            }
        };
    }
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.f().getName());
    }
}
class B{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public B() {
        System.out.println("B Nonparametric structure of");
    }
    public B(String name) {
        this.name = name;
        System.out.println("B Parametrical structure of");
    }
}

The printing result is as follows: directly use the parameter construction of the parent class in the expression of the anonymous class

B Parametrical structure of
annoyInner

Here is a very common use of anonymous classes. It is often seen that someone wrote this:

             ArrayList<String> list = new ArrayList<String>() {{
                add("A");
                add("B");
                add("C");
            }};

            Map m = new HashMap() {
                {
                    put("name","zhangsan");
                    put("age",18);
                }
            };

Seeing this, I just want to say:

Fancy!!!

Take ArrayList for example. The outer curly bracket creates an anonymous class that inherits from ArrayList. The inner curly bracket indicates that the inherited add method is called in the initialization block of the anonymous class. In fact, the anonymous class is no different from ArrayList. It seems to be simpler to write like this, but the readability is also poor, and it will not bring much performance optimization. At present, I don't know whether it will cause any problems. But it depends on personal preference, and it's OK to use it.

Posted by platnium on Sun, 22 Dec 2019 02:56:06 -0800