Effective Java 23 Don't use raw types in new code
2014-03-17 10:42 小郝(Kaibo Hao) 阅读(795) 评论(0) 编辑 收藏 举报Generic types advantage
-
Parameterized type can provide erroneous check in compile time.
// Parameterized collection type - typesafe
private final Collection<Stamp>stamps = ... ;
-
You no longer have to cast manually when removing elements from collections.
// for-each loop over a parameterized collection - typesafe
for (Stamp s : stamps) { // No cast
... // Do something with the stamp
}
or a traditional forloop:
// for loop with parameterized iterator declaration - typesafe
for (Iterator<Stamp> i = stamps.iterator(); i.hasNext(); ) {
Stamp s = i.next(); // No cast necessary
... // Do something with the stamp
}
Note
If you use raw types, you lose all the safety and expressiveness benefits of generics.
You lose type safety if you use a raw type like List, but not if you use a parameterized type like List<Object>.
// Uses raw type (List) - fails at runtime!
public static void main(String[] args) {
List<String> strings = new ArrayList<String>();
unsafeAdd(strings, new Integer(42));
String s = strings.get(0); // Compiler-generated cast
}
private static void unsafeAdd(List list, Object o) {
list.add(o);
}
This program compiles, but because it uses the raw type List, you get a warning:
Test.java:10: warning: unchecked call to add(E) in raw type List
list.add(o);
^
if you run the program, you get a ClassCastException when the program tries to cast the result of the invocation strings.get(0) to a String . This is a compiler-generated cast, so it's normally guaranteed to succeed, but in this case we ignored a compiler warning and paid the price.
unbounded wildcard types - Set<?>
If you want to use a generic type but you don't know or care what the actual type parameter is, you can use a question mark instead.
// Unbounded wildcard type - typesafe and flexible
static int numElementsInCommon(Set<?> s1, Set <?> s2) {
int result = 0;
for (Object o1 : s1)
if (s2.contains(o1))
result++;
return result;
}
Name |
Example |
Feature |
Disadvantage |
Raw type |
List |
Can add anything |
No type security check. |
Generic type |
List<Object> |
Provide type check. |
Generic type information is erased at runtime (Item 25) which means that List<String>.class and List<?> are illegal. |
Unbounded wildcard type |
List<?> |
You can't put any element (other than null) into a Collection<?> but null. |
|
This is the preferred way to use the instanceof operator with generic types
// Legitimate use of raw type - instanceof operator
if (o instanceof Set ) { // Raw type
Set<?> m = (Set<?>) o; // Wildcard type
...
}
Summary
Raw types can lead to exceptions at runtime, so don't use them in new code;
Set<Object> is a parameterized type representing a set that can contain objects of any type;
Set<?> is a wildcard type representing a set that can contain only objects of some unknown type, and Set is a raw type, which opts out of the generic type system. The first two are safe and the last is not.
Term |
Example |
Item |
Parameterized type |
List<String> |
|
Actual type parameter |
String |
|
Generic Type List<E> |
List<E> |
|
Formal type parameter |
E |
|
Unbounded wildcard type |
List<?> |
|
Raw type |
List |
|
Bounded type parameter |
<E extends Number> |
|
Recursive type bound |
<T extends Comparable<T>> |
|
Bonded wildcard type |
List<? Extends Number> |
|
Generic method |
Static <E> List<E> asList(E[] a) |
|
Type token |
String.class |
出处:http://www.cnblogs.com/haokaibo/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。