7

type で生成されたクラスがあり<T extends Enum<T> & Runnable>ます。Class<T> barクラス名で設定したメンバー変数があります: t = (Class<T>) Class.forName(name). これにより、チェックされていないキャストの警告が表示されます。

通常、asSubclassを使用すると同様の状況で使用できますが、T複数の境界があるため、コンパイラの警告を表示せずに使用することはできません。

//This is type safe, but I still get an unchecked cast warning
t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);

を使用せずに、この警告を何らかの方法で取り除くことはできます@SupressedWarning("unchecked")か?

完全な例:

public class Example<T extends Enum<T> & Runnable> {
    Class<T> t;

    Example(String className) throws ClassNotFoundException {
        t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);
    }
}
4

2 に答える 2

4
//This is type safe, but I still get an unchecked cast warning
t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);

おっと、ちょっとゆっくり!それは実際に本当ですか?いいえ、ちがいます!あなたが行ったのは、渡された名前に一致するクラスが実際には ではなく、Runnableと の両方であることを確立することだけです。境界を検証しただけです。クラスとがあると想像してください:EnumTT1T2

package foo;
public enum T1 implements Runnable {
    ;
    @Override
    public void run() {
    }
}

package foo;
public enum T2 implements Runnable {
    ;
    @Override
    public void run() {
    }
}

次に、これは正常に機能しますが、明らかにタイプ セーフではありません。

Example<T1> example = new Example<T1>("foo.T2");
Class<T1> t1Clazz = example.t; //uh oh...

これは、複数の境界の問題でもありません。バウンドが 1 つだけの場合も同じ問題が発生します。

@sp00m が言及しているように、本当の解決策はおそらくClass<T>ここに渡すことです。

編集

一方、内部的Tにのみ必要であり(つまり、複数の境界を指定するため)、実際に公開する必要がない場合、別のオプションは、2 つの別々の参照でクラスを維持することです。例えば:

Class<? extends Runnable> runnableClass;
Class<? extends Enum> enumClass;

Example(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    Class<?> clazz = Class.forName(className);
    runnableClass = clazz.asSubclass(Runnable.class);
    enumClass = clazz.asSubclass(Enum.class);
}

これは、型パラメーターがないと、同時に であるという知識を実際に利用できる状況がほとんどないためです。クラスのインスタンスを作成する場合は、タイプorの変数/フィールドに割り当てる必要があります。両方を行うことはできません。enumRunnableRunnableEnum

于 2013-07-09T21:53:27.980 に答える
1

私はあなたが単にできないと信じています...私の意見では、最良の解決策は、をClass<T> clazzではなくパラメータとして直接渡すことString nameです。

于 2013-07-09T09:17:54.500 に答える