Java generic list gives me warning

133 views Asked by At

I don't understand why Java compiler gives me 'unchecked conversion' warning in the following situation:

I have this class:

public class NodeTree<T> {
   T value;
   NodeTree parent;
   List<NodeTree<T>> childs;

   NodeTree(T value, NodeTree parent) {
       this.value = value;
       this.parent = parent;
       this.childs = null;
   }

   public T getValue() { return value; }
   public void setValue(T value) { this.value = value; }

   public NodeTree getParent() { return parent; }
   public void setParent(NodeTree parent) { this.parent = parent; }

   public List<NodeTree<T>> getChilds() {
       if (this.childs == null) {
           this.childs = new LinkedList<NodeTree<T>>();
       }
       return this.childs;
   }
}

and in the main class I have the following instructions:

NodeTree node = new NodeTree<Integer>(10, null);

NodeTree<Integer> child = new NodeTree<Integer>(20, node);      
List<NodeTree<Integer>> childs = node.getChilds();

childs.add(child);

I can't explain why the hell I get warning on the getChilds() line of this type:

warning: [unchecked] unchecked conversion
List<NodeTree<Integer>> childs = node.getChilds();
                                               ^
required: List<NodeTree<Integer>>
found:    List
1 warning

getChilds() function does not return List type, it returns List < NodeTree < T > > type.

Please help me to understand.

2

There are 2 answers

0
Gunther Rotsch On BEST ANSWER

Wouldn't it be better to code NodeTree<Integer> node = new NodeTree<>(10, null); instead of NodeTree node = new NodeTree<Integer>(10, null); ? Then the compiler would know the node's type parameter.

0
sisyphus On

You're mixing up raw types with non-raw types. This is fundamentally a BadThing(tm). So your code

NodeTree node = new NodeTree<Integer>(10, null);

creates a node variable as a raw type, even if the initialiser is not a raw type. So, for the compiler, the type of node.getChilds() is actually List and not List<NodeTree<Integer>> as you may have been expecting.

If you change it to be...

NodeTree<Integer> node = new NodeTree<Integer>(10, null);

then that will allow the compiler to keep track of the generic type parameters and do all the type checking it needs to.