Java 使用初始化块的优点是什么?
我知道初始化块在第一次加载类(静态初始化块)或创建实例(实例初始化块)时运行 但当我们可以这样做时,这有什么特别的好处:Java 使用初始化块的优点是什么?,java,initialization,Java,Initialization,我知道初始化块在第一次加载类(静态初始化块)或创建实例(实例初始化块)时运行 但当我们可以这样做时,这有什么特别的好处: class SmallInit { static int x = 7; int y = 8; } 没有什么特别的好处,它在某些情况下(通常是在声明多个成员时)有助于可读性。对于只包含一行变量声明的静态块,我看不到任何特别的好处。事实上,当您所做的只是为类或实例变量赋值时,(在我看来)更难理解发生了什么 但是,当需要建立更复杂的起始状态时,静态块和实例块确实很方便
class SmallInit {
static int x = 7;
int y = 8;
}
没有什么特别的好处,它在某些情况下(通常是在声明多个成员时)有助于可读性。对于只包含一行变量声明的静态块,我看不到任何特别的好处。事实上,当您所做的只是为类或实例变量赋值时,(在我看来)更难理解发生了什么 但是,当需要建立更复杂的起始状态时,静态块和实例块确实很方便。下面是一个同时使用声明和静态块的示例:
static List<Sprocket> mySprockets = new ArrayList<Sprocket>();
static {
mySprockets.add(new Sprocket("foo", 17));
mySprockets.add(new Sprocket("bar", 8));
}
静态列表mySprockets=newarraylist();
静止的{
添加(新链轮(“foo”,17));
添加(新链轮(“杆”,8));
}
以下可能是实例初始化块的优点: Java编译器将初始值设定项块复制到每个构造函数中。因此,这种方法可以用于在多个构造函数之间共享一块代码
好的概述。我过去使用过初始化块来填充复杂的数据结构。然而,我觉得编写一个填充数据结构的静态函数并调用它是一种更好的方法 e、 g
例如,有些人不熟悉初始化程序块,如果您决定在其他上下文中使用init代码,那么您可以轻松地调用该函数。实例初始化程序块的一个优点是,它们使模式成为可能 与此相反:
Set<String> names = new HashSet<String>();
names.add("Peter");
names.add("Paul");
names.add("Mary");
请参阅和所有答案,但已接受;)@Xaerxess的可能副本:我希望我能接受评论作为答案:)为了我的缘故,下次再问类似的问题:)PS如果你想,你可以发布这个问题的答案,其中包含链接,并解释你在那里找到的最佳答案。注意这一点-它绝对有效,但它会创建一个内部类,其中包含对“this”的隐式引用。如果您没有预料到,这可能会导致一些有趣的GC行为。。。我不是说不要使用它(我当然会),但要注意。@KevinDay你能详细说明一下吗?我对可能出现的潜在问题很感兴趣。当然-如果你像这样初始化一个映射,它会以一个对外部对象的隐式引用结束。如果随后将该映射传递到应用程序的另一个区域,“外部对象”将不会被释放,直到映射本身也被释放。如果映射纯粹是对象的一个实现,那么这很好。但是,如果您在外部接口中公开映射,它会向您打开像这样的意外引用。
private static Map foo = initFoo();
private static Map initFoo() {
Map foo = new Map();
foo.put("x", "y");
foo.put("a", "b");
return foo;
}
Set<String> names = new HashSet<String>();
names.add("Peter");
names.add("Paul");
names.add("Mary");
Set<String> names = new HashSet<String>() {{
add("Peter");
add("Paul");
add("Mary");
}};
doSomethingToSet(new HashSet<String>() {{
add("Peter");
add("Paul");
add("Mary");
}});