ArrayList 初始值设定项上的 {{ 语法的真正作用是什么

发布于 2024-10-06 20:55:15 字数 1149 浏览 1 评论 0原文

我最近发现了一种在我看来是静态初始化 ArrayList 的新语法:

new ArrayList<String>() {{
   add("first");
   add("second");
}};

我的问题是,那里到底发生了什么?这是定义静态块的快捷方式吗(我认为它需要 static 关键字)?或者只是定义默认构造函数的一种方法?还有别的事吗?哪个版本的 Java 变得有效?

如果有解释以及进一步阅读的链接,我们将不胜感激。

编辑: 下面是我的测试类,用于显示初始化程序块是在构造函数之前还是之后执行。结果显示初始化块在其他构造函数代码之前执行:

import org.junit.Test;

public class InitializerBlockTest {
    class InitializerTest {
        {
        System.out.println("Running initalizer block");
        }

        public InitializerTest() {
            System.out.println("Running default constructor");
        }
    }
    
    class SubClass extends InitializerTest {
      {
        System.out.println("Running subclass Initializer block");
      }

      public SubClass()  {
        System.out.println("Running subclass constructor");
      }
    }

    @Test
    public void testIt() {
        new SubClass();
    }
}

输出:

Running initalizer block
Running default constructor
Running subclass Initializer block
Running subclass constructor

I have recently found what appears to me to be a new syntax for statically initializing an ArrayList:

new ArrayList<String>() {{
   add("first");
   add("second");
}};

My question is, what is really happening there? Is that a shortcut for defining a static block (I thought it would need the static keyword)? Or just a way to define a default constructor? Something else? What version of Java did this become valid?

An explanation plus a link to further reading would be greatly appreciated.

edit:
My test class for showing whether initializer block executes before or after the constructor is below. Results show that initializer blocks execute before the other constructor code:

import org.junit.Test;

public class InitializerBlockTest {
    class InitializerTest {
        {
        System.out.println("Running initalizer block");
        }

        public InitializerTest() {
            System.out.println("Running default constructor");
        }
    }
    
    class SubClass extends InitializerTest {
      {
        System.out.println("Running subclass Initializer block");
      }

      public SubClass()  {
        System.out.println("Running subclass constructor");
      }
    }

    @Test
    public void testIt() {
        new SubClass();
    }
}

Output:

Running initalizer block
Running default constructor
Running subclass Initializer block
Running subclass constructor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笨死的猪 2024-10-13 20:55:15

您正在创建 ArrayList 的新匿名子类,其中的实例初始值设定项调用两次 add()。

它与以下内容相同:

class MyList extends ArrayList
{

{ // This is an instance initializer; the code is invoked before the constructor.
add("first"); 
add("second");
}

public MyList() {
    super();
    // I believe initializers run here, but I have never specifically tested this
    }
}

...

List list=new MyList();

请注意,就我个人而言,我不建议将其作为习惯用法,因为它会导致类文件爆炸。

You are creating a new anonymous subclass of ArrayList, with an instance initializer which calls add() twice.

It's the same as:

class MyList extends ArrayList
{

{ // This is an instance initializer; the code is invoked before the constructor.
add("first"); 
add("second");
}

public MyList() {
    super();
    // I believe initializers run here, but I have never specifically tested this
    }
}

...

List list=new MyList();

Note that, personally, I do not advise it as an idiom, since it will lead to class-file explosion.

旧时光的容颜 2024-10-13 20:55:15

它是实例变量的初始化块。

来自 Oracle 的文档:

例如初始化块
变量看起来就像静态的
初始化块,但没有
静态关键字:

{

    // whatever code is needed for initialization goes here
}

Java 编译器复制初始值设定项
阻塞到每个构造函数中。
因此,可以采用这种方法
在之间共享代码块
多个构造函数。

请参阅: http://download.oracle.com/javase/tutorial/java /javaOO/initial.html

It is an initializer block for instance variables.

From Oracle's documentation:

Initializer blocks for instance
variables look just like static
initializer blocks, but without the
static keyword:

{

    // whatever code is needed for initialization goes here
}

The Java compiler copies initializer
blocks into every constructor.
Therefore, this approach can be used
to share a block of code between
multiple constructors.

See: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

﹏半生如梦愿梦如真 2024-10-13 20:55:15

当您编写 new ArrayList() { } 时,您正在创建 ArrayList 的匿名子类。代码中最内括号中的 { } 表示初始化程序块,并且实际上被复制到每个构造函数中。

编辑:你们肯定回答得很快!

When you write new ArrayList() { } you are creating an anonymous subclass of ArrayList. The { } as in the innermost brackets in your code denote an initializer block and is actually copied into every constructor.

EDIT: You guys sure answer fast!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文