java - 设计模式 : Lazy Singleton, 泛型和继承 : java. lang.Class 无法转换为 java.lang.reflect.ParameterizedType

标签 java generics inheritance singleton lazy-evaluation

我正在尝试使用泛型和继承来实现惰性单例。我创建了一个abstract父类(super class)并声明一个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中提取它并在 SingletonHolderAbstractXMLParser

最佳答案

此代码存在多个问题:

  • static方法不被继承。 AbstractXMLParser.getInstance()不知道它是在 ActivityTypeXMLParser 的上下文中调用的当被称为 ActivityTypeXMLParser.getInstance() 时.

  • AbstractXMLParser.class.getClass()返回Class' of, not你类(class)的类(class)。

  • 不清楚为什么需要AbstractXMLParser<T>完全是通用的。请注意T位于AbstractXMLParser , SingletonHoldergetInstance()是不同类型的参数。

您需要将相关类传递给getInstance()隐含地:

getInstance(ActivityTypeXMLParser.class);

.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends AbstractXMLParser> T getInstance(Class<T> clazz) 
    throws InstantiationException, 
    ...
}

关于java - 设计模式 : Lazy Singleton, 泛型和继承 : java. lang.Class 无法转换为 java.lang.reflect.ParameterizedType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14180619/

相关文章:

java - 让一个类在运行时扩展另一个类

java - 将字符串数组转换为 double 组(原始类型)的最佳做法是什么

java - 检测 ASTM 协议(protocol)传输结束

java - retrofit 2 : Parsing data structure in list of list without Java 8

java - SerialVersionUID 异常

java - 使用相同的参数类型创建通用映射来保存类型的键和值

Java泛型,返回什么而不是-1

swift - 尝试从工作迭代器模式中获取通用代码

具有继承模板的C++调用函数

java - Java 嵌套子类实例化声明