在Java中,通常建议将变量保持私有以实现更好的封装,但是对于静态常量呢?下面这段代码:
public static final int FOO = 5;
以下代码的结果与此相同:
private static final int FOO = 5;
...
public static getFoo() { return FOO; }
但哪种做法更好?
直接在代码中使用常量的一个原因是不可取的。
假设FOO可能稍后更改(但仍保持不变),比如说 public static final int FOO = 10;
。只要没人傻到直接硬编码该值,这应该不会有任何问题,对吧?
否定的。Java编译器将内联像上面的Foo这样的常量到调用代码中,即someFunc(FooClass.FOO);
变成 someFunc(5);
。现在,如果重新编译库而不重新编译调用代码,你可能会遇到令人惊讶的情况。如果使用函数- JIT仍然会优化它,因此没有实际性能损失。
Pi
很有可能在这么多年后也不会变成 3 ;)),所以我不会谴责在所有情况下都使用公共常数。但是应该记住这一点,因为调试这样的问题非常糟糕。 - Voo由于最终变量不能在以后更改,如果您将其用作全局常量,只需将其设置为public,无需getter。
在这里使用Getter是没有意义的,而且很可能会被JVM内联。只需坚持使用公共常量即可。
封装背后的想法是保护变量不受意外更改,并隐藏内部表示。对于常量来说,这并没有太多意义。
将变量用作类外部:
public def FOO:Integer = 5;
private static final int FOO = 5;
...
public static getFoo() { return FOO; }
不依赖变量是更好的代码维护实践。记住,“过早优化是万恶之源”。
如果getFoo的结果是常量且不需要在运行时评估,那么第一个if语句将会执行。
我会选择使用getFoo(),因为它允许你在不改变客户端代码的情况下将来修改实现方式。正如@Tomasz所指出的,JVM可能会内联你目前的实现,所以你不会支付太多性能的代价。
FOO
真的是一个常量吗?提供FOO
的类是API的一部分还是终端应用程序的一部分?有些数学常数永远不会改变。也有一些位标志永远不应该改变(请参见SWT)。所以答案是“这取决于情况”。 - Tim Bender