《Java安全编码标准》一3.2 DCL01-J不要重用Java标准库的已经公开的标识

    xiaoxiao2022-05-30  186

    3.2 DCL01-J不要重用Java标准库的已经公开的标识

    不要重用那些在Java标准库中已经使用过的公共的标识、公共的工具类、接口或者包。当一个程序员使用和公开类相同的名字时,如Vector对后来的维护者来说,他可能不知道这个标识并不是指?java.util.Vector?,并且可能会无意地使用这个自定义的Vector类而不是原有的java.util.Vector类。使得这个自定义的?Vector会遮蔽java.util.Vector类,正如在JLS的6.3.2节中提到的那样。从而会导致不可预期的程序行为。良好定义的import语句可以解决这个问题。然而,当重用的命名定义是从其他包中导入时,使用type-import-on-demand declaration(详细参见JLS的7.5.2节“Type-Import-on-Demand Declaration”[JLS 2005])会将程序员弄糊涂,因为他需要确定哪一个定义是想要的。另外,因为我们通常会使IDE来自动包括import语句,所以一种常见的操作是在编写代码后才生成这些import语句,但这种做法容易导致错误。在Java包含的import引用路径中,如果在预期的类出现之前出现了一个自定义的类,那么不会进一步搜索,这样就会毫无知觉地使用了错误的类。

    3.2.1 不符合规则的代码示例(类名称)

    这个不符合规则的代码实现了一个类,这个类重用了java.util.Vector 的名称。它在isEmpty()中使用了一个不同的条件判断,尝试通过重写java.util.Vector中对应的方法来达到与遗留代码接口的目的。如果维护者混淆了这个isEmpty()和java.util.Vector. isEmpty(),就会出现不可预知的行为。

    class Vector { ??private int val = 1; ??public boolean isEmpty() { ????if (val == 1) {???// compares with 1 instead of 0 ??????return true; ????} else { ??????return false; ????} ??} ??// other functionality is same as java.util.Vector } // import java.util.Vector; omitted public class VectorUser { ??public static void main(String[] args) { ????Vector v = new Vector(); ????if (v.isEmpty()) { ??????System.out.println("Vector is empty"); ????} ??} }

    3.2.2 符合规则的方案(类名称)

    这个符合规则的方案为这个类使用了不同的名字,防止这个类作为任何潜在的Java标准类库中的类名称的遮蔽情况出现。

    class MyVector { ??// other code }

    当程序员和开发团队可以控制那些被模仿的原始类,更好的方法就是改变对它们的设计策略,这些策略可以根据Bloch的《Effective Java》[Bloch 2008]一书中第16条,更倾向于接口而不是抽象类的方法来实现。将原始类改变成接口,这可以让MyVector类得以通过声明它是我们假设的接口Vector?的实现。这可以让使用MyVector的代码与使用原始Vector实现的代码互相兼容。

    3.2.3 风险评估

    重用公有的标识会降低代码的可读性和可维护性。

    自动化检测 对于重用了Java标准类库中公共类和接口的名字的问题,它们可以被自动检测工具很容易地检测到。

    3.2.4 相关规范

    3.2.5 参考书目

    相关资源:七夕情人节表白HTML源码(两款)

    最新回复(0)