在查看一些遗留代码时,我遇到了一些令人困惑的事情:
public class A{
public A(){
//constructor
}
public void foo(){
//implementation ommitted
}
}
public class B{
public void bar(){
A a = new A(){
{ foo(); }
}
}
}
在调试模式下运行代码后,我发现在调用构造函数{ foo() }
之后调用了匿名块A()
。以上功能与以下功能有何不同:
public void bar(){
A a = new A();
a.foo();
}
?我认为它们在功能上是等价的,并且认为后一种方式是更好/更清晰的编写代码的方式。
答案 0 :(得分:7)
{ foo(); }
为什么?
Java编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。
答案 1 :(得分:4)
“只要以下情况,实例初始值设定项就是实例变量初始值设定项的有用替代方法:(1)初始化程序代码必须捕获异常,或者(2)执行无法用实例变量初始化程序表示的奇特计算。当然,您可以总是在构造函数中编写这样的代码。但是在具有多个构造函数的类中,你必须在每个构造函数中重复代码。使用实例初始化程序,你只需编写一次代码,它就会被执行,无论如何什么构造函数用于创建对象。实例初始值设定项在匿名内部类中也很有用,它们根本不能声明任何构造函数。“ Source
this answer也引用了这一点。
答案 2 :(得分:2)
除非访问对象的运行时类(通过调用getClass()
)并且由于某种原因需要与A
不同(例如因为它充当超类型令牌),确实没有区别,只是在施工后调用foo()
确实是更常见的习语。