![](/img/trans.png)
[英]java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
[英]Design Pattern: Lazy Singleton, Generics and Inheritance: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
我試圖用泛型和繼承實現Lazy Singleton。 我創建了一個abstract
超類,並聲明了一個Map,它將存儲該類的子類的所有實例。
這里是:
public abstract class AbstractXMLParser<T> {
@SuppressWarnings("rawtypes")
private static final Map<Class<? extends AbstractXMLParser>, AbstractXMLParser> INSTANCES = new HashMap<>();
public AbstractXMLParser() {
throw new UnsupportedOperationException("Cannot instantiate");
}
private static class SingletonHolder<T> {
@SuppressWarnings({ "unchecked"})
private static <T> T getInstance() throws InstantiationException, IllegalAccessException {
Class<T> clazz = (Class<T>) ((ParameterizedType) SingletonHolder.class.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return clazz.newInstance();
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends AbstractXMLParser> T getInstance() throws InstantiationException, IllegalAccessException {
Class<T> clazz = (Class<T>) ((ParameterizedType) AbstractXMLParser.class.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
if(INSTANCES.containsKey(clazz)) {
return (T) INSTANCES.get(clazz);
} else {
T instance = SingletonHolder.getInstance();
INSTANCES.put(clazz, instance);
return instance;
}
}
}
其中一個兒童班是:
public class ActivityTypeXMLParser extends AbstractXMLParser<ActivityTypeXMLParser>{
private ActivityTypesXMLModel activityTypes;
private ActivityTypeXMLParser() {
}
public static void main(String... strings) throws InstantiationException, IllegalAccessException {
ActivityTypeXMLParser.getInstance();
}
}
main
方法是用於測試目的。 但我得到例外:
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.edfx.adb.xml.parser.AbstractXMLParser.getInstance(AbstractXMLParser.java:25)
at com.edfx.adb.xml.parser.ActivityTypeXMLParser.main(ActivityTypeXMLParser.java:30)
現在調試后我發現了
Class<T> clazz = (Class<T>) ((ParameterizedType) AbstractXMLParser.class.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
是異常的原因,因為AbstractXMLParser.class.getClass().getGenericSuperclass()
返回class java.lang.Object
。 我需要在這里獲得Class<T>
。 我怎樣才能提取它的類AbstractXMLParser
和SingletonHolder
的AbstractXMLParser
?
此代碼存在多個問題:
static
方法不是繼承的。 當調用ActivityTypeXMLParser.getInstance()
時, AbstractXMLParser.getInstance()
不知道它在ActivityTypeXMLParser
上下文中被調用。
AbstractXMLParser.class.getClass()
返回Class' of
Class , not
Class的Class`。
目前尚不清楚為什么需要AbstractXMLParser<T>
才是通用的。 請注意, AbstractXMLParser
, SingletonHolder
和getInstance()
中的T
是不同的類型參數。
您需要隱式地將有問題的類傳遞給getInstance()
:
getInstance(ActivityTypeXMLParser.class);
。
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends AbstractXMLParser> T getInstance(Class<T> clazz)
throws InstantiationException,
...
}
這是我所做的完整解決方案,對某人有幫助。
abstract super-class
:
@SuppressWarnings({"all"})
public abstract class AbstractXMLParser<T> {
private static final Map<Class<? extends AbstractXMLParser>, AbstractXMLParser> INSTANCES = new HashMap<>();
public AbstractXMLParser() {
}
private static class SingletonHolder<T> {
private static <T> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Constructor<T> constructor = (Constructor<T>) clazz.getDeclaredConstructors()[0];
constructor.setAccessible(true);
return constructor.newInstance(null);
}
}
protected static <T extends AbstractXMLParser<T>> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
if(INSTANCES.containsKey(clazz)) {
return (T) INSTANCES.get(clazz);
} else {
T instance = SingletonHolder.getInstance(clazz);
INSTANCES.put(clazz, instance);
return instance;
}
}
protected static <T extends AbstractXMLParser<T>> void putInstance(Class<T> clazz, T instance) {
if(!INSTANCES.containsKey(clazz)) {
INSTANCES.put(clazz, instance);
}
}
}
其中一個孩子班:
public class ActivityTypeXMLParser extends AbstractXMLParser<ActivityTypeXMLParser>{
private ActivityTypeXMLParser() {
}
public static ActivityTypeXMLParser getInstance() {
ActivityTypeXMLParser activityTypeXMLParser = null;
try {
activityTypeXMLParser = getInstance(ActivityTypeXMLParser.class);
} catch (Exception exception) {
}
if(activityTypeXMLParser == null) {
activityTypeXMLParser = new ActivityTypeXMLParser();
putInstance(ActivityTypeXMLParser.class, activityTypeXMLParser);
}
return activityTypeXMLParser;
}
}
您似乎想要獲取類的泛型類型,該類是抽象類的子類。 但是你得到了
AbstractXMLParser.class.getClass()
這是抽象類的類,它總是Class
而不是你應該只使用getClass()
到具體類的類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.