I'm using Java 6.
I'm having trouble getting my inner class to use the same generic class as its enclosing class. Currently I have
public class TernarySearchTree < T > {
...
protected class TSTNode < T > {
// index values for accessing relatives array
protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
protected char splitchar;
protected TSTNode < T > [] relatives;
private T data;
protected TSTNode(char splitchar, TSTNode < T > parent) {
this.splitchar = splitchar;
relatives = new TSTNode[4];
relatives[PARENT] = parent;
}
}
}
Right now I get the warning
The type parameter T is hiding the type T
If I remove the type parameter from the inner class (i.e. remove the <T>
from teh protected class TSTNode<T>
line), then I get a compile error on the line relatives = new TSTNode[4]
.
How can I make everything right?
I don't know what are you trying to do but, there's this sollution:
With this you get a warn instead of a error at the same line.
Using a List is possible a better solution (no warnings)
A variation on Itay Maman's solution.
This is an answer to a broader question than the OP is asking: How do I create an array of generics to be used only internally in Java? (This solution is NOT intended to be used to create a generic array to be returned to the user -- that would be unsafe as is well recognized.)
Edit: Version 5: Use enums with an array. (I think V4 is better for the OP, but if you need an array with generics, here is how -- Josiah Yoder)
You can either:
remove the
<T>
type parameter fromTSTNode
(i.e., make it non-generic) - it will still have access to the outer<T>
.rename the
<T>
type parameter in classTSTNode
to (say)U
.[UPDATE]
Below are four different ways to rewrite your code. All of them compile. I think you should consider the use of an
EnumMap
(see Version 4, below).Version 1: use a differenly named type parameter in the inner class. you need to use a List instead of an array.
Version 2: inherit T from enclosing class
Version 3: use a Map (instead of a List)
Version 4: define the indices as an enum + use an EnunMap (instead of a hash map)
[Update 2] One thing to keep in mind: Use EnumMap instead of ordinal indexing
I suspect what you want is something like:
Here, a tree's head node has the same
T
as the tree itself, and every relative node has the sameT
as the parent node, so all the nodes in the tree will have the same value type as the tree itself.I used an
ArrayList
here because arrays cannot have generic types.As to the compile error for generic array creation when you remove the T from the inner class:
Because it's a non-static inner class, it's within the scope of the outer class's type parameter. Which means that it is implicitly also parameterized by its outer class's type parameter
So when you write
TSTNode
it basically meansTernarySearchTree<T>.TSTNode
(the T here is the outer T). SoTSTNode
is still a generic type (even though you don't see any brackets explicitly), and creating an array of a generic type fails.You can refer to the raw type of
TSTNode
by manually qualifying the name:TernarySearchTree.TSTNode
.So
new TernarySearchTree.TSTNode[4]
is the answer.You will get an unchecked warning, which you can ignore (it is something you have to live with with arrays of generic types)
P.S. removing the type parameter from the inner class is almost certainly the right choice, as non-static inner classes in Java implicitly have a reference to an instance of the outer class. So it is already parameterized with the outer T. If you simply want to use the same T, don't declare another one.