17

I am trying to implement an inner class that has a generic parameterized type.

Here is a short version of my code:

public class AVLTree<T extends Comparable<? super T>> implements Iterable<T> {
 ...

 private class BinaryNode<T extends Comparable<? super T>> {
  ...
 }

 private class TreePreOrderIterator<E extends Comparable<? super E>> implements Iterator<E> {
  ...
 }

}

It does not work. Eclipse/Java is giving me a warning that the type T parameter on the inner class is 'hiding' the super class's parameter. Any thoughts on how I can fix this?

EDIT: I added the other inner class I'm having problems with: TreePreOrderIterator. The generic type T will be the same for AVLTree, BinaryNode, and TreePreOrderIterator. The inner classes need to access fields in AVLTree.

EDIT2: Also, the Iterator accesses a BinaryNode<T>, which is a conflict.

(Note: This is part of bigger project I'm doing for a class. If any other information is needed, please ask.)

Kirby
  • 15,127
  • 10
  • 89
  • 104
Will M
  • 2,135
  • 4
  • 22
  • 32
  • can you edit your question to include how the generic type of BinaryNode gets used? e.g., is the BinaryNode parameterized by the same type as the AVLTree? – Carl Jan 05 '10 at 23:38
  • Just edited. Does this answer your question? – Will M Jan 06 '10 at 00:49

4 Answers4

29

If you want T in BinaryNode to be the same type as the enclosing T associated with AVLTree, remove the declaration of T in BinaryNode.

If you want the T in BinaryNode to be different than the enclosing T associated with AVLTree, but you want to be able to access properties of the parent AVLTree, rename T to something else.

If you don't need to access properties of the enclosing AVLTree, make BinaryNode static.

Kirby
  • 15,127
  • 10
  • 89
  • 104
ILMTitan
  • 10,751
  • 3
  • 30
  • 46
  • Okay, thanks. I changed it to something different cause I need to access properties or fields in AVLTree. Problem is I'm getting some compile errors now such as, "Type mismatch: cannot convert from AVLTree.TreePreOrderIterator to Iterator" and "Bound mismatch: The type T is not a valid substitute for the bounded parameter > of the type AVLTree.TreePreOrderIterator." Any fixes? – Will M Jan 06 '10 at 00:30
  • 1
    I removed the declaration of T (the first option). Now when I write "return new AVLTree.TreePreOrderIterator();" I get the error "The member type AVLTree.TreePreOrderIterator must be qualified with a parameterized type, since it is not static." When I remove "" from the previous code, I get the warning "AVLTree.TreePreOrderIterator is a raw type. References to generic type AVLTree.TreePreOrderIterator should be parameterized." – Will M Jan 06 '10 at 15:48
7

Just rename T to something else so it wouldn't conflict with the outer class T.

The type parameter names are visible in all the class scope, including the inner classes. So inner classes or instance methods should declare yet another type parameter whose name conflict with the class type parameter. However, static nested classes and static methods don't have that problem.

notnoop
  • 58,763
  • 21
  • 123
  • 144
1

Just remove generic type declaration from the BinaryNode class. Since the class is declared private, it can only exist within AVLTree, and therefor you can just use the T declared for AVLTree anywhere inside BinaryNode.

Vort3x
  • 1,778
  • 2
  • 20
  • 37
0

It's because the parameter T (as the parameter for the BinaryNode<T> class) is the same as that used for AVLTree<T> -- the parameter used for AVLTree is normally in scope for the definition of the inner class BinaryNode, but because you're giving a new parameter the same name, it will be hidden. You could instead use:

private class BinaryNode<U extends Comparable<? super T>> { ... }
Edmund
  • 10,533
  • 3
  • 39
  • 57