...
This noncompliant code example compiles although it produces an unchecked warning because the raw type of the List.add()
method is used (the list
parameter in the addToList()
method) instead of rather than the parameterized type. To make this code compile cleanly, the @SuppressWarnings
annotation is used.
Code Block | ||
---|---|---|
| ||
public class MixedTypes { @SuppressWarnings("unchecked") private static void addToList(List list, Object obj) { list.add(obj); // Uncheckedunchecked warning } privatepublic static void printmain(String[] args) { List<String> list = new ArrayList<String> (); addToList(list, 1); System.out.println(list.get(0)); } public static void main(String[] args) { MixedTypes.print(); } } |
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 not of the proper type (that is, String
):
Code Block |
---|
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at Raw.print(Test.java:11)
at Raw.main(Test.java:14)
|
Compliant Solution
By gleaning information from the diagnostic exception message, the error can be quickly traced to the line addToList(1)
in the noncompliant code example. Changing this to addToList("1")
is a superficial defense. To resolve the issue, use parameterized types consistently.
an improper type. In other words, the code aborts some time after the operation that caused the abort is executed, complicating debugging.
Compliant Solution (Checked 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>
.
Code Block | ||
---|---|---|
| ||
class MixedTypes {
private static void addToList(List list, Object obj) {
list.add(obj); // Unchecked warning
}
public static void main(String[] args) {
List<String> list = new ArrayList<String> ();
List<String> checkedList = Collections.checkedList( list, String.class);
addToList( checkedList, 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)
This 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
To enforce compile time checking of types, replace the parameters to the method addToList()
with List<String> list
and String str
.
Code Block | ||
---|---|---|
| ||
class Parameterized { private static void addToList(List<String> list, String str) { list.add(str); // UncheckedNo warning generated } privatepublic static void printmain(String[] args) { List<String> list = new ArrayList<String> (); addToList(list, "1"); System.out.println(list.get(0)); } public static void main(String[] args) { Parameterized.print(); } } |
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 mismatch.
...
This code produces the output:
Code Block |
---|
1.0 1 1 1 |
Compliant Solution
This compliant solution generifies the addToList()
method to eliminate possible type violations.
...
Wiki Markup |
---|
\[[Langer 2008|AA. Bibliography#Langer 08]\] Topic 3, "[Coping with Legacy|http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#Topic3]" [[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 23: "Don't use raw types in new code" [[Bloch 2007|AA. Bibliography#Bloch 07]\] Generics, 1. "Avoid Raw Types in New Code" \[[Naftalin 2006bBloch 2005|AA. Bibliography#Bloch 05]\] Puzzle 88: Raw Deal \[[Darwin 2004|AA. Bibliography#NaftalinBibliography#Darwin 06b04]\] "Principle of Indecent Exposure" 8.3 Avoid Casting by Using Generics \[[JavaGenerics 2004|AA. Bibliography#JavaGenerics 04]\] \[[JLS 2005\]|AA. Java Bibliography#JLSReferences#JLS 05]\] The Java Language Specification, Conversions and Promotions, also 4.8 "Raw types" and 5.1.9 "Unchecked Conversion" \[[Naftalin 2006|AA. Bibliography#Naftalin 06]\] Chapter 8, "Effective Generics" \[[Naftalin 2006b|AA. Bibliography#Naftalin 06b]\] "Principle of Indecent Exposure" \[[Schildt 2007|AA. Bibliography#Schildt 07]\] "Create a checked collection" |
...
49. Miscellaneous (MSC) 49. Miscellaneous (MSC) MSC01-J. Do not use insecure or weak cryptographic algorithms