[英]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.