我知道实例初始化器将在构造函数之前调用,它们就像静态构造函数,只是每次创建类的实例时都会调用它们。 E.g。
public class App {
public static void main( String[] args ){
new App();
new App();
}
static{
System.out.println( "static initializer" );
}
public App(){
System.out.println( "constructor" );
}
{
System.out.println( "instance initializer" );
}
}
输出:
static initializer
instance initializer
constructor
instance initializer
constructor
但我为什么要用它们呢?我只能在构造函数中编写逻辑,如果我想在一些已经存在的构造函数之前执行逻辑,我可以将它添加到构造函数的开头。
我也发现继承类没有优势,因为即使我覆盖了构造函数,我仍然可以实现自己的逻辑并在之后调用父构造函数。
Java中的初始化程序或任何语言的适当用例是什么?或者总是可以与构造函数获得相同的函数?
答案 0 :(得分:4)
来自JLS 8.6 - Instance Initializers:
在创建类的实例时,将执行类中声明的实例初始值设定项。
来自JLS 8.8 - Constructor Declarations:
构造函数用于创建作为类实例的对象。
从而确认您的观点,即在实例初始化器中完成的所有操作也可以在构造函数中完成。
这离开了。比较:
Map<String, String> lookup = new HashMap<>();
{
lookup.put("Hello", "Hello");
}
使用:
Map<String, String> lookup = new HashMap<>();
// Maybe some considerable number of lines of code.
public Test() {
lookup.put("Hello", "Hello");
}
这两者之间显然没有功能差异,但将两者放在一起更有意义。
当然有以下情况:
public Test() throws Exception {
// ...
}
您无法在实例初始化程序中执行此操作。
答案 1 :(得分:0)
如果您有多个构造函数,则还将执行实例初始值设定项。 这样你就不必复制粘贴代码了。
答案 2 :(得分:0)
当我创建一个自定义的匿名类实例时,我几次使用它,你无法显式声明构造函数。 see here
例如,
public static final Set<String> someStringSet = new HashSet<String>(){
{
add("string1");
add("string2");
add("string3");
}
};
它可以是匿名的hashmap,也可以是你能想到的任何需要修改的地图 在开始。