【问题标题】:Is Static Initialization Good Programming Practice?静态初始化是好的编程习惯吗?
【发布时间】:2012-03-10 00:37:30
【问题描述】:

在Java中,我们使用静态初始化块:

private static final ApiKey API_KEY;

static {
    API_KEY = new ApiKey();
}

我想知道

  • 这是一种好的编程习惯吗?
  • 我们应该在哪里使用这种模式?

提前致谢。

【问题讨论】:

  • 我会发表评论,因为您的问题没有“非黑即白”的答案。就个人而言,我不认为静态访问器是程序员的好朋友。依赖注入是一个非常好的替代方案,在测试方面也有很大帮助。
  • 我看到了一段代码,其中在静态块中启动了新线程。 :) 非常糟糕。

标签: java static initialization


【解决方案1】:

在某种程度上,这是一个品味问题。对我来说,只要:

  • 你一直保持最终状态,就像你所做的那样
  • 确保引用的对象是不可变的且线程安全的

静态往往会使编写好的测试变得更加困难。如果您发现要开始修改静态状态,那么您可能需要再次查看设计。

考虑看看Google Guice 和它非常好的Singleton implementation

当然,如果您的应用程序是一个 10 行的单类实验,那么这就不那么重要了。

请注意,在您的示例中,您可以简化为:

private static final ApiKey API_KEY = new ApiKey();

但这并不总是可能的。也许您省略了一些更复杂的初始化代码?在这种情况下,Guice 将再次值得一看。

【讨论】:

    【解决方案2】:

    我喜欢尽可能使用枚举。

    代替

    class ApiKey {        
        private static final ApiKey API_KEY;
    
        static {
            API_KEY = new ApiKey();
        }
    

    我会写

    enum ApiKey {
        INSTANCE;
    

    【讨论】:

      【解决方案3】:

      您可以使用以下代码完全避免使用静态初始化程序块:

      private static final ApiKey API_KEY = new ApiKey();
      

      private static final ApiKey API_KEY = createNewApiKey();
      

      如果 API 密钥创建需要的不仅仅是构造函数调用。恕我直言,这使代码更具可读性。不过没关系。

      当两个静态字段依赖于相同的初始化代码时,静态初始化器很有用:

      static {
          // compute some values
          A = somePartOfTheComputedValues();
          B = someOtherPartOfTheComputedValues();
      }
      

      但即便如此,A 和 B 也可能被重构为一个对象,该对象将在一个方法中创建。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多