The Java standard library provides many useful public utility classes, interfaces, and packages. Do not use the identifiers representing these items to refer to some distinct item.
If a developer uses an identifier that reuses the name of a public class, such as {{Vector}}, a subsequent maintainer might not be aware that this identifier does not actually refer to {{java.util.Vector}}, and might incorrectly use the custom {{Vector}} when their intention was to use the original {{java.util.Vector}} class. The custom type {{Vector}} can [shadow|BB. Definitions#shadow] a class name from {{java.util.Vector}}), as specified by Java Language Specification \[[JLS 2005|AA. Bibliography#JLS 05]\], [Section 6.3.2.|http://java.sun.com/docs/books/jls/third_edition/html/packages.html#6.3.2]. This can cause unexpected program behavior. |
Well-defined import statements can resolve these issues. However, when the definitions of the reused name are imported from other packages, use of the _type-import-on-demand declaration_ (see \[[JLS 2005|AA. Bibliography#JLS 05]\], [Section 7.5.2|http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.5.2], "Type-Import-on-Demand Declaration") can lead to unexpected import of a class that was not intended. Moreover, a common and potentially misleading tendency is to produce the import statements _after_ writing the code, often via automatic inclusion of import statements by an IDE. This creates further ambiguity with respect to the names; when a custom type is found earlier in the Java include path than the intended type, no further searches are conducted. |
This noncompliant code example implements a class that reuses the name of the class java.util.Vector
. It attempts to introduce a different condition for the isEmpty()
method for interfacing with native legacy code, by overriding the corresponding method in java.util.Vector
. Unexpected behavior can arise if a maintainer confuses the isEmpty()
method with java.util.Vector.isEmpty()
method.
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"); } } } |
This compliant solution uses a different name for the class, preventing any potential shadowing.
class MyVector { //other code } |
When the developer and organization control the original shadowed class, it may be preferable to change the design strategy of the original in accordance with Bloch's _Effective Java_ \[[Bloch 2008|AA. Bibliography#Bloch 08]\] "Item 16: Prefer interfaces to abstract classes." Changing the original class into an interface would permit class {{MyVector}} to declare that it implements the hypothetical {{Vector}} interface. This would permit client code that intended to use {{MyVector}} to remain compatible with code that uses the original implementation of {{Vector}}. |
Name reuse makes code more difficult to read and maintain. This can result in security weaknesses.
Guideline |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP16-J |
low |
unlikely |
medium |
P2 |
L3 |
An automated tool can easily detect reuse of the set of names representing public classes or interfaces from the Java Standard Library.
C Secure Coding Standard: PRE04-C. Do not reuse a standard header file name
C++ Secure Coding Standard: PRE04-CPP. Do not reuse a standard header file name
\[[JLS 2005|AA. Bibliography#JLS 05]\] [Section 6.3.2|http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.3.2] "Obscured Declarations", [Section 6.3.1|http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.3.1] "Shadowing Declarations", [Section 7.5.2|http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.5.2] "Type-Import-On_Demand Declaration", [Section 14.4.3|http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.4.3] "Shadowing of Names by Local Variables" \[[FindBugs 2008|AA. Bibliography#FindBugs 08]\] \[[Bloch 2005|AA. Bibliography#Bloch 05]\] Puzzle 67: All Strung Out \[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 16: Prefer interfaces to abstract classes |
MET17-J. Do not increase the accessibility of overridden or hidden methods OBJ17-J. Do not expose sensitive private members of an outer class from within a nested class