我有以下类结构:
abstract class Role;
class Employee extends Role;
class Student extends Role;
class Employer extends Role;
此外,我还有一个枚举,其中存储了可接受的角色。
public enum RoleEnum
{
EMPLOYEE ("Employee", Employee.class),
STUDENT ("Student", Student.class),
EMPLOYER ("Employer", Employer.class);
final private String name;
final private Class<? extends Role> pRoleClass;
private RoleEnum(final String name, final Class<? extends Role> pRoleClass)
{
this.name = name;
this.pRoleClass = pRoleClass;
}
}
我想要的是从RoleEnums列表中获取类型Class<? extends Role>
的元素数组。我正在使用Guava库中的FluentIterable,我想做的就像FluentIterable.from(list).transform(function).toArray(Class<? extends PartyRole>)
。然而,我设法做的是一个解决方法和一种黑客攻击。它看起来像这样:
(Class<R>[]) FluentIterable.from(roles)
.transform(new Function<RoleEnum, Class<R>>()
{
@Override public Class<R> apply(final RoleEnum role)
{
return (Class<R>) role.getRoleClass();
}
})
.toList().toArray(new Class[0]));
,其中
class RoleComboWidget<R extends Role>
是我调用方法的类和
ImmutableList<RoleEnum> roles;
答案 0 :(得分:1)
您看到的是将数组与泛型相结合的效果。 Java中的数组在运行时完全输入:组件类型在运行时可用,加载/存储操作是类型检查的,可能会抛出异常。
这要求组件类型是可再生类型,但参数化类型如RoleComboWidget<W>
则不是。泛型是通过在编译时添加的不可见强制转换在Java中实现的,但是一旦程序运行,JVM实际上并不知道它是List<String>
还是List<Integer>
。
回到你的问题,如果你控制API,在需要数组而不是Collection(或Stream)时要小心:很少有好处(通常在性能上)优于缺点(通常在源代码维护中)。另外,请注意(编译已经警告过你),SomeParameterizedType<T>[]
的强制转换始终是未选中的:根据前面解释的内容,你最终可能会得到错误的类型的对象。搞砸甚至停止你的计划。