简体   繁体   中英

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). 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. 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. Can this even be done, even with reflection?

You can't.

Generics in Java are simply compile-time syntactic sugar. 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.

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

Type Erasure Tutorial

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

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

you can have nested if else or 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.

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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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