Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
TheCat
class discussed earlier in this chapter has a legacy methodgetLitter
, that returns a collection of Cat objects:Note that thepublic Collection getLitter(int size) { ArrayList litter = new ArrayList(size); for (int i = 0; i < size; i++) { litter.add(i, new Cat()); return litter; } }Collection
object is a raw type; the type of object contained in the collection is not specified. This situation exists for all methods that return collections before generics became available.Suppose you write a new program,
Cats
, that assigns this returned litter to a collection whose type is specified to be aCat
:When you compilepublic static void main(String[] args) { Collection<Cat> litter = myCat.getLitter(3); for (Cat c : litter) { System.out.println(c.getColor()); }Cats.java
you will get the following warning:Using theNote: Cats.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.Xlint:checked
flag provides this information:In addition, if% javac -Xlint:unchecked Cats.java Cats.java:5: warning: [unchecked] unchecked conversion found : java.util.Collection required: java.util.Collection<Cat> Collection<Cat> litter = myCat.getLitter(3); ^Cat
is recompiled with a compiler that supports generics, the following warning will result:Though the code is correct, these warnings indicate that the compiler can't guarantee the correctness of the operations, the way it can when using collections whose types are specified throughout. Whenever you get an unchecked warning, you should verify that the operation that gives rise to the warning is really correct.% javac -Xlint:unchecked Cat.java Cat.java:19: warning: [unchecked] unchecked call to add(int,E) as a member of the raw type java.util.ArrayList litter.add(i, new Cat()); ^Finally, let's look at a complete listing of the
Stack2
class:Notice that thepublic class Stack2<T> implements Cloneable { private ArrayList<T> items; private int top=0; public Stack2() { items = new ArrayList<T>(); } public void push(T item) { items.add(item); top++; } public T pop() { if (items.size() == 0) throw new EmptyStackException(); T obj = items.get(--top); return obj; } public boolean isEmpty() { if (items.size() == 0) return true; else return false; } protected Stack2<T> clone() { try { Stack2<T> s = (Stack2<T>)super.clone(); // Clone the stack s.items = (ArrayList<T>)items.clone(); // Clone the list return s; // Return the clone } catch (CloneNotSupportedException e) { //This shouldn't happen because Stack is Cloneable throw new InternalError(); } } }clone
method invokes theclone
methods of its superclass and contained list. Theclone
methods are legacy methods because they were defined before generics became available.When you compile
Stack2.java
you will get the following warning:These warnings indicate that the compiler can't guarantee the correctness of the cast. In other words, because the% javac -Xlint:unchecked Stack2.java Stack2.java:32: warning: [unchecked] unchecked cast found : java.lang.Object required: Stack2<T> Stack2<T> s = (Stack2<T>)super.clone(); //clone the stack ^ Stack2.java:33: warning: [unchecked] unchecked cast found : java.lang.Object required: java.util.ArrayList<T> s.items = (ArrayList<T>)items.clone(); //clone the list ^ 2 warningsclone
method is defined to return an object of typeObject
, the compiler can't verify that the collection being returned is aStack2<T>
. However, because of the contract of theclone
method, the assignment is legal, though it generates an unchecked warning.There are many subtleties to using generics and interoperating with legacy code. For further information on generics see:
- Gilad Bracha's comprehensive tutorial, Generics in the Java Programming Language
- Java Generics FAQ
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.