简体   繁体   English

我可以在 ArrayList 中获取 object 的类型来实例化通用 class 吗?

[英]Can I get the type of an object in an ArrayList to instantiate a generic class?

I am not experienced in Java, but was tasked with an objective in my company that involves Java and I am looking for help.我在 Java 方面没有经验,但在我的公司中负责一个涉及 Java 的目标,我正在寻求帮助。

I have two Eclipse Java projects: MyProject.Base and MyProject.Contracts with MyProject.Contracts referencing MyProject.Base.我有两个 Eclipse Java 项目:MyProject.Base 和 MyProject.Contracts,其中 MyProject.Contracts 引用 MyProject.Base。 MyProject.Contracts contains a set of serializable classes. MyProject.Contracts 包含一组可序列化的类。

MyProject.Base uses JAXB to (de-)serialize objects. MyProject.Base 使用 JAXB 来(反)序列化对象。 In order to serialize ArrayLists with JAXB, I had to write the following class, because JAXB expects a XmlRootElement annotation for objects that shall be serialized and ArrayList does not offer that. In order to serialize ArrayLists with JAXB, I had to write the following class, because JAXB expects a XmlRootElement annotation for objects that shall be serialized and ArrayList does not offer that.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays", name = "ListOfValuesOfAnyTypeAdapter")
public class ListConverterAdapter<E> {
    @XmlElement(namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays", name = "ListOfValuesOfAnyType")
    List<E> Map;

    public ListConverterAdapter() {
        Map = new ArrayList<E>();
    }

    public ListConverterAdapter(Object value) {
        Map = new ArrayList<E>();

        @SuppressWarnings("unchecked")
        List<E> map = (List<E>) value;
        if (map == null) {
            return;
        }

        for (int i = 0; i < map.size(); i++) {
            Map.add(map.get(i));
        }
    }

    public List<E> GetHashMap() {
        List<E> map = new ArrayList<E>();

        for (int i = 0; i < Map.size(); i++) {
            map.add(Map.get(i));
        }

        return map;
    }
}

I want the serializer and this helper class to work with any list of any data contract to work.我希望序列化程序和这个帮助程序 class 与任何数据合约的任何列表一起工作。 However, JAXB wants to know all the types that are used as E. I could simply add an annotation listing the data contracts, if I could reference MyProject.Contracts in MyProject.Base.但是,JAXB 想知道用作 E 的所有类型。如果我可以在 MyProject.Base 中引用 MyProject.Contracts,我可以简单地添加一个列出数据协定的注释。 However, as I explained earlier, there is already a reference from MyProject.Contracts to MyProject.Base.但是,正如我之前解释的,已经有从 MyProject.Contracts 到 MyProject.Base 的引用。 Meaning, I can't add the new reference, because it would create a circular reference.意思是,我不能添加新的引用,因为它会创建一个循环引用。

I have done some search here and on other forums about instantiating a generic class like mine above at run-time.我已经在此处和其他论坛上进行了一些关于在运行时实例化通用 class 的搜索,如我上面的。 Unfortunately, I am not able to do so for two reasons.不幸的是,我不能这样做有两个原因。 First, as far as I have read in the past days, it is not possible to get to know the type of objects in an empty Java list.首先,据我过去几天的阅读,不可能知道空的 Java 列表中的对象类型。 Second, even if I get the class type of an object in a non-empty list, I can't use it to instantiate my generic class.其次,即使我在非空列表中获得 object 的 class 类型,我也不能使用它来实例化我的通用 class。

List<Object> list = (List<Object>) value;
if (list.size() > 0) {
    Class classType = list.get(0).getClass();

    ListConverterAdapter<classType> convert = new ListConverterAdapter<>(value);
}

Is there a way to instantiate a generic class with an object type of an empty or non-empty list in Java?有没有办法用 Java 中的空或非空列表的 object 类型实例化通用 class?

Is there a way to instantiate a generic class with an object type of an empty or non-empty list in Java?有没有办法用 Java 中的空或非空列表的 object 类型实例化通用 class?

No. At runtime, generic type information is no longer available, so List<T> is just List .不。在运行时,泛型类型信息不再可用,因此List<T>只是List

Here's a really simple example of a generic method.这是一个非常简单的泛型方法示例。 For some type <T> , it will return a List<T> which will be ArrayList<T> (really just ArrayList<> , without T ):对于某些类型<T> ,它将返回一个List<T> ,它将是ArrayList<T> (实际上只是ArrayList<> ,没有T ):

public static <T> List<T> run() {
    return new ArrayList<>();
}
  1. Invoke it like this, passing type info in the method invocation: GenericListExample.<String>run() (or GenericListExample.run() if you have a lefthand side of the statement with type info, like below)像这样调用它,在方法调用中传递类型信息: GenericListExample.<String>run() (或GenericListExample.run()如果语句的左侧有类型信息,如下所示)
  2. At compile time, you'll get a return type of this: List<String>在编译时,你会得到这样的返回类型: List<String>
  3. At runtime, the resulting list that comes back is just ArrayList .在运行时,返回的结果列表只是ArrayList Only at compile time is there any trace of the list containing String .只有在编译时才会有包含String的列表的任何痕迹。 After compilation, String is lost.编译后, String丢失。

Here's the entire class:这是整个 class:

public class GenericListExample {
    public static void main(String[] args) {
        List<String> list = GenericListExample.run();
        System.out.println("list.getClass(): " + list.getClass());
    }

    public static <T> List<T> run() {
        return new ArrayList<T>();
    }
}

And the output:和 output:

list.getClass(): class java.util.ArrayList

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM