最佳实践:Java静态非final变量

24

在Java中,何时应该使用静态的非final变量?

例如:

private static int MY_VAR = 0;

显然,我们这里不是在谈论常量。

public static final int MY_CONSTANT = 1;

根据我的经验,在使用单例模式时,我经常会为它们辩护,但最终我需要拥有多个实例,这会给我带来很大的麻烦和重构。

似乎在实际应用中很少需要使用单例模式。你怎么看?

7个回答

23

统计信息可能使用非最终变量,例如计算创建的实例数量。另一方面,在这种情况下,您可能希望使用AtomicLong等,此时可以是最终的。或者,如果您正在收集多个统计信息,则可能会出现一个Statistics类和对其实例的最终引用。

拥有(合理的)非最终静态变量确实相当罕见。


+1,但请使用原子操作。考虑到它是“静态”的,假设多个线程将访问它。 - Jason Cohen

6
当用作缓存、日志记录、统计或调试开关时,这些是显而易见的合理用途。当然,所有私有。
如果您将可变对象分配给最终字段,那么道义上与具有可变字段相同。
一些语言,如Fan,完全禁止可变静态(或等效)内容。

2

根据我的经验,静态非最终变量只应用于单例实例。其他所有内容都可以更清晰地通过单例(例如缓存)进行封装或使其成为最终(例如记录器引用)。但是我不信奉硬性规定,因此建议您对我提出的建议持保留态度。话虽如此,我建议仔细检查任何情况,在这种情况下,您考虑声明静态非最终变量,并查看是否可以进行重构或以不同方式实现-即将其移动到单例容器中或使用对可变对象的最终引用。


1
静态变量可用于控制应用程序级别行为,例如指定全局日志记录级别、连接服务器等。
我曾在旧应用程序中遇到这样的用例,通常来自其他公司。
现在,使用静态变量进行此类目的显然是不好的做法,但在1999年之前并不那么明显。没有Spring、log4j、R.C.Martin的Clean code等。
Java语言现在相当古老了,即使某些功能现在被强烈反对,它们经常在开端使用。由于向后兼容性,这种情况不太可能改变。

0

我认为封装静态变量并通过单例(或至少是通过静态方法)提供访问通常是一个好主意,因为这样可以更好地控制访问并避免一些竞争条件和同步问题。


0
一个静态变量意味着它对整个类都是可用的,所以两个例子都对整个类都是可用的。Final 意味着该值不能被更改。所以我想问题是,当你想让一个值在整个类中可用,并且在实例化后不能被更改时,你会想要什么。我的猜测是一个常量,可用于该类的所有实例化。否则,如果你需要像人口计数器这样的东西,那就使用非 final 变量。

0

就个人而言,我使用CamelCase符号表示非final类变量。从代码中可以清楚地看出它是一个类变量,因为您必须将其引用为:FooBar.bDoNotRunTests

在这方面,我使用this前缀来区分类实例变量和局部作用域变量。例如:this.bDoNotRunTests


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接