-1

次があるとします。

abstract class Item {   public Item(){}}
abstract class ExtraItem extends Item {  public ExtraItem(){}}
class A extends Item{ public A(){}}
class B extends Item{ public B(){}}
class C extends Item{ public C(){}}
class EA extends ExtraItem{ public A(){}}
class EB extends ExtraItem{ public B(){}}
class EC extends ExtraItem{ public C(){}}

このようなファクトリークラスを書きたいのですが、キャストはしません:

   class Factory {

       Item createItem(String className){
                Class clazz = Class.forName(className);
                return (Item) clazz.newInstance(); //I don't want here cast to Item    
    }
    ExtraItem createExtraItem(String className){
               Class<? extends ExtraItem> clazz = (Class<? extends ExtraItem>)   Class.forName(className); // I don't want here cast to Extraitem
                return clazz.newInstance();
        }
    }

上記のように書いてみます(もちろんキャスト付き):

@SuppressWarnings("unchecked")
public static <T extends Item> T createItem(String protocolType) {
    try {
        String className = protocolType;
        Class<?> clazz = Class.forName(className);                        
        return (T) clazz.newInstance();
    } catch (Exception e) {
        Log.e("ItemFactory", "Lack key \"" + protocolType + "\" in map: " + e.getLocalizedMessage());
    }
    return null;
}

しかし、ここで Class.cast() メソッドをどのように使用しますか? それはより良い方法ですか?

4

3 に答える 3

1

単にコンパイラの警告が気に入らない場合Class.asSubclassは、チェックを行うために使用できます。

Class<? extends Item> clazz = Class.forName(className).asSubclass(Item.class);

についても同じ原則ですExtraItemClassCastException指定されたクラスが実際には のサブクラスでない場合、これは実行時に をスローしますItem

于 2012-11-09T09:18:12.340 に答える
0

className を文字列で渡す場合、キャストを避けることはできません。タイプがないので、 を作成し、Class<?>結果newInstance()は になりObjectます。

キャストしたくない場合は、インスタンスを作成するクラスの Class インスタンスを渡す必要があります。

キャスト以外は通常動作なので、回避してもあまり意味がありません。ほとんどのコードは、プログラミングして動作するように動作することを覚えておいてください。渡された文字列が を継承するクラスを作成できることが確実な場合はItem、予期しない結果を招くことなくキャストできます。

于 2012-11-09T08:37:11.000 に答える
0

まったくキャストしたくない場合は、メソッド シグネチャを次のように変更します。

class Factory {
    <T extends Item> T createItem(Class<T> itemClass) {
        try {
            return itemClass.newInstance();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    <T extends ExtraItem> T createExtraItem(Class<T> itemClass) {
        return createItem(item);
    }
}
于 2012-11-09T08:59:32.150 に答える