BlackChen'site

java 匿名内部类

背景

最近在使用HashSet的时候, 为了方便初始化操作,看到了网上一些文章,使用java匿名内部类的方式进行初始化.

HashSet<String> hashSet = new HashSet<String>(){{
    add("xxx1");
    add("xxx2");
    add("xxx3");
}};

上面这段代码, 是使用匿名内部类 + 构造代码块 的方式进行初始化. 改写一下:

HashSet<String> hashSet = new HashSet<String>(){
    {
    add("xxx1");
    add("xxx2");
    add("xxx3");
    }
};

构造代码块的作用

  1. 构造代码块的作用是给对象进行初始化。
  2. 对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
  3. 构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

Class

使用匿名内部类初始化HashSet后, 编译java文件, 发现新增了一个class文件

package com.example.demo.innerclass;


import java.util.HashSet;

public class Test {
    public static void main(String[] args) throws Exception {

        HashSet<String> hashSet = new HashSet<String>() {{
            add("xxx1");
            add("xxx2");
        }};

    }
}

在目录下执行命令: javac Test.java

发现目录下多了一个文件: Test$1.class

使用IDEA打开:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.example.demo.innerclass;

import java.util.HashSet;

final class Test$1 extends HashSet<String> {
    Test$1() {
        this.add("xxx1");
        this.add("xxx2");
    }
}

匿名内部类是继承了一个类后,生成的子类.

评论