常量接口反模式¶
ID: java/constants-only-interface
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- maintainability
- modularity
Query suites:
- java-security-and-quality.qls
常量(指静态的 final 字段)的定义应放在逻辑上所属的相应类中。但是,通常不建议仅仅为了将多个常量定义放入作用域而实现接口(或扩展抽象类)。
建议¶
将常量定义放入作用域的首选方法是使用 import static
指令,该指令允许编译单元将其他类中的任何可见静态成员放入作用域。
这个问题在 [Bloch] 中讨论过。
类在内部使用某些常量是一个实现细节。实现常量接口会导致此实现细节泄漏到类的导出 API 中。对于类的用户来说,类是否实现了常量接口无关紧要。事实上,它甚至可能会让他们感到困惑。更糟糕的是,它代表了一种承诺:如果在未来的版本中修改了类,使其不再需要使用这些常量,它仍然必须实现该接口以确保二进制兼容性。
为了防止类的二进制接口受到污染,最好将常量定义移至最常使用它们的具体类中。定义的用户可以使用 import static
来访问相关的字段。
示例¶
在以下示例中,接口 MathConstants
仅用于保存一个常量。
public class NoConstantsOnly {
static interface MathConstants
{
public static final Double Pi = 3.14;
}
static class Circle implements MathConstants
{
public double radius;
public double area()
{
return Math.pow(radius, 2) * Pi;
}
}
}
相反,应该将常量移至 Circle
类或其他经常使用该常量的类中。
参考文献¶
J. Bloch, Effective Java(第二版),第 19 条。Addison-Wesley,2008。