班级成员的计算

时间:2013-05-15 15:56:26

标签: java oop

编码时,遇到以下情况:

我有一节课,我们称之为C。它具有任意类型的属性A,必须首先计算:

public class C {
    private int A;

    public C(...) {
        ...
    }

    public void calculateA() {
        A = 42;
    }

    public int getA() {
    }
}

我现在的问题是,如何正确实现getter getA。我应该检查是否定义了A并抛出异常吗?

或者我应该在calculateA中调用getA,如果没有设置?

这类问题的最佳选择是什么?


编辑:好的,我举了一个不好的例子。无法在构造函数中计算A,因为计算方法将返回同一个类的新实例,这将导致无限递归。

4 个答案:

答案 0 :(得分:2)

我认为 -

public class C {
    private int A = Integer.MIN_VALUE;
    ...
    public int getA() {
         if(A==Integer.MIN_VALUE )// Assume Integer.MIN_VALUE when it is not calculated
            throw new RuntimeException();
         return A;
    }
}

它不能100%证明,因为假设Integer.MIN_VALUE无法计算值。

使实例变量A成为整数对象而不是原始int,因此您可以将其设置为null,以便更容易确定状态。

答案 1 :(得分:1)

这是一个不好的例子,因为int是一种原始类型。它永远不会为空。它被初始化为零。

但您的观点对参考类型有效。

我认为允许对私有成员进行空引用是一种糟糕的设计。构造函数应该将对象初始化为100%准备就绪。

答案 2 :(得分:1)

这是一个设计问题,对于这个论坛来说有些不合适。

如果客户有责任在calculateA()之前致电getA(),那么getA()如果尚未计算则会引发异常。 a是原始的这一事实无关紧要,您可以初始化为无效值 - 例如如果它是一个长度类型的实体,那么将其初始化为-1 - 或使用另一个boolean变量或使用一个为空的Integer,无论如何。

了解这会创建时间依赖性 - 客户端需要以固定顺序调用方法。这通常是不受欢迎的,但可能存在合理的情况,您必须在致电Car.start()之前致电Car.stop()

另一方面,如果C“拥有”A,那么它有责任计算它。它可以通过以下几种方式实现:

  • 热切地,在其<init>中,如果所有必要信息都是可用的
  • Lazily / On-demand但缓存,需要第一次calculateA()致电A
  • 每次调用时计算,但在这种情况下getA()可能是误导性名称。

答案 3 :(得分:0)

这取决于。如果计算是静态的,你也可以从构造函数中调用calculateA()函数。

public C(...) {
        ...
        calculateA()
    }

public void calculateA() {
    A = 42;
}

如果getter()的合约规定只返回A的有效值和计算值,请在返回之前计算A

如果由于某种原因无法计算A,并且如果在计算任何进一步使用无效A之前停止执行是有意义的,则抛出异常。