使用初始化块有什么好处?

时间:2011-12-12 00:37:38

标签: java initialization

我知道初始化块在首次加载类(静态初始化块)或创建实例(实例初始化块)时运行。

class SmallInit {
   static int x;
   int y;
   static { x = 7 ; } // static init block
   { y = 8; } // instance init block
}

但是,当我们这样做的时候,这有什么特别的好处:

class SmallInit {
   static int x = 7;
   int y = 8;
}

7 个答案:

答案 0 :(得分:7)

实例初始化块的一个好处是它们使Double Brace Initialization模式成为可能。

而不是:

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");
}};

第一个大括号创建一个匿名内部类;第二个启动实例初始化程序块。 (请注意,这意味着namesHashSet的匿名子类的实例,但这通常不是问题。这也意味着此模式仅适用于非最终版本类。)

这在一次性情况下特别有用,在这种情况下,将对象初始化为表达式会很方便。例如:

doSomethingToSet(new HashSet<String>() {{
    add("Peter");
    add("Paul");
    add("Mary");
}});

答案 1 :(得分:3)

对于仅包含单行变量声明的静态块,我没有看到任何特殊好处。事实上,当你所做的只是为你的类或实例变量赋值时,(在我看来)更难来理解正在发生的事情。

当您需要构建更复杂的起始状态时,静态和实例块确实派上用场。这是一个使用声明和静态块的示例:

static List<Sprocket> mySprockets = new ArrayList<Sprocket>();

static {
    mySprockets.add(new Sprocket("foo", 17));
    mySprockets.add(new Sprocket("bar", 8));
}

答案 2 :(得分:2)

我过去曾使用初始化块来填充复杂的数据结构。但是,我开始觉得编写一个填充数据结构并调用它的静态函数是一种更好的方法。

e.g。

private static Map foo = initFoo();

private static Map initFoo() {
  Map foo = new Map();
  foo.put("x", "y");
  foo.put("a", "b");
  return foo;
}

例如,有些人不熟悉初始化程序块,如果您决定在其他某些环境中使用初始化代码,那么您可以轻松地调用该函数。

答案 3 :(得分:0)

没有特别的好处,它可以帮助在某些情况下的可读性(通常当你宣布多个成员时)。

答案 4 :(得分:0)

以下可能是实例初始化块的一个优点:

  

Java编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。

转到here了解详情。

答案 5 :(得分:0)

  1. 如果没有初始化程序,变量将被初始化 为0或null。因此,如果你打算在中设置一些东西 构造函数到其他值,你实际上设置它两次(一次 到0或null,然后在构造函数中再次到你想要的)。该 在绝大多数情况下,性能损失可以忽略不计(a 异常可能是您在紧密循环中使用的数学类,但是 即使这将非常依赖于该循环中发生的其他事情。)
  2. 它有助于提高可读性。
  3. 如果从构造函数调用虚方法,则派生的数据成员 重写的虚方法中使用的类将具有0或null作为值 除非它有初始化程序。我不是100%这是Java的情况 已经有一段时间了;我知道它在C#中。

答案 6 :(得分:0)

我找到了最好的答案here,而不是接受的答案,而是Jon Skeet的答案。

感谢Xaerxess发布了这个答案的链接。