繁体   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;
    }
};

有人可以回答片段中提到的问题吗?

谢谢

{}的外部集声明了一个匿名子类

内部集声明了该子类中的初始化块。

通过以下示例,可以更轻松地了解正在发生的事情:

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

你基本上说:我想要一个List的子类,它在初始化时调用方法add

它类似于:

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?

它不需要。

两者之间的区别在于,在第一种情况下,您正在编写用于初始化双括号中每个对象的代码。 x是它的局部变量(与A类对象没有任何关系)。

在第二种情况下,您将定义类主体。 x将是其成员变量。 如果它是static ,则为其类变量。 如果final一个(基本上)不变。

我想知道,为什么要使用代码的第一个版本(带{{}}的代码)。 在它里面声明的x变量根本没用,它只在本地定义的块作用域本地,并且在匿名类中,你将无法在代码中的任何地方引用它。

不管怎样,第一个版本x的声明并不需要是final ,它编译一样细,有或没有final

第一个实例A a = new A(){{...在声明中有一个初始化块。 另一种写作方式是这样的:

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

更改格式使其更加明显。

在您的第一个示例中,内部大括号创建一个称为实例初始化程序的东西。 在构造对象时,这是一种初始化变量和调用实例方法的模糊方法。 因此,第一个示例创建A的匿名子类,并在初始化程序的范围内创建局部变量。 它不一定是最终的。

在第二个示例中,您要创建A的匿名子类但不创建实例初始化程序,您创建的变量是匿名子类的实例变量。

暂无
暂无

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

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