Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added NCCE/CS + Edited

...

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
bgColor#CCCCFF
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
bgColor#FFCCCC

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
bgColor#CCCCFF

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
5, Core Java™ 2 Volume I - Fundamentals, Seventh Edition by Cay S. Horstmann, Gary Cornell
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)