0

I have the following class structure:

abstract class Role;
class Employee extends Role;
class Student extends Role;
class Employer extends Role;

Also I have an enum in which I store the acceptable roles.

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;
      }
}

What I want is to get an array of elements of type Class<? extends Role> from a list of RoleEnums. I am using FluentIterable from Guava libraries and what I am trying to do is something like FluentIterable.from(list).transform(function).toArray(Class<? extends PartyRole>). However what I managed to do is a workaround and kinda of a hack. It looks something like this:

(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]));

where

class RoleComboWidget<R extends Role>

is the class from where I call the method and

ImmutableList<RoleEnum> roles;
4

1 回答 1

1

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

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

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

于 2016-03-08T15:50:20.987 回答