我具有以下类结构:

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;

最佳答案

您将看到将数组与泛型结合在一起的效果。 Java中的数组在运行时是完全类型化的:组件类型在运行时可用,并且加载/存储操作经过类型检查,并可能引发异常。

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

回到问题所在,如果您可以控制API,则在需要数组而不是Collection(或Stream)时要小心:好处(通常在性能上)很少超过缺点(通常在源代码维护中)。另外,要警告(编译器已经警告您)始终不检查对SomeParameterizedType<T>[]的强制转换:按照前面所述,您可能会得到错误类型的对象,这些对象可能会弄乱甚至暂停程序。

09-04 11:37
查看更多