简体   繁体   English

Java中{}和{{}}初始化之间的区别

[英]Difference between {} and {{}} initialization in Java

public class A{
}

A a = new A(){{
    final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
}};

A aa = new A(){
    int x = 1; // THIS NEED NOT BE FINAL. WHY?
    final int y = 1; // STILL FINAL IS ALLOWED HERE. WHY?
    public int getX(){
        return x;
    }
};

Can somebody please answer the questions mentioned inside the snippet? 有人可以回答片段中提到的问题吗?

Thanks 谢谢

The outer set of {} declares an anonymous subclass {}的外部集声明了一个匿名子类

The inner set declares an initialization block within that subclass. 内部集声明了该子类中的初始化块。

With the following example, it becomes easier to understand what's going on: 通过以下示例,可以更轻松地了解正在发生的事情:

List<String> strings = new ArrayList<String>() {{
    add("string");
    add("another string");
}};

You basically say: I want a subclass of List, which calls method add at initialization. 你基本上说:我想要一个List的子类,它在初始化时调用方法add

It's similar to: 它类似于:

List<String> strings = new ArrayList<String>();
strings.add("string");
strings.add("another string");
A a = new A(){{
    final int x = 1; // IT HAS TO BE FINAL HERE. WHY?

It needn't. 它不需要。

The difference between the two is that in the first case, you're writing the code used to initialize each object in the double braces. 两者之间的区别在于,在第一种情况下,您正在编写用于初始化双括号中每个对象的代码。 That x is its local variable (doesn't have anything to do with objects of class A ). x是它的局部变量(与A类对象没有任何关系)。

In the second case, you're defining the classes body. 在第二种情况下,您将定义类主体。 x would be its member variable. x将是其成员变量。 If it were static , its class variable. 如果它是static ,则为其类变量。 If final a (basically) constant. 如果final一个(基本上)不变。

I wonder, why would you want to use the first version of the code (the one with {{}}). 我想知道,为什么要使用代码的第一个版本(带{{}}的代码)。 The x variable declared inside it's not useful at all, it's local only to the block scope in which it was defined, and being inside an anonymous class, you won't be able to reference it anywhere in the code. 在它里面声明的x变量根本没用,它只在本地定义的块作用域本地,并且在匿名类中,你将无法在代码中的任何地方引用它。

And anyway, the first version of x declaration does not need to be final , it compiles just as fine, with or without final . 不管怎样,第一个版本x的声明并不需要是final ,它编译一样细,有或没有final

The first instance A a = new A(){{... has an initialisation block inside the declaration. 第一个实例A a = new A(){{...在声明中有一个初始化块。 Another way of writing it would be like this: 另一种写作方式是这样的:

A a = new A()
{
    {
        final int x = 1; // This is inside an initialisation block
    }        
};

Changing the formatting makes it a bit more obvious. 更改格式使其更加明显。

In your first example the inner braces create something called an instance initializer. 在您的第一个示例中,内部大括号创建一个称为实例初始化程序的东西。 It's an obscure way to initialize variables and call instance methods when an object is constructed. 在构造对象时,这是一种初始化变量和调用实例方法的模糊方法。 So the first example creates an anonymous subclass of A and creates a local variable within the scope of the initializer. 因此,第一个示例创建A的匿名子类,并在初始化程序的范围内创建局部变量。 It doesn't have to be final. 它不一定是最终的。

In the second example you're creating an anonymous subclass of A but not creating an instance initializer, the variables you create are instance variables of the anonymous subclass. 在第二个示例中,您要创建A的匿名子类但不创建实例初始化程序,您创建的变量是匿名子类的实例变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM