Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

If a parameterized type tries to access an object that is not of the parameterized type, heap pollution resultsoccurs. For instance, consider the code snippet below.

...

When executed, this code produces an exception not because a List<String> receives an Integer, but rather because the value returned by list.get(0) is an improper type. In other words, the code aborts some time after the operation that caused the abort is executed, complicating debugging.

Compliant Solution (

...

Parameterized Collection)

This compliant solution creates a checked view of the list by using the Collections.checkedList() method. This method returns a wrapper collection that performs runtime type checking in its implementation of the add() method before delegating to the backend List<String>enforces type-safety by changing the addToList() function signature to enforce proper type checking. It also complies by adding a String rather than an Integer.

Code Block
bgColor#ccccff
class MixedTypesParameterized {
  private static void addToList(ListList<String> list, ObjectString objstr) {
    list.add(objstr);     // UncheckedNo warning generated
  }

  public static void main(String[] args) {
    List<String> list = new ArrayList<String> ();
    List<String> checkedList = Collections.checkedList( addToList(list, String.class);
    addToList( checkedList, 1"1");
    System.out.println(list.get(0));
  }
}

The compiler still issues the "unchecked warning", which may still be ignored. However, the code now fails precisely when it attempts to add the Integer to the list, consequently preventing the program from proceeding with invalid data.

Compliant Solution (Parameterized Collection)

does not allow insertion of an Object once list is parameterized. Likewise, addToList() cannot be called with an argument whose type produces a mismatch.

Compliant Solution (Legacy Code)

While the recommended solution eliminates usage of raw collections, this may not always be possible when using legacy code.

Suppose that the addToList() method was legcay code and could not be changed. The following compliant solution creates a checked view of the list by using the Collections.checkedList() method. This method returns a wrapper collection that performs runtime type checking in its implementation of the add() method before delegating to the backend List<String>. This wrapper collection may be safely passed to the legacy addToList() methodThis compliant solution enforces type-safety by changing the addToList() function signature to enforce proper type checking. It also complies by adding a String rather than an Integer.

Code Block
bgColor#ccccff
class ParameterizedMixedTypes {
  private static void addToList(List<String>List list, StringObject strobj) {
    list.add(strobj);     // NoUnchecked warning generated
  }

  public static void main(String[] args) {
    List<String> list = new ArrayList<String> ();
    List<String> checkedList = Collections.checkedList( list, String.class);
    addToList(list checkedList, "1");
    System.out.println(list.get(0));
  }
}

The compiler does not allow insertion of an Object once list is parameterized. Likewise, addToList() cannot be called with an argument whose type produces a mismatchstill issues the "unchecked warning", which may still be ignored. However, the code now fails precisely when it attempts to add the Integer to the list, consequently preventing the program from proceeding with invalid data.

Noncompliant Code Example

...