...
In JDK 1.6.0_10, the output of this code snippet is 0
. In this code, we want to count the same numbers of array list1
and array list2
. Undoubtedly, the result is not what we expect. Integer
can only cache from -127 to 128, so when an int
number is beyond this range, it will be autoboxed into different objects, and ==
will return false. But if we can set more caches inside Integer
(cache all the integer values -32K-32K, which means that all the int
values could be autoboxed to the same Integer
object), then the result may be different.
Compliant Solution
In JDK 1.6.0_10, the output of this code is 10
. Notice that equals
has been used for comparisons in this case.
Code Block | ||
---|---|---|
| ||
public class TestWrapper1 { public static void main(String[] args) { //Create an array list of integers, where each element //is more than 127 ArrayList<Integer> list1 = new ArrayList<Integer>(); for(int i=0;i<10;i++) list1.add(i+1000); //Create another array list of integers, where each element //is the same as the first one ArrayList<Integer> list2 = new ArrayList<Integer>(); for(int i=0;i<10;i++) list2.add(i+1000); int counter = 0; for(int i=0;i<10;i++) if(list1.get(i).equals(list2.get(i))) counter++; System.out.println(counter); } } |
...
Noncompliant Code Example
Wiki Markup |
---|
This noncompliant code snippet \[[Techtalk 07|AA. Java References#Techtalk 07]\] prints {{100}} as the size of the {{HashSet}} while it is expected to print {{1}}. The combination of a {{short}} and an {{integer}} value in the operation {{i-1}} leads to autoboxing into an {{Integer}} object. The {{HashSet}} contains only {{short}} values whereas (distinctly typed) {{Integer}} objects are being removed successively. The remove operation is thus equivalent to a _No Operation_ (NOP). The compiler enforces type checking so that only {{short}} values are inserted, however, a programmer is free to remove an object of any type without triggering any exceptions. |
Code Block | ||
---|---|---|
| ||
public class ShortSet {
public static void main(String[] args) {
HashSet<Short> s = new HashSet<Short>();
for(short i=0; i<100;i++) {
s.add(i);
s.remove(i - i);
}
System.out.println(s.size());
}
}
|
Compliant Solution
Avoid mixing different types together with an integer
type. If inevitable, cast the autoboxed Integer
object to a Short
to remedy the issue described in the noncompliant code.
Code Block | ||
---|---|---|
| ||
public class ShortSet {
public static void main(String[] args) {
HashSet<Short> s = new HashSet<Short>();
for(short i=0; i<100;i++) {
s.add(i);
s.remove((short)(i-1)); //cast to short
}
System.out.println(s.size());
}
}
|
Risk Assessment
Using array lists with primitive types causes a potential security risk.
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[Core Java 04|AA. Java References#Core Java 04]\] Chapter |
Publisher:Prentice Hall PTR;Pub Date:August 17, 2004.
Section 5.1.7, The Java⢠Language Specification,Third Edition by James Gosling, Bill Joy, Guy Steele, Gilad Bracha
Publisher:ADDISON-WESLEY;Pub Date:May 2005.
5
\[[JLS 05|AA. Java References#JLS 05]\] Section 5.1.7
\[[Techtalk 07|AA. Java References#Techtalk 07]\] "The Joy of Sets" |
...
EXP04-J. Be wary of invisible implicit casts 02. Expressions (EXP) 03. Scope (SCP)