Java 反射通用类型 ParamertizedType 对象创建失败并出现 java.lang.exception

标签 java generics reflection

我正在尝试在运行时生成类型化类的实例以与 Redis 一起使用。

这是我的代码,但它无法创建类型化类 T 的实例。

interface ObjectFactory<T>
{
    T create() throws Exception;
}

这是创建 T 实例的类

import java.lang.reflect.ParameterizedType;

public class RedisObjectConstructor<T> implements ObjectFactory<T>
{

    @SuppressWarnings("unchecked")
    @Override
    public T create() throws Exception
    {
        try
        {
            return (T) ((Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
        }
        catch (Exception e)
        {
            throw new Exception();
        }
    }
}

以下是实际设置和获取域字段值的逻辑:

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.stereotype.Component;

@Component
public class RedisBasicEntity<T>
{
    private final ObjectFactory<T> factory;

    public RedisBasicEntity(ObjectFactory<T> factory)
    {
        this.factory = factory;
    }

    public Map<String, String> getFields(T redisDomain, Class<? extends Annotation> ann)
    {
        Map<String, String> redisHash = new HashMap<String, String>();
        Class<?> clazz = redisDomain.getClass();
        while (clazz != null)
        {
            for (Field field : clazz.getDeclaredFields())
            {
                if (field.isAnnotationPresent(ann))
                {
                    field.setAccessible(true);
                    try
                    {
                        Object value = field.get(redisDomain);
                        if (value != null)
                        {
                            redisHash.put(field.getName(), value.toString());
                            System.out.println(field.getName() + ":" + value.toString());
                        }
                    }
                    catch (IllegalArgumentException e)
                    {

                    }
                    catch (IllegalAccessException e)
                    {

                    }
                }
            }
            c = c.getSuperclass();
        }
        return redisHash;

    }

    public T getRedisEntity(Map<String, String> redisHash, Class<? extends Annotation> ann) throws Exception
    {
        T redisDomain = factory.create();
        Class<?> clazz = redisDomain.getClass();
        while (clazz != null)
        {
            for (Field field : clazz.getDeclaredFields())
            {
                if (field.isAnnotationPresent(ann))
                {
                    field.setAccessible(true);
                    try
                    {
                        FieldUtils.writeDeclaredField(field, field.getName(), redisHash.get(field.getName()));
                    }
                    catch (Exception e)
                    {

                    }
                }
            }
        }
        return redisDomain;
    }
}

这是我的测试类:

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.ranker.annotations.rediskey.RedisHashKey;
import com.ranker.api.dao.iListQualityDAO;
import com.ranker.app.redis.domain.list.ListQuality;
import com.ranker.app.redis.repository.support.RedisBasicEntity;
import com.ranker.app.redis.repository.support.RedisObjectConstructor;

public class ListQualityDAO implements iListQualityDAO
{
    @Autowired 
    private RedisBasicEntity<ListQuality> redisBasicEntity;

    public static ListQuality saveListQuality()
    {
        RedisObjectConstructor<ListQuality> redisObjectConstructor = new RedisObjectConstructor<ListQuality>();
        RedisBasicEntity<ListQuality> redisBasicEntity = new RedisBasicEntity<ListQuality>(redisObjectConstructor);
        ListQuality listQuality = new ListQuality();
        listQuality.setBurialScore(10.0);
        Map<String, String> redisHash = redisBasicEntity.getFields(listQuality, RedisHashKey.class);
        return null;
    }

    public static ListQuality getListQuality() throws Exception
    {
        RedisObjectConstructor<ListQuality> redisObjectConstructor = new RedisObjectConstructor<ListQuality>();
        RedisBasicEntity<ListQuality> redisBasicEntity = new RedisBasicEntity<ListQuality>(redisObjectConstructor);
        Map<String, String> redisHash = new HashMap<String, String>();
        redisHash.put("satisfactionScore", "10.00");
        redisHash.put("burialScore", "5.00");
        redisHash.put("burialState", "true");
        ListQuality listQuality = redisBasicEntity.getRedisEntity(redisHash, RedisHashKey.class);
        return listQuality;

    }


    public static void main(String args[]) throws Exception
    {
        ListQualityDAO.getListQuality();
    }
}

我用来标识字段的注释:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisHashKey {
}

请让我知道这里做错了什么:

这是我测试运行时遇到的异常:

Exception in thread "main" java.lang.Exception at com.ranker.app.redis.repository.support.RedisObjectConstructor.create(RedisObjectConstructor.java:19) at com.ranker.app.redis.repository.support.RedisBasicEntity.getRedisEntity(RedisBasicEntity.java:61) at com.ranker.api.dao.impl.ListQualityDAO.getListQuality(ListQualityDAO.java:37) at com.ranker.api.dao.impl.ListQualityDAO.main(ListQualityDAO.java:45)

最佳答案

如本 stackoverflow response 中所述,我修改了create你的方法RedisObjectConstructor<T>这样:

public class RedisObjectConstructor<T> implements ObjectFactory<T> {
    private final Class<T> type;

    public RedisObjectConstructor(Class<T> type) {
        this.type = type;
    }

    @Override
    public T create() throws Exception {
        return type.newInstance();
    }
}

并像这样实例化它:

RedisObjectConstructor<ListQuality> redisObjectConstructor = 
            new RedisObjectConstructor<ListQuality>(ListQuality.class);

并且不再存在强制转换异常问题。

关于Java 反射通用类型 ParamertizedType 对象创建失败并出现 java.lang.exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30930738/

相关文章:

java - 如何改变JFrame的背景颜色

c# - 如何区分 IEnumerable<int> 和 IEnumerable<MyClass>?

java - 关于用 Java 编写自定义类异常

java - 检查对象是否有Java中的方法?

c# - 将 Func<T, T2> 转换为 Func<T, object> 的更快方法?

Java - gov.nasa.jpf.jvm.Verify Pathfinder 包不存在

java - "Failed to export application"在 Eclipse 4.4.1 for Android 与 ADT 23.0.4

ios - KVO 观察不适用于 Swift 泛型

java - 将一个特定条目从一个 LinkedHashMap 添加到另一个 LinkedHashMap

json - Play2.2 Scala 中通用案例类与 JSON 之间的自动序列化/反序列化