在我使用IntelliJ检查我的代码后,会发出数百个“声明可以有最终修饰符”的警告。要解决这些警告,我基本上需要将大部分变量转换为final,以下是一个典型示例。这让我觉得我应该默认将成员变量设为'final'。在大多数情况下,成员,尤其是容器类(即List或Set),一旦被分配,就不会被更改。它们通过插入或删除元素来进行内部更改,但对它们的引用不会更改。
public class Attribute {
private final Insight insight;
private final Attribute attribute;
private final List<String> names;
public Attribute(Insight insight, Attribute attribute) {
attribute = attribute;
insight = insight;
names = new ArrayList<>();
}
}
在设计类中默认将大多数变量设为final是否有意义?是否可以在Java中将大多数成员变量定义为“final”?
答案 0 :(得分:3)
如果要重新设计Java,今天变量应该默认为private和final而不是package和mutable。
可变变量有时是必要的,但是只要有可能你应该更喜欢final,我真的不能想到许多合理的理由让变量变成私有变量。
对于不同的目标环境,情况可能会有所不同,但Java旨在提供良好的可读/可维护的长期代码,考虑到这一点,他们只是在默认情况下做出了一些不好的决定。
但这是一种古老的语言,我们现在所知道的并不多。生活和学习。
ps:如果我负责的话,我也会抛弃检查过的例外......我可能不是一件好事。
答案 1 :(得分:1)
如果您考虑在现实环境中的大多数应用程序,大多数变量都可以是最终的。宣布最终结果有很多好处。 但我建议你这样做,而不是使用IDE的建议和功能。 习惯总是想到变量是否需要变异,如果不是定义变量的一部分,只需添加final。 这种习惯使你可以独立于IDE建议编写决赛。大多数IDE都非常擅长代码完成,但你永远不会知道。 PS:当你养成这个习惯时,请记住你的物品的继承。
我偶然宣布一个习惯性的最终方法,并为此付出代价: - )。
答案 2 :(得分:1)
我必须让我的大多数变量最终成功吗?
是。但其原因可能与20世纪90年代语言出现时所想象的原因不同。
在90年代,桌面计算中的CPU是单核,单线程。当时主要使用final
修饰符作为实现与C的const
类似语义的方法。
但是final
现在更重要的是程序运行在多线程,多核CPU上。通常,在可能的情况下限制和/或简化可以在并发环境中共享的对象的状态空间是有利的。当语言处于早期阶段时,这并不总是很好理解。早期Java中的Calendar
类(持续到Java 8)具有非常复杂的状态空间,具有同样复杂的状态转换,这使得在并发环境中使用Calendar
对象比以前更困难。 Joshua Bloch在他的书“ Effective Java ”(第二版)中甚至说很少有人真正理解Calendar
类的状态空间。
当实例字段为final时,它们可以经历的状态转换次数必然受到限制。这是一件好事,因为这使得并发环境中的对象更容易推理。最终简单的对象是一个不可变对象,其中所有实例字段都以其最终形式初始化,并且无法更改。这些对象在并发环境中使用非常简单,因为......
因此,可以在任意大量的线程之间自由共享不可变对象。
TL; DR:最终实例字段使您的对象更简单,更容易推理。预期的影响是代码更容易理解,维护成本更低。布洛赫建议您尽可能使用任何实例字段final
。
答案 3 :(得分:0)
虽然有意义的是,每个成员字段都不会更改它所初始化的引用,但是应该声明为final,但在你的情况下,你可以使用其他一些最佳实践。您可能希望为您的成员属性提供setters
(和getters
),除非它们在初始化后不可修改。如果您提供setters
,IntelliJ不会抱怨。此外,您可以按照here列出的说明禁止这些警告。
简短的回答是
final
。