3

interfacecom.mycompany.SomeInterfaceと enumがあるとしますcom.mycompany.SomeEnum implements SomeInterfaceSomeInterfaceReflection API を使用して、実行時にこのクラスのすべての列挙型定数をインスタンスとして取得したいと考えています。

現在、私のコード(クラス内EnumConstantGetter)は次のようなものです:

Class<?> clazz = EnumConstantGetter.class.getClassLoader().
  loadClass("com.mycompany.SomeEnum");

if (!(SomeInterface.class.isAssignableFrom(clazz)) {
    throw new Exception("the class doesn't implement SomeInterface");
}

if (!(clazz.isEnum()) {
    throw new Exception("not an enum");
} 

Class<? extends Enum<? extends SomeInterface>> castClass =
  (Class<? extends Enum<? extends SomeInterface>>) clazz; // cast #1
ArrayList<SomeInterface> vals = new ArrayList<SomeInterface>();
for (Enum<? extends SomeInterface> enumConstant :
  castClass.getEnumConstants()) {
    vals.add((SomeInterface) enumConstant); // cast #2
}

上記のコードは機能しているように見えますが、castClass.

私の質問は、次のとおりです。コードに記載されている両方のキャスト (クラスのキャストと定数のキャスト) は、私のチェックに基づいて必ず有効ですか?

言い換えれば、 のすべてのメンバーはEnum<? extends T>を実装することが保証されていTますか?

答えが「はい、キャストは安全です」の場合、なぜコンパイラはこの警告を表示するのでしょうか?

そうでない場合、なぜですか?または、どのような状況でルーチンが失敗する可能性がありますか?

編集:上記のコードは明らかに混乱しているため、何が起こっているのかについての私の説明は次のとおりです。

  1. SomeEnumパッケージで指定されたクラスをロードし、そのオブジェクトを変数にcom.mycompany格納します。Class
  2. SomeInterface参照されたクラスがインターフェースを実装していることを確認してください。
  3. 参照されるクラスが列挙型であることを確認してください。
  4. を実装する列挙型であることがわかっているのでSomeInterfaceClass<? extends Enum<? extends SomeInterface>> キャスト #1にキャストします。
  5. すべての列挙型定数をループします。
  6. 定数ごとに、SomeInterface キャスト #2にキャストし、定数のリストに追加します。

ありがとう!

4

1 に答える 1

5

次のことができます。

Class<?> clazz = ...;
Class<? extends SomeInterface> someInterfaceClass;
try {
    someInterfaceClass = clazz.asSubclass(SomeInterface.class);
}
catch (ClassCastException cce) {
    throw new IllegalStateException("Specified type doesn't implement SomeInterface", cce);
}
SomeInterface[] enumConstants = someInterfaceClass.getEnumConstants();
if (enumConstants == null) {
    throw new IllegalStateException("Specified type is not an enum.");
}

//use constants

asSubclassがチェックされ、オブジェクトが「列挙型を表していない」場合にgetEnumConstants返されるため、これにより警告が回避されます。nullClass

于 2012-11-21T00:52:12.510 に答える