为什么不是实例变量?

时间:2016-09-13 16:15:12

标签: java instance-variables variable-declaration

我对Java相对较新(我接受过AP计算机科学),而我的书Big Big提出了这个问题:

  

考虑以下类Square的实现:

--master
     

为什么引入一个实例变量不是一个好主意   区域?重写该类,以便该区域是局部变量。

我确信答案对于经验丰富的编码人员来说是显而易见的,但我真的不确定为什么将区域变为实例变量是一种糟糕的方法。任何指导都将非常感谢!

4 个答案:

答案 0 :(得分:3)

面积是根据边长计算的值。实例变量保存对象的状态,如果将其包含在那里,则必须维护两个冗余的状态。

将区域作为实例变量包含将计为缓存,因为您保存结果而不是重新计算。这有时是需要的,但不是这里因为计算足够便宜。

答案 1 :(得分:2)

最小化变量范围被视为良好做法。

这是因为变量应仅在您知道变量适用且具有有用值的上下文中可用。

以下是可以引入的两个错误,因为范围比它应该更宽:

// This function compiles and looks correct, but only works if `getArea()`
// just happened to be called first. Otherwise, it returns 0.
int getVolume(int height) {
  return area * height;
}

如果最小化area的范围(通过使其成为局部变量),则此代码将无法编译,并且您不会遇到此错误。

// This functions compiles and looks correct, but will sometimes return
// the area of a single side if another thread is trying to call getArea()
// at the same time, because both will overwrite the same variable.
int getCubeArea() {
  area = 6 * sideLength * sideLength;
  return area;
}

同样,如果area是一个局部变量,那么你就不会遇到这个问题。

答案 2 :(得分:1)

我不确定作者想要说的是什么(其他),我提出的一件事是,每次实例化对象时,它只占用内存中的额外和冗余空间。而您可以将简单方法体编写为,

public int getArea() {
    return sideLength * sideLength;
}

这样,您不会占用内存中的任何额外空间,将计算结果发送到CPU并获取结果。这是实际应用中的一种好方法。对于初学者来说,理解变量的创建,类型匹配等会更容易理解。没有其他的。

答案 3 :(得分:0)

所述的其他答案实际上是正确的,因为通过知道边长可以(轻松)计算面积,在单独的变量中跟踪它是没有意义的。这就是作者的意思 - 将区域变量设为其getter方法的本地变量。您可以通过删除字段声明

来实现

private int area;

并在您的方法中声明您在本地变量,因此在您的getter中:

int area = sideLength * sideLength; return area;

然而,如果你不想每次重复计算,那么保持那个字段是有意义的 调用getArea()。为了做到这一点,你需要从getter中取出计算并放入构造函数中。

更新

跟进" that_other_guy"正确的答案,如果该区域在构造函数中获取其值,那么这些错误都不会发生,一切都会返回正确的结果