这是指示的代码:
import java.util.Iterator;
public class MyClass<T> implements Iterable<T> {
private int n;
private Object array[];
public myClass( int size ){
array = new Object[size];
n=0;
}
@Override
public Iterator<T> iterator(){
return new MyClassIterator<T>(n,array); //Here's my error!
}
}
class MyClassIterator<T> implements Iterator<T>{
private int n;
private T[] array;
MyClassIterator( int n, T[] array ){
this.n = n;
this.array = array;
}
@Override
public T next(){
return array[n++];
}
@Override
public boolean hasNext(){
return n==array.length;
}
}
这段代码给我错误:
错误:类型不兼容:Object []无法转换为T [] 返回新的myClassIterator(n,array); 其中T是类型变量: T扩展在类myClass中声明的对象 注意:一些消息已简化。用-Xdiags:verbose重新编译以获取完整输出 1个错误
但是在iterator()中创建myClassIterator对象的操作中删除了
起作用的“正确”代码是这样的:
@Override
public Iterator<T> iterator(){
return new myClassIterator(n,array);
}
答案 0 :(得分:1)
您说:
但是在删除iterator()中的myClassIterator对象中的`之后,错误消失了,代码可以正常工作了
通过删除类型参数<T>
,您将使用MyClassIterator
中的raw type。该错误消失的原因是
为了向后兼容,请将参数化类型分配给其原始数据 类型是允许的。
使用原始类型,您基本上会获得泛型行为
在这种情况下,iterator()
将返回一个MyClassIterator
,它返回类型为Object
的元素。
之所以可行,是因为
如果将原始类型分配给参数化类型,则会收到警告:
这样您会收到警告,但不会收到编译时错误。
但是为什么指定通用类型会给我这个错误?
public Iterator<T> iterator() {
return new MyClassIterator<T>(n, array); // Here's my error!
}
在这里,您尝试将组件类型为Object
的数组传递给构造函数MyClassIterator(int n, T[] array)
。该构造函数接受类型为T
的数组。 Object
的实例类型为T
吗?这可能是但并非必须如此。但是要调用此构造函数必须如此。
如何填补这一空白?
必须使用组件类型array
声明字段T
。
private T[] array;
但是array = new Object[size];
将不起作用because
您无法创建参数化类型的数组。
该如何解决?
通过将Class<T>
传递到@ohlec suggests之类的构造函数中。
另一个选择是遵循Stream.toArray(IntFunction<T[]> generator)
的示例:
public MyClass(int size, IntFunction<T[]> generator) {
array = generator.apply(size);
n = 0;
}
要创建一个MyClass<String>
= n
的{{1}}实例,我们就这样调用构造函数:
5
在这种情况下,我们将隐式类型参数MyClass<String> strings = new MyClass<>(5, String[]::new);
传递给构造函数。
答案 1 :(得分:0)
MyClassIterator<T>
的构造函数被声明为采用T
的数组,但是您要传递Object
的数组。由于您还使用T
参数化了您的外部类,因此实际上您似乎希望array
字段是T
s的数组
private T array[]
但是,只有将类传递给构造函数,您才能初始化数组:
public myClass( int size, Class<T> clazz ){
array = (T[]) Array.newInstance(clazz, size);
}