使用泛型和自定义迭代器时出错
Error while using generics and customized iterator
这是被起诉的代码:
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;
}
}
这段代码给我的错误:
error: incompatible types: Object[] cannot be converted to T[]
return new myClassIterator(n,array);
where T is a type-variable:
T extends Object declared in class myClass
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
但在 iterator() 中创建 myClassIterator 对象时删除 后,错误消失并且代码运行没有问题,现在我问为什么指定泛型会给我这个错误?
有效的 "correct" 代码如下:
@Override
public Iterator<T> iterator(){
return new myClassIterator(n,array);
}
MyClassIterator<T>
的构造函数被声明为采用 T
的数组,但您传递的是 Object
的数组。因为你已经用 T
参数化了你的外部 class ,所以看起来你确实希望 array
字段是 T
s
的数组
private T array[]
但是,如果将 class 传递给构造函数,则只能初始化数组,如下所示:
public myClass( int size, Class<T> clazz ){
array = (T[]) Array.newInstance(clazz, size);
}
你说:
但是在 iterator() 中创建 myClassIterator 对象时删除 ` 后,错误消失,代码运行没有问题
通过删除类型参数 <T>
,您将使用 MyClassIterator
的 raw type。错误消失,因为
For backward compatibility, assigning a parameterized type to its raw
type is allowed.
Using raw types, you essentially get pre-generics behavior
在这种情况下,iterator()
会 return 一个 MyClassIterator
,其中 return 是 Object
类型的元素。
之所以有效,是因为
if you assign a raw type to a parameterized type, you get a warning:
因此您会收到警告,但不会收到编译时错误。
但是为什么指定泛型会报错?
public Iterator<T> iterator() {
return new MyClassIterator<T>(n, array); // Here's my error!
}
此处您试图将组件类型为 Object
的数组传递给构造函数 MyClassIterator(int n, T[] array)
。此构造函数接受 T
类型的数组。 Object
s 实例是类型 T
吗?这可以但不必。但是要调用这个构造函数,它必须是。
如何填补这个空白?
字段 array
需要用组件类型 T
.
声明
private T[] array;
但是 array = new Object[size];
将不起作用 because
You cannot create arrays of parameterized types.
如何解决?
通过将 Class<T>
传递给 @ohlec .
这样的构造函数
另一种选择是效仿Stream.toArray(IntFunction<T[]> generator)
的例子:
public MyClass(int size, IntFunction<T[]> generator) {
array = generator.apply(size);
n = 0;
}
要使用 n
= 5
创建一个 MyClass<String>
实例,我们这样调用构造函数:
MyClass<String> strings = new MyClass<>(5, String[]::new);
在这种情况下,我们将类型参数 String
隐式传递给构造函数。
这是被起诉的代码:
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;
}
}
这段代码给我的错误:
error: incompatible types: Object[] cannot be converted to T[] return new myClassIterator(n,array); where T is a type-variable: T extends Object declared in class myClass Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error
但在 iterator() 中创建 myClassIterator 对象时删除
有效的 "correct" 代码如下:
@Override
public Iterator<T> iterator(){
return new myClassIterator(n,array);
}
MyClassIterator<T>
的构造函数被声明为采用 T
的数组,但您传递的是 Object
的数组。因为你已经用 T
参数化了你的外部 class ,所以看起来你确实希望 array
字段是 T
s
private T array[]
但是,如果将 class 传递给构造函数,则只能初始化数组,如下所示:
public myClass( int size, Class<T> clazz ){
array = (T[]) Array.newInstance(clazz, size);
}
你说:
但是在 iterator() 中创建 myClassIterator 对象时删除 ` 后,错误消失,代码运行没有问题
通过删除类型参数 <T>
,您将使用 MyClassIterator
的 raw type。错误消失,因为
For backward compatibility, assigning a parameterized type to its raw type is allowed.
Using raw types, you essentially get pre-generics behavior
在这种情况下,iterator()
会 return 一个 MyClassIterator
,其中 return 是 Object
类型的元素。
之所以有效,是因为
if you assign a raw type to a parameterized type, you get a warning:
因此您会收到警告,但不会收到编译时错误。
但是为什么指定泛型会报错?
public Iterator<T> iterator() {
return new MyClassIterator<T>(n, array); // Here's my error!
}
此处您试图将组件类型为 Object
的数组传递给构造函数 MyClassIterator(int n, T[] array)
。此构造函数接受 T
类型的数组。 Object
s 实例是类型 T
吗?这可以但不必。但是要调用这个构造函数,它必须是。
如何填补这个空白?
字段 array
需要用组件类型 T
.
private T[] array;
但是 array = new Object[size];
将不起作用 because
You cannot create arrays of parameterized types.
如何解决?
通过将 Class<T>
传递给 @ohlec
另一种选择是效仿Stream.toArray(IntFunction<T[]> generator)
的例子:
public MyClass(int size, IntFunction<T[]> generator) {
array = generator.apply(size);
n = 0;
}
要使用 n
= 5
创建一个 MyClass<String>
实例,我们这样调用构造函数:
MyClass<String> strings = new MyClass<>(5, String[]::new);
在这种情况下,我们将类型参数 String
隐式传递给构造函数。