Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设计模式:惰性单例、泛型和继承:java.lang.Class不能转换为java.lang.reflect.ParameterizedType_Java_Generics_Inheritance_Singleton_Lazy Evaluation - Fatal编程技术网

设计模式:惰性单例、泛型和继承:java.lang.Class不能转换为java.lang.reflect.ParameterizedType

设计模式:惰性单例、泛型和继承:java.lang.Class不能转换为java.lang.reflect.ParameterizedType,java,generics,inheritance,singleton,lazy-evaluation,Java,Generics,Inheritance,Singleton,Lazy Evaluation,我试图用泛型和继承实现懒惰的单例。我创建了一个abstractsuper类,并声明了一个映射,它将存储这个类的子类的所有实例 这是: public abstract class AbstractXMLParser<T> { @SuppressWarnings("rawtypes") private static final Map<Class<? extends AbstractXMLParser>, AbstractXMLParser> IN

我试图用泛型和继承实现懒惰的单例。我创建了一个
abstract
super类,并声明了一个映射,它将存储这个类的子类的所有实例

这是:

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;
        }
    }
}
现在调试后我发现

Class<T> clazz = (Class<T>) ((ParameterizedType) AbstractXMLParser.class.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Class clazz=(Class)((ParameterizedType)AbstractXMLParser.Class.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

是异常的原因,因为
AbstractXMLParser.class.getClass().getGenericSuperclass()
正在返回
class java.lang.Object
。我需要在这里获取
类。如何在类
AbstractXMLParser
AbstractXMLParser
SingletonHolder
中提取它?

此代码存在多个问题:

  • 静态
    方法不会被继承
    AbstractXMLParser.getInstance()
    不知道它在调用为
    ActivityTypeXMLParser.getInstance()时在
    ActivityTypeXMLParser
    的上下文中被调用

  • AbstractXMLParser.class.getClass()
    返回类的
    class',而不是类的
    class'

  • 不清楚为什么需要
    AbstractXMLParser
    作为泛型。请注意,
    AbstractXMLParser
    中的
    T
    s、
    SingletonHolder
    getInstance()
    是不同的类型参数

您需要隐式地将有问题的类传递给
getInstance()

getInstance(ActivityTypeXMLParser.class);

@SuppressWarnings({“unchecked”,“rawtypes”})
公共静态getInstance(类clazz)
抛出实例化异常,
...
}

您似乎想要获取类的泛型类型,它是抽象类的子类。无论你得到什么

AbstractXMLParser.class.getClass()

这是抽象类的类,它始终是
class
,而您应该只使用
getClass()
来定义具体类的类。

以下是我提出的完整解决方案,对某些人可能会有所帮助

抽象超类

@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);
        }
    }
}
@SuppressWarnings({“all”})
公共抽象类AbstractXMLParser{
私有静态最终映射实例=new HashMap();
公共抽象XmlParser(){
}
私有静态类SingletonHolder{
私有静态T getInstance(类clazz)抛出实例化异常、IllegalAccessException、NoSuchMethodException、SecurityException、IllegalArgumentException、InvocationTargetException{
构造函数=(构造函数)clazz.getDeclaredConstructors()[0];
constructor.setAccessible(true);
返回构造函数.newInstance(null);
}
}
受保护的静态T getInstance(类clazz)抛出实例化异常、IllegalAccessException、NoSuchMethodException、SecurityException、IllegalArgumentException、InvocationTargetException{
if(实例.containsKey(clazz)){
return(T)INSTANCES.get(clazz);
}否则{
T instance=SingletonHolder.getInstance(clazz);
实例.put(clazz,instance);
返回实例;
}
}
受保护的静态void实例(类clazz,T实例){
如果(!INSTANCES.containsKey(clazz)){
实例.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;
    }
}
公共类ActivityTypeXMLParser扩展了AbstractXMLParser{
私有ActivityTypeXMLParser(){
}   
公共静态活动类型XmlParser getInstance(){
ActivityTypeXMLParser ActivityTypeXMLParser=null;
试一试{
activityTypeXMLParser=getInstance(activityTypeXMLParser.class);
}捕获(异常){
}
if(activityTypeXMLParser==null){
activityTypeXMLParser=新activityTypeXMLParser();
putInstance(ActivityTypeXMLParser.class,ActivityTypeXMLParser);
}
返回activityTypeXMLParser;
}
}

感谢您的回复。但是现在我得到另一个错误java.lang.IllegalAccessException for clazz.newInstance()。因为ActivityTypeXMLParser具有私有构造函数。如何克服这个问题?如果您确实需要使用反射访问
private
构造函数,请使用
setAccessible(true)
AbstractXMLParser.class.getClass()
@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;
    }
}