两个私有子类中的相同类型变量不被识别为相同
Same type variable in two private subclasses not recognized as same
在对实现数据结构进行了一些研究后,我发现在尝试使用与父项相同的通用 class 制作两个子 class 时出现问题。
我以前没有发现这个问题,因为我通常避免做私有子classes,虽然这次我想做一个快速测试并发现了这个。
我可以在没有 Node<T>
作为 current
类型的情况下使它工作,但是 Node
,然后转换为 T
。但我想知道为什么编译器不理解它与 Node.js 中的 T
相同。它认为 Node 中的 T
和 LinkedStackIterator
中的 T
是两个不同的 T
,即使 node 中的 T
被识别为 T
LinkedStack
.
public class LinkedStack<T> implements Iterable<T>{
private Node<T> first = null;
private class Node<T>{
private T item;
private Node next;
}
private class LinkedStackIterator<T> implements Iterator<T>{
private Node<T> current = first; //Error here
public boolean hasNext() { return current.next == null; }
public void remove() { throw new UnsupportedOperationException(); }
public T next()
{
T item = current.item;
current = current.next;
return item;
}
}
}
Error: incompatible types: LinkedStack<T#1>.Node<T#1> can not be converted to LinkedStack<T#1>.LinkedStackIterator<T#2> where T#1 and T#2 are type variables.
T#1 extends Object in LinkedStack
T#2 extends Object in LinkedStack.LinkedStackIterator.
感谢您的帮助。
在这里声明两个不同的 T
类型:
public class LinkedStack<T> implements Iterable<T>{
...
private class LinkedStackIterator<T> implements Iterator<T>{
...
}
所以这条语句无法编译:
private Node<T> current = first;
因为 first
变量指的是与 current
变量不同的类型。
first
指的是 LinkedStack
的 T
而 current
指的是 LinkedStackIterator
的 T
要允许两个 class 使用相同的 T
类型,不要在内部 class 中再次声明 T
而是重用一个在外部声明 class :
private class LinkedStackIterator implements Iterator<T>{
您不需要将通用类型添加到第二个 class、LinkedStackIterator
。它将继承外部 class.
的类型
请注意,尽管使用相同的名称 T
,但对于类型参数,它将是一个 与外部 class 不同的 参数。同样的道理,在第一个内层classNode
中,最好给参数取一个不同的名字,例如Node<U>
,让区别一目了然。
以下代码对我来说编译得很好(在制作 LinkedStack
抽象之后):
public abstract class LinkedStack<T> implements Iterable<T>{
private Node<T> first = null;
private class Node<U>{
private U item;
private Node<U> next;
}
private class LinkedStackIterator implements Iterator<T>{
private Node<T> current = first; //Error here
public boolean hasNext() { return current.next == null; }
public void remove() { throw new UnsupportedOperationException(); }
public T next()
{
T item = current.item;
current = current.next;
return item;
}
}
}
泛型T
继承自LinkedStack<T>
class
所以 Node
有两种可能的定义
我更喜欢这个——注意 static
private static class Node<T> {
private T item;
private Node<T> next;
}
如果您出于某些原因需要 Node
是非静态的
(只有 item
类型必须是 T
)
private class Node {
private T item;
private Node next;
}
在对实现数据结构进行了一些研究后,我发现在尝试使用与父项相同的通用 class 制作两个子 class 时出现问题。
我以前没有发现这个问题,因为我通常避免做私有子classes,虽然这次我想做一个快速测试并发现了这个。
我可以在没有 Node<T>
作为 current
类型的情况下使它工作,但是 Node
,然后转换为 T
。但我想知道为什么编译器不理解它与 Node.js 中的 T
相同。它认为 Node 中的 T
和 LinkedStackIterator
中的 T
是两个不同的 T
,即使 node 中的 T
被识别为 T
LinkedStack
.
public class LinkedStack<T> implements Iterable<T>{
private Node<T> first = null;
private class Node<T>{
private T item;
private Node next;
}
private class LinkedStackIterator<T> implements Iterator<T>{
private Node<T> current = first; //Error here
public boolean hasNext() { return current.next == null; }
public void remove() { throw new UnsupportedOperationException(); }
public T next()
{
T item = current.item;
current = current.next;
return item;
}
}
}
Error: incompatible types: LinkedStack<T#1>.Node<T#1> can not be converted to LinkedStack<T#1>.LinkedStackIterator<T#2> where T#1 and T#2 are type variables.
T#1 extends Object in LinkedStack
T#2 extends Object in LinkedStack.LinkedStackIterator.
感谢您的帮助。
在这里声明两个不同的 T
类型:
public class LinkedStack<T> implements Iterable<T>{
...
private class LinkedStackIterator<T> implements Iterator<T>{
...
}
所以这条语句无法编译:
private Node<T> current = first;
因为 first
变量指的是与 current
变量不同的类型。
first
指的是 LinkedStack
的 T
而 current
指的是 LinkedStackIterator
的 T
要允许两个 class 使用相同的 T
类型,不要在内部 class 中再次声明 T
而是重用一个在外部声明 class :
private class LinkedStackIterator implements Iterator<T>{
您不需要将通用类型添加到第二个 class、LinkedStackIterator
。它将继承外部 class.
请注意,尽管使用相同的名称 T
,但对于类型参数,它将是一个 与外部 class 不同的 参数。同样的道理,在第一个内层classNode
中,最好给参数取一个不同的名字,例如Node<U>
,让区别一目了然。
以下代码对我来说编译得很好(在制作 LinkedStack
抽象之后):
public abstract class LinkedStack<T> implements Iterable<T>{
private Node<T> first = null;
private class Node<U>{
private U item;
private Node<U> next;
}
private class LinkedStackIterator implements Iterator<T>{
private Node<T> current = first; //Error here
public boolean hasNext() { return current.next == null; }
public void remove() { throw new UnsupportedOperationException(); }
public T next()
{
T item = current.item;
current = current.next;
return item;
}
}
}
泛型T
继承自LinkedStack<T>
class
所以 Node
我更喜欢这个——注意 static
private static class Node<T> {
private T item;
private Node<T> next;
}
如果您出于某些原因需要 Node
是非静态的
(只有 item
类型必须是 T
)
private class Node {
private T item;
private Node next;
}