【问题标题】:Initializing final properties using helper private methods使用辅助私有方法初始化最终属性
【发布时间】:2011-12-06 12:48:14
【问题描述】:

我在带有构造函数的 Java 类中定义了几个最终属性,该构造函数具有初始化属性的所有信息。

public final class A {
   private final Object prop1;
   private final Object prop2;

   public A(Object someObj, String prop1Str, String prop2Str) {
       //initialize prop1 and prop2 based on information provided from someObj, prop1Str and prop2Str parameter (1)
   }
}

我想在 A 类中引入一个具有以下签名和语义的新构造函数

   public A(Object obj1, Object obj2, String prop1Str, String prop2Str) {
       //use obj1 and obj2 to initialize the someObj
       //initialize prop1 and prop2 based on information provided from someObj, prop1Str and prop2Str parameter (1)
   }

如何重用 (1) 中的代码?我尝试使用辅助私有方法,但 Java6 给了我一个编译错误,因为该类的属性是最终的并且它们可能尚未初始化。

编辑: 请注意,我不能从第一行的第二个构造函数调用第一个构造函数,因为首先我需要进行一些计算,然后重用相关代码。

【问题讨论】:

    标签: java properties final code-reuse


    【解决方案1】:

    你发现final的一个缺点:-)

    Java 必须确保在构造函数完成时初始化所有final 字段。由于其他各种限制,这意味着必须在构造函数的代码块内分配字段。

    解决方法:

    1. 使用static 辅助方法(根据设计,这些方法不依赖于类的状态,因此不依赖于任何final 字段)。

    2. 使用构建器模式(将所有参数放在一个辅助类中,该类具有返回所需结果的build() 方法)。

    3. 不要使用final。您可以通过省略 setter 来获得相同的事件。如果您担心类中的代码可能会更改字段,请将它们移至新的基类。

    【讨论】:

    • 就我而言,选项 3 可能是最合适的选择。但我想知道这是为什么?编译器真的无法检测到我从构造函数的主体中调用了辅助私有方法并且我只从那里调用它吗?有什么我想念的特殊情况吗?
    • Java 编译器从不试图变得聪明。它仅涵盖最明显的情况。这是设计使然。
    【解决方案2】:

    您应该致电this(obj1, prop1Str, prop2Str)。这必须是第二个构造函数中的第一个可执行行。

    【讨论】:

      【解决方案3】:

      首先,你确定你的构造函数没有失控吗?

      如果您确定(目前)使用多个构造函数根,那么您可以从另一个构造函数调用一个构造函数。需要在构造函数的第一行使用this();语法,替换隐式或显式super();。

      public A(Object obj, String prop1Str, String prop2Str) {
          this(obj, obj, prop1Str, prop2Str);
      }
      public A(Object obj1, Object obj2, String prop1Str, String prop2Str) {
          // ...
      }
      

      当然,您可以使用更复杂的表达式来转换参数,而不仅仅是简单的传入参数。例如:

      public A(Object obj, Object prop1Obj, String prop2Str) {
          this(obj, maskNull(obj), String.valueOf(prop1Str), prop2Str);
      }
      

      构造函数用于将对象初始化为有效状态。对于更复杂的处理,您可能需要添加静态创建方法。该方法甚至可能有一个有意义的名称来表明它正在做什么。

      【讨论】:

        猜你喜欢
        • 2010-11-27
        • 2011-02-16
        • 2020-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-12
        • 1970-01-01
        • 2015-12-20
        相关资源
        最近更新 更多