【问题标题】:Why would I use static initialization block in java? [duplicate]为什么我要在 java 中使用静态初始化块? [复制]
【发布时间】:2013-02-21 04:25:57
【问题描述】:

当我可以通过构造函数初始化静态成员时,为什么要使用静态初始化块?

【问题讨论】:

  • 如果您从未拥有该类的实例 - 但想使用它的静态函数,它使用由静态初始化块初始化的值,该怎么办?跨度>
  • 并且每次调用 c'tor 时,都会重置静态值。糟糕!

标签: java static


【解决方案1】:

首先,你可能永远不会有你的类的任何实例。或者您可能希望在拥有该类的任何实例之前初始化静态成员。

其次,从构造函数初始化静态成员的工作量更大:

  • 您需要确保每个构造函数都这样做;
  • 您需要维护一个标志来跟踪静态成员是否已初始化;
  • 您必须考虑同步以防止出现竞争条件;
  • 您可能必须考虑同步对性能的影响,尤其是当您有许多线程创建您的类的许多实例时。

最后,在概念上通常是错误的做法(我说“通常”是因为延迟初始化有合法用途)。

【讨论】:

  • +1 - 虽然如果你要实现惰性(或非惰性延迟)初始化,你可能不会在构造函数中“让它发生”。
【解决方案2】:

静态成员不与类的任何实例相关联,而构造函数创建实例。您可以在没有类的单个实例的情况下使用静态成员,它们仍然必须被初始化。在这种情况下,构造函数无法完成这项工作。

【讨论】:

    【解决方案3】:

    那为什么:

    static Set<String> digits = new HashSet<String>();
    static {
        Collections.add(digits, "unu", "du", "tri", "kvar", "kvin");
        digits.add("ses");
        digits.add("sep");
        digits.add("ok");
    }
    

    如果以下可能:

    static Set<String> digits = new HashSet<String>() {{
        Collections.add(this, "unu", "du", "tri", "kvar", "kvin");
        add("ses");
        add("sep");
        add("ok");
    }};
    
    1. 它引入了一个新的匿名类,jar 中的一个文件;不是那么理想。
    2. 第二种形式是极客玩物。

    【讨论】:

    • 为什么引入新的匿名类不是最优的?它会导致类加载错误吗?或者你只是说你不想让你的罐子膨胀。
    • @DavidT。我不喜欢这两种形式,但比较两者:第一种有多余的 digits 出现,第二种创建了一个任意类(很小的开销),并且对非 Java 开发人员有误导性的语法。真正的危险是在 Serializable 类上使用非静态 {{ ... }} 时:然后周围类的 this 也会被序列化。例如,在重新加载对象后,我遇到过这样的 X.this 为空。
    • 实际上,我发现了一个区别 -> 在 Eclipse 上,如果您在 Anonymous 类中发生崩溃,Eclipse 甚至不知道将崩溃线指向哪个项目(比如,说你有一堆线程和可运行作为匿名类)
    猜你喜欢
    • 2012-09-15
    • 2017-08-27
    • 2012-03-11
    • 1970-01-01
    • 2016-05-30
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    相关资源
    最近更新 更多