0

私は次のクラス構造を持っています:

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

私が欲しいのはClass<? extends Role>、RoleEnums のリストから型の要素の配列を取得することです。私は 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;
4

1 に答える 1

1

ご覧のとおり、配列とジェネリックを組み合わせた効果です。Java の配列は実行時に完全に型指定されます。コンポーネントの型は実行時に利用可能であり、ロード/ストア操作は型チェックされ、例外がスローされる場合があります。

これには、コンポーネントの型具体化可能な型である必要がありますが、パラメーター化された型RoleComboWidget<W>はそうではありません。ジェネリックは、コンパイル時に追加された目に見えないキャストを介して Java に実装されますが、プログラムが実行されると、JVM は実際にはそれが aList<String>か aかを認識しませんList<Integer>

問題に戻ると、API を制御している場合は、コレクション (またはストリーム) の代わりに配列を必要とする場合は注意してください。利点 (通常はパフォーマンス) が欠点 (通常はソースコードのメンテナンス) を上回ることはめったにありません。SomeParameterizedType<T>[]また、キャスト先が常にチェックされていないことに注意してください (コンパイルはすでに警告しています) 。前に説明したように、間違った型のオブジェクトが生成され、プログラムが台無しになったり停止したりする可能性があります。

于 2016-03-08T15:50:20.987 に答える