Item 23: Don’t use raw types in new code 博客分类: Effective Java2读书笔记 Generic TypesRaw Typesunbounded wildcardClassCastException
1. Raw types behave as if all of the generic type information were erased from the type declaration. For all practical purposes, the raw type List behaves the same way as the interface type List did before generics were added to the platform.
2. It pays to discover errors as soon as possible after they are made, ideally at compile time. By using raw types, you don’t discover the error till runtime, long after it has happened, and in code that is far removed from the code containing the error. Once you see the ClassCastException, you have to search through the code base looking for the method invocation that put the wrong type into the collection.
3. If you use raw types, you lose all the safety and expressiveness benefits of generics.
4. It was deemed critical that all of legacy codes remain legal and interoperable with new code that does use generics. It had to be legal to pass instances of parameterized types to methods that were designed for use with ordinary types, and vice versa. This requirement, known as migration compatibility, drove the decision to support raw types.
5. List<String> is a subtype of the raw type List, but not of the parameterized type List<Object>. As a consequence, you lose type safety if you use a raw type like List, but not if you use a parameterized type like List<Object>.
Commented By Sean:You can assign a List<String> to List and add anything to it through List, but you cann’t assign List<String> to List<Object>.
6. You can’t put any element (other than null) into a Collection<?> and you can’t assume anything about the type of the objects that you get out.
7. There are two minor exceptions to the rule that you should not use raw types in new code, both of which stem from the fact that generic type information is erased at runtime. First, you must use raw types in class literals. (Though it does permit array types and primitive types.) Second, it is illegal to use the instanceof operator on parameterized types other than unbounded wildcard types. The use of unbounded wildcard types in place of raw types does not affect the behavior of the instanceof operator in any way.