简体   繁体   English

如何在java中运行时设置ArrayList的泛型类型?

[英]How to set the generic type of an ArrayList at runtime in java?

Ok, so I am setting up my own XML serialization (I know there are others out there, even some built in to Java, but I am doing it myself to learn and because it is so awesome to work with). 好的,所以我正在建立自己的XML序列化(我知道还有其他的,甚至是一些内置于Java的,但我自己也在学习,因为它非常棒)。 I have serialization down. 我有序列化了。 I am currently on the deserialization (reading in the XML file and assembling objects based on the data in the file) and I am running into problems with setting generic types. 我目前正在进行反序列化(读取XML文件并根据文件中的数据组装对象),我遇到了设置泛型类型的问题。 After extensive research, I figured out how to get the generic types of a class so I could write them when serializing, but I have no clue how to do this: 经过广泛的研究,我想出了如何获取类的泛型类型,以便我可以在序列化时编写它们,但我不知道如何做到这一点:

Class c = Class.forName(string);
ArrayList<c> list = new ArrayList<c>();

I have seen a few answers for this in C#, but obviously C# is a bit more versatile than Java, and there is no way that I can replicate the solutions there in Java. 我在C#中看到了一些这方面的答案,但显然C#比Java更通用,我无法用Java复制那里的解决方案。 Can this even be done, even with reflection? 甚至可以用反射来完成这项工作吗?

You can't. 你不能。

Generics in Java are simply compile-time syntactic sugar. Java中的泛型只是编译时语法糖。 It makes it so you don't have to cast everything to and from Object like we did in the old days when dinosaurs roamed the JVM, and gives you some compile-time type checking. 它使得你不必像过去那样在恐龙漫游JVM的过程中向ObjectObject投射所有内容,并为你提供一些编译时类型检查。

Edit to add: There is some metadata preserved at runtime that you can get at via reflection to inspect a generic class, but nothing like what you want. 编辑添加:在运行时保留了一些元数据,您可以通过反射来检查泛型类,但不是您想要的。

You cannot set generic type at runtime. 您不能在运行时设置泛型类型。 All generic type information is erased at compile time. 在编译时擦除所有泛型类型信息。

See below articles to understand type erasure: 请参阅以下文章以了解类型擦除:

Type Erasure StackOverflow 键入Erasure StackOverflow

Type Erasure Tutorial 键入Erasure教程

else what you can do (if you have limited number of classes).. you make a check of object by using 'instance of' operator and depending upon that place that in your arraylist 否则你可以做什么(如果你的课程数量有限)..你通过使用'instance of'操作符并根据你的arraylist中的那个地方来检查对象

if(obj instance of abc)
    ArrayList<abc> al = new ArrayList<abc>();

you can have nested if else or switch 你可以嵌套if else或switch

No, Generics is only at compile time, only for compile-time type checking, to allow you to avoid casts that can be proven safe at compile-time. 不,Generics仅在编译时,仅用于编译时类型检查,以允许您避免在编译时被证明是安全的强制转换。

Think about it. 想一想。 If you could do what you want, it would be completely useless. 如果你能做你想做的事,那就完全没用了。 The whole point of having ArrayList<String> , say, is that when you get an element out of it, the compiler can infer at compile-time that it has type String , and so it allows you to assign it to type String in the code without a cast. 比如说,使用ArrayList<String>是,当你从中获取一个元素时,编译器可以在编译时推断它有类型String ,因此它允许你将它分配给String中的String类型。没有演员表的代码。 Also, if you try to add an element into it, the compiler can check at compile-time that it is of type String , or else not let you do it. 此外,如果您尝试向其中添加元素,编译器可以在编译时检查它是否为String类型,否则不允许您这样做。

But you want a type parameter that is not known at compile-time. 但是您需要一个在编译时未知的类型参数。 Thus when you get an element out of it, the compiler doesn't know anything about its type, so you can only assign it to type Object . 因此,当您从中获取元素时,编译器对其类型一无所知,因此您只能将其指定为Object类型。 And when you try to put something into it, the compiler doesn't know what type it's supposed to allow, so it must allow all types? 当你试图把东西放进去的时候,编译器不知道它应该允许什么类型,所以它必须允许所有类型? Then there is no point to the generics. 那么仿制药就没有意义了。

Thus, you should just use the upper bound type as the type parameter. 因此,您应该只使用上限类型作为类型参数。 Like ArrayList<Object> list = new ArrayList<Object>(); ArrayList<Object> list = new ArrayList<Object>();

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

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