【问题标题】:Examples of why we need initialization blocks为什么我们需要初始化块的例子
【发布时间】:2014-05-27 21:08:25
【问题描述】:

我正在研究这些主题:

  1. In what order do static initializer blocks in Java run?
  2. Java Static Initialization Order

我不明白我们是否有构造函数,我们可以在其中放置一些逻辑,例如处理异常情况,为什么我们需要初始化块,我们还可以将哪些代码移至构造函数?

如果答案是在某些情况下我们需要在构造函数运行之前初始化一些资源,你能帮我举一些例子,这样我就可以完全看到图片了。

【问题讨论】:

  • 我没有想到的例子,所以这是一个评论。如果您不想跨构造函数重复工作,则初始化块很好。如果你想在初始化静态变量时做更复杂的工作,静态初始化块是很好的。
  • @user3580294 你可以调用另一个构造函数来避免将逻辑放入初始化块中。
  • @LuiggiMendoza 但是在某些情况下,我们有constructor(String) constructor(int) 并且这个构造函数可能以不同的方式设置实例,所以它们不应该混合使用。
  • @Pshemo 在这种情况下使用构建器模式。
  • @LuiggiMendoza 我开始徘徊为什么我们实际上需要初始化块(不是静态的,它们在 enums 中很有用)

标签: java initialization block


【解决方案1】:

您使用(并且我已经使用过)静态初始化块的一个示例是初始化元素集合。例如,如果我有一组存储在静态地图中的解析器:

 private static Map<String, Parser> parsers = new HashMap<String, Parser>();

我可以使用静态初始化块来填充此地图的成员:

static {
  parsers.put("node", new NodeParser());
  parsers.put("tree", new TreeParser());
  parsers.put("leaf", new LeafParser());
  //etc.
}

我会这样做是因为我希望地图是静态的,而不是特定对象的一部分,或者如果我只想有这些地图之一(也许我只需要一个)。

this和构造函数的区别在于构造函数是在对象实例化时调用的,而静态初始化块是在类加载时调用的。

也就是说,如果你调用

MyClass.parsers.get("node");

MyClass 构造函数永远不会被调用,因此如果您等到构造函数初始化 parsers 映射,上述调用将返回 null。

【讨论】:

  • 我能找到的关于static 初始化器的最佳示例是必须从配置文件中检索常量变量并且必须保持为常量。
  • @LuiggiMendoza 是的,这是静态初始化器的绝佳使用
【解决方案2】:

为什么我们需要初始化块

例如初始化块,我只能考虑两种情况:

  1. 创建匿名类时:

    Runnable runnable = new Runnable() {
        int x;
        //initialization block here
        {
            //IMO this is such odd design, it would be better to not
            //create this as an anonymous class
            x = outerClassInstance.someMethod();
        }
        @Override
        public void run() {
            //write the logic here...
        }
    };
    
  2. 使用双括号初始化时(如果类没有标记final):

    List<String> stringList = new ArrayList<>() {
        {
            add("Hello");
            add("world");
        }
    };
    System.out.println(stringlist);
    //prints [Hello, world]
    

对于静态初始化块,有两种情况:

  1. static 字段定义数据时。这在@ChrisThompson's answer 中有介绍。

  2. 从外部源初始化常量 (static final) 字段时,例如某些计算的结果。

    class Foo {
        public static final boolean DEBUG;
        static {
            DEBUG = getDebugMode();
        }
        private static boolean getDebugMode() {
            //code to open a properties file, read the DEBUG property
            //and return the value
        }
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2011-06-08
    相关资源
    最近更新 更多