我很想知道一个类的泛型类型是否可以通过作为参数传递的另一个对象的泛型类型来定义?
我正在处理的是线程安全迭代器,因此多个线程可以安全地通过列表迭代,而没有两个线程获得相同的对象。它的当前形式很好,但我认为它可以做得更好。
import java.util.Iterator;
public class AtomicIterator implements Iterator<Object>
{
private Iterator<?> it;
public AtomicIterator(Iterable<?> iterable)
{
it = iterable.iterator();
}
public Object next()
{
synchronized(it)
{
if(it.hasNext())
return it.next();
else
return null;
}
}
}
有些代码已被省略,但这应该可以解决这个问题。目前为了获得下一个对象,你总是被迫抛出返回的对象,这似乎效率低下。
ArrayList<String> someList = new ArrayList<String>;
AtomicIterator it = new AtomicIterator(someList);
String example = (String)it.next();
问题显然是it.next()
返回我想要的类型Object
,在此示例中,它返回类型String
简单的解决方案是为AtomicIterator
提供自己的通用类型,从而产生类似的结果
ArrayList<String> someList = new ArrayList<String>();
AtomicIterator<String> it = new AtomicIterator<String>(someList);
String example = it.next();
然而,这对我来说似乎是多余的,someList
已将其通用类型明确定义为String
,而我想要的是AtomicIterator
来推断它来自Iterable
对象的泛型类型。
我真正想要的是这样的事情
import java.util.Iterator;
public class AtomicIterator implements Iterator<E>
{
private Iterator<E> it;
public <E> AtomicIterator(Iterable<E> iterable)
{
it = iterable.iterator();
}
public E next()
{
synchronized(it)
{
if(it.hasNext())
return it.next();
else
return null;
}
}
}
从那里可以做类似
的事情ArrayList<String> someList = new ArrayList<String>();
AtomicIterator it = new AtomicIterator(someList);
String example = it.next();
但是这不起作用,因为泛型类型E
仅存在于构造函数的范围内。
有谁知道一个很好的干净方法吗?
答案 0 :(得分:6)
将泛型类型添加到AtomicIterator,以及(如果在Java 6下运行)静态工厂方法,因此它默认解析泛型类型
public class AtomicIterator<T> implements Iterator<T>
{
private Iterator<T> it;
public AtomicIterator(Iterable<T> iterable)
{
it = iterable.iterator();
}
public static <T> AtomicIterator<T> create ( Iterable<T> iterable )
{
return new AtomicIterator( iterable )
}
public T next()
{
synchronized(it)
{
if(it.hasNext())
return it.next();
else
return null;
}
}
}
以下是用法:
ArrayList<String> someList = new ArrayList<String>;
AtomicIterator<String> it = AtomicIterator.create(someList);
答案 1 :(得分:0)
通用AtomicIterator
的问题在于构造函数本身是通用的,并且具有与类的泛型类型参数不同的泛型类型。 <E>
中的public <E> AtomicIterator
定义了与类泛型参数不同的泛型参数,即使它们都是E
。在我最初尝试编译它时,我得到了一个相当混乱的错误:
AtomicIterator.java:8: incompatible types
found : java.util.Iterator<E>
required: java.util.Iterator<E>
it = iterable.iterator();
^
解决方案:让构造函数的通用参数Iterable<E>
使用类通用参数&#39; E&#39;通过在<E>
之后从public
移除E
并将其添加到类中,因此泛型类型public class AtomicIterator<E> implements Iterator<E>
// ^ Added here
的范围是整个类:
public AtomicIterator(Iterable<E> iterable)
// ^ Remove here
...
{{1}}
答案 2 :(得分:0)
Java 7 Diamond推理 -
AtomicIterator<String> it = new AtomicIterator<>(someList);
^
no need to repeat String here
public class AtomicIterator<E> implements Iterator<E>
public AtomicIterator(Iterable<E> iterable)
如果您不想显式写入完整类型的it
,请让编译器推断出类型,例如
var it = new ...; // the type of `it` is inferred from right hand side
遗憾的是,Java尚未拥有该功能,并且暂时不会使用它。