How to create Instance from genericReturnType

Viewed 129

Here I need to create an object of java.util.List<com.entity.User>, where I have java.util.List<com.entity.User> is available as string only.

demo class

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

In another class

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();
    }

Here I need to create an object of java.util.List<com.entity.User>, I only have genericReturnType = java.util.List<com.entity.User>

I tried

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

This returns java.lang.ClassNotFoundException

I want to create instance of java.util.List<com.entity.User>

the thing is that the method allUser can be anything and return type of method can be anything

stuff till Method genericReturnType seems fine. I need to create an object with the help of genericReturnType.

NOTE: consider that there is no any syntex error in code.

let me simplify this.

// 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();

I want to do some process with com.entity.User if there is list of User is there, (there might any kind of list there instead of User) so I need to identify generic type of List as well.

Thanks in advance.

1 Answers

You can extract the generic type this after casting the Type into a 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 {

}
Related