Fluent从包含泛型类的列表中迭代到数组

时间:2016-03-08 15:31:50

标签: java generics guava toarray

我有以下类结构:

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;

1 个答案:

答案 0 :(得分:1)

您看到的是将数组与泛型相结合的效果。 Java中的数组在运行时完全输入:组件类型在运行时可用,加载/存储操作是类型检查的,可能会抛出异常。

这要求组件类型可再生类型,但参数化类型如RoleComboWidget<W>则不是。泛型是通过在编译时添加的不可见强制转换在Java中实现的,但是一旦程序运行,JVM实际上并不知道它是List<String>还是List<Integer>

回到你的问题,如果你控制API,在需要数组而不是Collection(或Stream)时要小心:很少有好处(通常在性能上)优于缺点(通常在源代码维护中)。另外,请注意(编译已经警告过你),SomeParameterizedType<T>[]的强制转换始终是未选中的:根据前面解释的内容,你最终可能会得到错误的类型的对象。搞砸甚至停止你的计划。