Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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泛型方法,使用反射实例化具有任何构造函数的任何类_Java_Oop_Generics_Reflection - Fatal编程技术网

Java泛型方法,使用反射实例化具有任何构造函数的任何类

Java泛型方法,使用反射实例化具有任何构造函数的任何类,java,oop,generics,reflection,Java,Oop,Generics,Reflection,正如我们所知,Java使用擦除,所以任何泛型类都不能这样做 T t = new T(); 所以我尝试用Java反射来创建一个带有静态方法的类,用任何构造函数来实例化任何类。这是代码 import java.lang.reflect.*; public class GenericNewInstance { public static <T> T createInstance(Class<T> cObj) { try { r

正如我们所知,Java使用擦除,所以任何泛型类都不能这样做

T t = new T();
所以我尝试用Java反射来创建一个带有静态方法的类,用任何构造函数来实例化任何类。这是代码

import java.lang.reflect.*;

public class GenericNewInstance {
    public static <T> T createInstance(Class<T> cObj) {
        try {
            return cObj.newInstance();
        } catch (InstantiationException e) {
            System.out.println("Instantiation Exception");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("Illegal Access Exception");
            return null;
        }
    }

    public static <T> T createInstanceUsingRelection(Class<T> c, Object... initArgs) {
        Constructor<T> cTor = null;
        Class<?>[] cObjs = new Class<?>[initArgs.length];
        int i = 0;

        for(Object o : initArgs) {
            cObjs[i++] = o.getClass();
        }

        try {
            cTor = c.getConstructor(cObjs);
        } catch (SecurityException e) {
            System.out.println("security exception. Cannot get Constructor");
            return null;
        } catch (NoSuchMethodException e) {
            System.out.println("NoSuchMethodException Cannot get constructor");
            return null;
        }

        try {
            return cTor.newInstance(initArgs);
        } catch (IllegalArgumentException e) {
            System.out.println("Illegal Argument Exception");
            return null;
        } catch (InstantiationException e) {
            System.out.println("Instantiation Exception");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("Illegal Access Exception");
            return null;
        } catch (InvocationTargetException e) {
            System.out.println("Invocation Target Exception");
            return null;
        }
    }
}
所以我的问题是:

  • 这是正确的实施方式吗?(还是冗长?)
  • 这样做的典型用例是什么
  • 在使用泛型时是否可以/应该避免使用反射

  • 您的代码将在
    c.getConstructor(cObjs)
    失败,因为这没有考虑类型层次结构。如果任何参数是构造函数声明的参数类型的子类型,则此调用不会返回该参数。你需要更多的打字技巧才能让它工作。我建议你看一下这本书。也许您甚至可以按原样使用该库,这是您的选择。它是Clojure的实现代码,一种基于JVM的动态语言,它需要的就是这些东西。该图书馆可从Maven central repo获得


    顺便说一句,您的异常处理是多余的。要么声明
    抛出异常
    ,要么捕获任何
    异常
    ,并将其包装在
    运行时异常
    中。当某些东西失败时,原始异常是最好的诊断。

    您的代码将在
    c.getConstructor(cObjs)
    失败,因为这不考虑类型层次结构。如果任何参数是构造函数声明的参数类型的子类型,则此调用不会返回该参数。你需要更多的打字技巧才能让它工作。我建议你看一下这本书。也许您甚至可以按原样使用该库,这是您的选择。这是Clojure的实现代码,Clojure是一种基于JVM的动态语言,需要这些东西。该图书馆可从Maven central repo获得


    顺便说一句,您的异常处理是多余的。要么声明
    抛出异常
    ,要么捕获任何
    异常
    ,并将其包装在
    运行时异常
    中。当出现故障时,原始异常是最好的诊断。

    您不仅需要传递参数值,还需要传递参数类型您可以命名提供此功能的java库吗?所提到的库是java库
    clojue core.jar
    。您不仅需要传递参数值,还需要传递参数类型。您可以命名提供此功能的java库吗?提到的库是java库
    clojue core.jar
    Integer i = GenericNewInstance.createInstanceUsingRelection(Integer.class, "0");