我想知道是否可能通过Java中的参数传递类型。
让我更好地解释一下:
假设下一个代码
class Bee {
// Class implementation
}
class Worker extends Bee {
// Class implementation
}
class Queen extends Bee {
// Class implementation
}
现在用蜜蜂对象创建一个容器
Vector<Bee> x=new Vector<Bee>();
// ...
for(i=0;i<10;i++)
x.add(new Worker());
// ...
for(i=0;i<10;i++)
x.add(new Queen());
现在我想创建一个泛型方法,迭代向量并返回一个具有特定类型的蜜蜂,工人或女王的集合。怎么做?
我试过
search(x,Worker.class);
static public <T extends Bee> Set<T> search(List<Bee> bees, Class<T> clazz){
// ...
}
我收到错误报告“方法搜索(List,Class)不适用于参数(Set,Class)”。问题在于第二个参数,因为类型不兼容。
答案 0 :(得分:5)
您可以使用instanceof
表达式来测试Bee
是Worker
还是Queen
。您可以根据子类型使用它来过滤Vector<Bee>
(甚至更好,List<Bee>
)。
Guava还提供了您可以使用的Iterables.filter(Iterable<?> unfiltered, Class<T> type)
。
答案 1 :(得分:5)
从我的编辑中我看到,你仍然在努力实施。这是一个有效的例子:
public static void main(String[] args) {
Collection<Bee> bees = new ArrayList<Bee>();
bees.add(new Hive.Worker());
bees.add(new Hive.Queen());
Set<Queen> queens = getBeesOfOneType(bees, Queen.class);
}
private static <T extends Bee> Set<T> getBeesOfOneType(Collection<Bee> bees, Class<T> beeType) {
Set<T> result = new HashSet<T>();
for (Bee bee : bees) {
if (beeType.isInstance(bee)) {
// The following cast is safe. The previous if makes sure that
// that bee can be cast to T at this place
T beeTypeInstance = beeType.cast(bee);
result.add(beeTypeInstance);
}
}
return result;
}
还有一种类型的安全警告,我很确定这个警告无法消除。编译器现在没有,我们只选择T型蜜蜂,所以它必须警告我们。
答案 2 :(得分:4)
使用Class
作为方法的参数
public <T extends Bee> Set<T> filterBeesByType(List<Bee> bees, Class<T> clazz)
顺便说一句,最好通过接口(Set
,List
等)来引用集合类型,而不是实现(Vector
)。
答案 3 :(得分:3)
使用instanceof
运算符:
public static Set<Queen> queensOnly(Collection<Bee> bees) {
Set<Queen> queens = new HashSet<Queen>();
for (Bee bee:bees) {
if (bee instanceof Queen) {
queens.add((Queen) bee);
}
}
return queens;
}