0

While coding, I encountered following situation:

I have a class, let's call it C. It has an attribute A of arbitrary type which must be calculated first:

public class C {
    private int A;

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

    public void calculateA() {
        A = 42;
    }

    public int getA() {
    }
}

My question now is, how to implement the getter getA properly. Should I check whether A is defined and throw an exception otherwise?

Or should I just call calculateA in getA if it is not set?

What is the best choice for that kind of problem?


Edit: OK, I gave a bad Example. A cannot be calculated in the constructor, because the calculation method will return a new instance of the same class, which will lead to an infinite recursion.

4

4 回答 4

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为 Integer Object 而不是 original int,因此您可以设置为 null ,这样可以更容易地确定状态。

于 2013-05-15T15:59:47.603 回答
1

这是一个设计问题,有点不适合这个论坛。

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

了解这会产生时间依赖性——客户端需要以固定的顺序调用方法。这通常是不受欢迎的,但可能有一些情况可以证明它是合理的,你必须在调用Car.start()之前先调用Car.stop()

另一方面,如果C“拥有” A,那么计算它是它的责任。它可以通过多种方式做到这一点:

  • 急切地<init>,如果所有必要的信息都可用
  • 懒惰/按需但缓存,需要calculateA()第一次调用A
  • 每次调用时都要计算,但getA()在这种情况下可能是一个误导性的名称。
于 2013-05-15T16:12:30.687 回答
1

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

但是您的观点对引用类型有效。

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

于 2013-05-15T16:00:00.600 回答
0

这取决于。如果计算是静态的,您不妨从构造函数中调用 calculateA() 函数。

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

public void calculateA() {
    A = 42;
}

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

如果A由于某种原因无法计算,并且如果在您的程序中停止执行是有意义的,然后再使用 invalid 进一步计算任何内容A,则抛出异常。

于 2013-05-15T15:59:12.370 回答