Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.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 如何从传递给函数的列表T[]中获取泛型T的类型,然后使用T进行实例化?_Java - Fatal编程技术网

Java 如何从传递给函数的列表T[]中获取泛型T的类型,然后使用T进行实例化?

Java 如何从传递给函数的列表T[]中获取泛型T的类型,然后使用T进行实例化?,java,Java,例如,假设有一个代码块,如下所示: public className<T> { public className(T[] varName) { //somecode } } 公共类名{ 公共类名(T[]varName){ //一些代码 } } 如何从T[]的实例中获取T的类型,然后使用它来实例化T类型的对象?为了使您能够实例化T类型的任何元素,在这种情况下,您需要使用反射,并且必须满足一些条件: 如果数组不为null且数组中至少有一个元素,则只能

例如,假设有一个代码块,如下所示:

public className<T> {
    public className(T[] varName) {
        //somecode
    }
}
公共类名{
公共类名(T[]varName){
//一些代码
}
}

如何从T[]的实例中获取T的类型,然后使用它来实例化T类型的对象?

为了使您能够实例化T类型的任何元素,在这种情况下,您需要使用反射,并且必须满足一些条件:

  • 如果数组不为null且数组中至少有一个元素,则只能获取
    T
    的类型。由于类型擦除,在数组中不存在实际对象的情况下,无法直接推断类型

  • 然后,您必须检查数组中第一个对象的构造函数是否有no args参数

下面是一个可执行示例,您可以尝试:

import javax.swing.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class TypeClass<T> {

    public TypeClass(T[] array) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        if(array != null && array.length > 0) { // You can only get the type of T if the arrays is not null and there is at least one element in the array
            T first = array[0];
            Class<?> clazz = first.getClass();
            Constructor<?>[] constructors = clazz.getConstructors();
            for(Constructor<?> constructor : constructors) {
                int parameterCount = constructor.getParameterCount(); // Check if the constructor has a no args argument
                if(parameterCount == 0) {
                    T o = (T) constructor.newInstance();
                    // Do something with the new object
                    System.out.println(o);
                }
            }
        }
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        JFrame[] jframes = new JFrame[]{new JFrame()};
        TypeClass<JFrame> typeClass = new TypeClass<>(jframes);
    }
}
更新 您还可以指定一个替代构造函数,该构造函数专门指示要通过反射实例化的类型。这更有意义,因为数组中的元素类型实际上可能是type
T
的子类。下面是一个替代构造函数的示例:

// Alternative with the specific type for instantiation
public TypeClass(T[] array, Class<T> tClass) throws IllegalAccessException, InvocationTargetException, InstantiationException {
    if(tClass != null) {
        Class<?> clazz = tClass.getClass();
        Constructor<?>[] constructors = clazz.getConstructors();
        for(Constructor<?> constructor : constructors) {
            int parameterCount = constructor.getParameterCount(); // Check if the constructor has a no args argument
            if(parameterCount == 0) {
                T o = (T) constructor.newInstance();
                // Do something with the new object
                System.out.println(o);
            }
        }
    }
}
//具有用于实例化的特定类型的备选方案
公共类型类(T[]数组,类tClass)抛出IllegaAccessException、InvocationTargetException、InstanceionException{
if(tClass!=null){
类clazz=tClass.getClass();
构造函数[]constructors=clazz.getConstructors();
for(构造函数:构造函数){
int parameterCount=constructor.getParameterCount();//检查构造函数是否有无args参数
如果(参数计数==0){
T o=(T)构造函数.newInstance();
//对新对象执行某些操作
系统输出打印ln(o);
}
}
}
}

恐怕您不能这样做。泛型在运行时被擦除,因此您的方法将获得一个
对象[]
,而不是
T[]
。您必须传递一个类对象,答案是cannot,但C#can do。你必须以param的身份通过这门课,我不确定这是不是该走的路。数组
MyObject[]
可以包含
MyObject
的子类元素。在我看来,仅使用第一个元素似乎相当随意。创建任意实例可能会产生不可预知的后果。@LuCio你是对的。可能存在子类。另一个更好的选择是使用
classclazz
更改构造函数,并精确指定要实例化的类型。这肯定是一个比这个更好的解决方案。在新方法中,
array
是未使用的,因此它实际上没有回答这个问题。如果只是“从
T[]
的实例中获取
T
的类型”,我们可以调用
array.getClass().getComponentType()
。你也给出了一个答案,这可能是一个合适的答案。但是国际海事组织OP还没有澄清背景。因此,我的第一个评论需要OP来回答。但现在游戏结束了;)
// Alternative with the specific type for instantiation
public TypeClass(T[] array, Class<T> tClass) throws IllegalAccessException, InvocationTargetException, InstantiationException {
    if(tClass != null) {
        Class<?> clazz = tClass.getClass();
        Constructor<?>[] constructors = clazz.getConstructors();
        for(Constructor<?> constructor : constructors) {
            int parameterCount = constructor.getParameterCount(); // Check if the constructor has a no args argument
            if(parameterCount == 0) {
                T o = (T) constructor.newInstance();
                // Do something with the new object
                System.out.println(o);
            }
        }
    }
}