为什么在Java类中存储计算值是一种不好的做法,如何避免这种情况?

为什么在Java类中存储计算值是一种不好的做法,如何避免这种情况?,java,Java,我是Java新手,正在攻读研究生课程,学习Java语言。才几个星期。我得到了一个我刚刚工作过的实验室,教授告诉我我们不会在课堂上存储计算值,并让我参考一份最佳实践文档。我查看了文档,但没有看到对计算值的引用 我想他指的是这段代码: public double getCalories() { this.calories = (((this.weight * 0.12) * 9) + ((this.weight * 0.09) * 4) + ((this.weight

我是Java新手,正在攻读研究生课程,学习Java语言。才几个星期。我得到了一个我刚刚工作过的实验室,教授告诉我我们不会在课堂上存储计算值,并让我参考一份最佳实践文档。我查看了文档,但没有看到对计算值的引用

我想他指的是这段代码:

public double getCalories() {
    this.calories = (((this.weight * 0.12) * 9) + ((this.weight * 0.09) * 4)
            + ((this.weight * 0.02) * 4));
    return this.calories;
}

我不得不用体重来计算卡路里的量。这是我在这门课上做的唯一真正的计算,所以我假设这就是问题所在。有没有更好的方法写这个?那么你如何进行计算呢?

你得问问你的教授,这在“java的应做和不应做的事”列表中并不是最重要的。然而,对于您的特定代码片段,您的教授可能有一个稍微不同的观点:

你在这里做的事情完全没有任何目的,或者,如果有,你的代码被破坏了

只有两种选择:

这是整个代码库中唯一引用卡路里字段的地方,或者

您还可以在其他地方使用该字段

选项1-这是您唯一使用它的地方。 那就没用了。你计算卡路里,每次有人打电话给GetCarries。爪哇不是巫术;如果调用一个方法,则按顺序执行其中的每一行。添加这样的字段只是。。也意味着java将在该字段中存储该结果。这并不意味着java下次将跳过计算

因此,您的getCarries调用将进行计算、存储结果并返回结果。存储的结果不会在任何地方使用,这完全是对空间的浪费。菲克斯:只是。。不要储存它。删除该字段。将该方法设置为一行,并用return替换this.carries=

选项2-您可以在其他地方使用它 假设在这个类中有另一个方法:

public boolean exceedsRecommendedDaily() {
    return this.calories > 2000;
}
然后这个代码就被破坏了——如果我调用这个方法,那么卡路里字段仍然是0,并且在有人调用getCarries之前将保持为0。我想我们可以通过记录这样的行为来修复它:

/**
 * Calculates if this food item on its own exceeds recommended daily intake.
 * NB: If you haven't called `getCalories()` earlier on this object,
 * this method will straight up lie to you!
 */
但我想我们都同意这意味着这种方法是愚蠢的

不,为什么不这样做呢:

public boolean exceedsRecommendedDaily() {
    return getCalories() > 2000;
}
塔达。不再需要愚蠢的警告了

所以这是最佳实践吗? 不,不是。如果计算需要足够长的时间,并且经常需要计算的结果,并且对象是不可变的,没有设置的方法/在构造后没有任何字段可以更改,或者每次字段更新都不值得清除缓存的值,那么缓存该值是一个好主意


例如,java自己的java.lang.String缓存哈希代码,因为计算这是一个非常昂贵的操作,至少需要检查每个字符。所以在一个100万字符的字符串中,这需要一段时间!,它可以称为一吨,字符串是不可变的。

您的函数计算卡路里并返回计算值。您发布的代码中没有理由存储返回值的副本;它不在任何地方使用

public double getCalories() {
    return (((this.weight * 0.12) * 9) + ((this.weight * 0.09) * 4)
            + ((this.weight * 0.02) * 4));
}

如果碰巧有其他代码(未显示)使用this.carries的值,那么getcarries方法还有另一个缺陷。它被称为“获取卡路里”,如果它能为其他方法节省热量,这是令人惊讶的;如果不首先调用GetCarries,那么另一个方法可能会出现故障。

我们不打算在类中存储计算值, 我个人认为这一说法并不清楚,因为它背后没有背景。我想你们的意思是不要把多余的信息存储到全局字段中

当创建一个类时,由于不同的原因,您将封装其中的数据,您可以详细了解OOP语言的概念。在您的情况下,您的类保存实体的信息

例如:

class car {
  int engineVersion
  String modelName
}

您可以看到,engineVersion和modelName是初始化对象car时的重要信息,因此您可以稍后访问它。当您存储信息时,肯定会占用空间。然而,对于你的方法GetCarries,假设你自己的班级不需要它,也就是说:不在其他地方使用它,你可以直接返回一个结果,然后你就可以节省资源。

你的教授错了:没有最佳实践来管理这一点

答案是视情况而定

如果计算昂贵,考虑存储它,但如果状态改变,则需要设置程序中的钩子以使计算无效。这是一种形式。它在某种程度上使类复杂化,但是如果为了性能而牺牲简单性是可以接受的,那么它可以安全地完成,并且是合理的

如果类是,您不需要担心状态的变化,因此您可以计算它,理想情况下,即按需计算一次并存储值,而无需任何此类挂钩

如果计算成本低,那么每次计算都会更干净。

我建议
请你的教授澄清,因为他们会确切地知道他们的意思以及他们对你的期望。我建议你问问自己,为什么我要存储这个值?。知道这一点是真正评估是否应该这样做的唯一方法。这个问题在某种程度上是基于堆栈溢出的观点。不过还是有一些好的答案,所以我想没关系。无论如何,这是一个有趣的问题。谢谢!我认为你的选择1正是他的意思。我明白你的意思。我甚至不需要使用任何名为carries的变量,因为我只需要返回通过getcarries调用的值。我现在明白了,为什么我不需要这么做。这是有道理的。我正在远程执行这个程序,来回的工作一直很有挑战性。谢谢。我可以理解为什么我现在只需要这样做,而不需要存储计算。很有帮助