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

和相同的原理ExtraItem。如果ClassCastException命名的类实际上不是Item.

于 2012-11-09T09:18:12.340 回答
0

当您在字符串中传递 className 时,您无法避免强制转换。由于您没有类型,我将创建 aClass<?>并且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 回答