【问题标题】:How to create Instance from genericReturnType如何从 genericReturnType 创建实例
【发布时间】:2021-09-21 19:56:32
【问题描述】:

这里我需要创建一个java.util.List的对象,其中 我有 java.util.List 只能作为字符串使用。

演示课

class Demo {
    public List<User> allUser() {
        // some stuff
    }
}

在另一个班级

Method method = null;
try {
         Class cls= Class.forName("Demo"); // fully qualified Name here for sure
         
         Method[] methods = cls.getMethods();
         for (Method _method:methods) {
             if(_method.getName().equals("allUser")) {
                method = _method;
                break;
             }
         }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if(method != null) {
            java.lang.reflect.Type genericReturnType = method.getGenericReturnType();
    }

这里我需要创建一个java.util.List的对象,我只有 genericReturnType = java.util.List

我试过了

Class clazz = Class.forName(genericReturnType.getTypeName());

这会返回java.lang.ClassNotFoundException

我想创建 java.util.List

的实例

问题是allUser 方法可以是任何东西,方法的返回类型可以是任何东西

直到 Method genericReturnType 看起来还不错。我需要在 genericReturnType 的帮助下创建一个对象。

注意:请考虑代码中没有任何语法错误。

让我简化一下。

// I want to achive this
String clsName = "java.util.List<com.entity.User>";  // consider fully qualified name
Class cls = Class.forName(clsName); // from here I got error java.lang.ClassNotFoundException
Object clsInstance = (Object) cls.newInstance();

如果有用户列表,我想用com.entity.User 做一些处理,(那里可能有任何类型的列表而不是用户)所以我还需要识别列表的通用类型强>。

提前致谢。

【问题讨论】:

  • 我不明白背后的动机。由于类型擦除,此信息在运行时无论如何都不应该相关。
  • 通过识别 List 的泛型类型我想通过反射检查当前类中是否存在的一些属性。根据属性的存在与否,有不同的操作。

标签: java methods reflection


【解决方案1】:

您可以在将Type 转换为ParameterizedType 之后提取泛型类型:

ReflectionTest.java

public class ReflectionTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Method method = null;
        try {
            Class cls = Class.forName("Demo"); // fully qualified Name here for sure

            Method[] methods = cls.getMethods();
            for (Method _method : methods) {
                if (_method.getName().equals("allUser")) {
                    method = _method;
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (method != null) {
            System.out.println(method.getReturnType());
            ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType();

            if (parameterizedType.getActualTypeArguments().length > 0 && parameterizedType.getActualTypeArguments()[0] instanceof Class<?>) {
                Class type = (Class) parameterizedType.getActualTypeArguments()[0];

                User user = (User) type.newInstance();

                System.out.println(user.getClass());
            }
        }
    }
}

class Demo {
    public List<User> allUser() {
        return Collections.emptyList();
    }
}

User.java

public class User {

}

【讨论】:

  • 我已经试过了,出现类型转换错误如下图:class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType (java.lang.Class and java.lang .reflect.ParameterizedType 在加载器'bootstrap'的模块java.base中)
  • 如果返回类型没有被参数化(例如public List allUser()),那么method.getGenericReturnType()返回一个Class对象,而不是一个ParameterizedType。是你在做什么吗?无论如何,我认为您需要共享更多代码,以便问题更清楚
  • List 是我在代码中提到的方法的返回类型。那是实际的代码。
  • 我已经用我正在运行的代码编辑了我的答案,我不知道你在做什么不同。确保您正在执行的代码是您看到的代码,该项目我没有编译,您可能正在运行其他东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多