Java 为什么不使用实例变量?

Java 为什么不使用实例变量?,java,instance-variables,variable-declaration,Java,Instance Variables,Variable Declaration,我对Java比较陌生(我正在学习AP计算机科学),我的书《大Java》提出了这个问题: 考虑类Square的以下实现: public class Square { private int sideLength; private int area; // Not a good idea public Square(int length) { sideLength = length; } public int getArea() {

我对Java比较陌生(我正在学习AP计算机科学),我的书《大Java》提出了这个问题:

考虑类Square的以下实现:

public class Square {

    private int sideLength;

    private int area; // Not a good idea

    public Square(int length) {

        sideLength = length; }

    public int getArea() {

        area = sideLength * sideLength;

        return area; }
}
为什么为应用程序引入实例变量不是一个好主意 地区重写类,使area成为局部变量

我相信答案对一个更有经验的程序员来说是显而易见的,但我真的不确定为什么将area作为实例变量是一个糟糕的方法。任何指导都将不胜感激

我不确定作者的意思是什么,我想到的一件事是,每次实例化对象时,它都会占用内存中额外的冗余空间。而您可以将简单方法体编写为

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

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

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


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

将变量的范围最小化被认为是良好的做法

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

这里有两个可能引入的bug,因为范围比应该的更广:

// 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;
}
如果将
区域的作用域最小化(通过将其设置为局部变量),则此代码不会编译,也不会出现此错误

// 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;
}

同样,如果面积是一个局部变量,你就不会有这个问题。

其他答案实际上是正确的,因为面积可以(很容易)通过知道边长来计算,所以在单独的变量中跟踪它是没有意义的。这就是作者的意思——使区域变量成为getter方法的局部变量。您可以通过删除字段声明来实现这一点

私人内部区域

并在方法中局部声明变量,因此在getter中:

int区域=边长*边长;
返回区

但是,如果您不想每次重复该计算,则保留该字段是有意义的
调用getArea()。但是,为了做到这一点,您需要将计算从getter中取出并放入构造函数

更新:


根据“They_other_guy”的正确答案,如果面积在构造函数中取其值,这些错误都不会发生,一切都将返回正确的结果

,因为面积不能独立于长度而变化。。。为什么要将它作为一个单独的状态?正如前面所说的,因为它是冗余的。即使是局部变量也是冗余的。一般来说,getter不应该有任何副作用。getter应该返回一个值、句点,而不是改变对象的状态;我想我现在完全明白了。谢谢