我如何获得内部类继承封闭类的泛型类型? [英] How do I get an inner class to inherit enclosing class' generic type?
问题描述
我正在使用Java 6.
我无法让内部类使用相同的泛型类作为它的封闭类。目前我有
public class TernarySearchTree< / p> T> {
...
受保护的类TSTNode< T> {
//访问亲属数组的索引值
protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;
受保护的char splitchar;
保护TSTNode< T> [] 亲戚们;
私人T数据;
protected TSTNode(char splitchar,TSTNode< T> parent){
this.splitchar = splitchar;
relatives = new TSTNode [4];
亲属[父母] =父母;
}
}
}
现在我收到警告
类型参数T隐藏类型T
如果我从内部类中移除了类型参数(即从受保护的类TSTNode< T>< T>中移除
< T> / code> line),然后我得到一行
relatives = new TSTNode [4]
的编译错误。
我怎样才能把事情做好?
:
-
将
< T>
类型参数从TSTNode
(即使它不是通用的) - 它仍然可以访问外部的< T>
。 重命名类TSTNode 中的
< T>
> [更新]
以下是四种重写代码的方法。他们都编译。我认为你应该考虑使用
EnumMap
(见下面的版本4)。
版本1 :在内部类中使用一个不同名称的类型参数。您需要使用List而不是数组。
public class TernarySearchTree< T> {
受保护的类TSTNode< U> {
//访问亲属数组的索引值:
protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;
保护字符splitchar;
protected List< TSTNode< U>>亲戚们;
私人U数据;
protected TSTNode(char splitchar,TSTNode< U> parent){
this.splitchar = splitchar;
relatives = new ArrayList< TSTNode< U>>();
for(int i = 0; i< HIKID; ++ i){//分配亲戚中的4个位置
relatives.add(null);
}
relatives.set(PARENT,parent);
}
}
private TSTNode< T>节点; //当你使用它时,将T作为U
public TernarySearchTree(){
node = new TSTNode< T>(',',null); //当你使用它时,将T作为U
}
}
第2版:从封装类继承T
public class TernarySearchTree< T> {
protected class TSTNode {
//访问亲属数组的索引值:
protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;
保护字符splitchar;
protected List< TSTNode>亲戚们;
私人T数据;
protected TSTNode(char splitchar,TSTNode parent){
this.splitchar = splitchar;
relatives = new ArrayList< TSTNode>();
for(int i = 0; i< HIKID; ++ i){//分配亲戚中的4个位置
relatives.add(null);
}
relatives.set(PARENT,parent);
}
}
私人TSTNode节点;
public TernarySearchTree(){
node = new TSTNode(',',null);
第3版:use一个Map(而不是一个List)
public class TernarySearchTree< T> {
protected class TSTNode {
//访问亲属数组的索引值:
protected static final int PARENT = 0,LOKID = 1,EQKID = 2,HIKID = 3;
保护字符splitchar;
protected Map< Integer,TSTNode>亲戚们;
私人T数据;
protected TSTNode(char splitchar,TSTNode parent){
this.splitchar = splitchar;
//创建一个哈希映射。无需预先分配!
relatives = new HashMap< Integer,TSTNode>();
relatives.put(父母,父母); // set - >放置
}
}
私人TSTNode节点;
public TernarySearchTree(){
node = new TSTNode(',',null);
}
}
}
第4版:将索引定义为enum +使用EnunMap(而不是哈希映射)
pre $public class TernarySearchTree< T> ; {
保护静态枚举索引{
PARENT,LOKID,EQKID,HIKID;
}
保护类TSTNode {
保护字char splitchar;
protected EnumMap< Index,TSTNode>亲戚们;
私人T数据;
protected TSTNode(char splitchar,TSTNode parent){
this.splitchar = splitchar;
//创建一个EnumMap。
relatives = new EnumMap< Index,TSTNode>(Index.class);
relatives.put(Index.PARENT,parent);
}
}
私人TSTNode节点;
public TernarySearchTree(){
node = new TSTNode(',',null);
}
}
[更新2]
请记住一件事:使用EnumMap而不是顺序索引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 tehprotected class TSTNode<T>
line), then I get a compile error on the linerelatives = new TSTNode[4]
.How can I make everything right?
解决方案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.
public class TernarySearchTree<T> { protected class TSTNode<U> { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected List<TSTNode<U>> relatives; private U data; protected TSTNode(char splitchar, TSTNode<U> parent) { this.splitchar = splitchar; relatives = new ArrayList<TSTNode<U>>(); for (int i = 0; i < HIKID; ++i) { // Allocate 4 slots in relatives relatives.add(null); } relatives.set(PARENT, parent); } } private TSTNode<T> node; // When you use it, pass T as U public TernarySearchTree() { node = new TSTNode<T>(',', null); // When you use it, pass T as U } }
Version 2: inherit T from enclosing class
public class TernarySearchTree<T> { protected class TSTNode { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected List<TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; relatives = new ArrayList<TSTNode>(); for (int i = 0; i < HIKID; ++i) { // Allocate 4 slots in relatives relatives.add(null); } relatives.set(PARENT, parent); } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } }
Version 3: use a Map (instead of a List)
public class TernarySearchTree<T> { protected class TSTNode { // index values for accessing relatives array: protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3; protected char splitchar; protected Map<Integer, TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; // Create a hash map. No need to pre-allocate! relatives = new HashMap<Integer, TSTNode>(); relatives.put(PARENT, parent); // set -> put } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } } }
Version 4: define the indices as an enum + use an EnunMap (instead of a hash map)
public class TernarySearchTree<T> { protected static enum Index { PARENT, LOKID, EQKID, HIKID; } protected class TSTNode { protected char splitchar; protected EnumMap<Index, TSTNode> relatives; private T data; protected TSTNode(char splitchar, TSTNode parent) { this.splitchar = splitchar; // Create an EnumMap. relatives = new EnumMap<Index, TSTNode>(Index.class); relatives.put(Index.PARENT, parent); } } private TSTNode node; public TernarySearchTree() { node = new TSTNode(',', null); } }
[Update 2] One thing to keep in mind: Use EnumMap instead of ordinal indexing
这篇关于我如何获得内部类继承封闭类的泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!