简体   繁体   中英

How to set type of generic Java class at runtime?

I'm currently running into a problem with Java generics, where the type of the parameter T has to be determined at runtime.

Here's the class having a type parameter T:

public class Something<T> {
    T value;

    public Something(T value) {
          this.value = value;
    }

    ... //some other methods
}

And here's a method in another class, where an instance of Something should be created, but where the type of T depends on the dynamic type of the given object:

public void create(Object o) {

    //this is not working, since there is no getType() method         
    Something<o.getType()> s = new Something();
}

Is there a way to determine the dynamic type of o and pass it as type parameter to the Something -class? It is no option to make use of an if -cascade using instanceof , since there are many possibilities what o might be.

You can parametrize the create() method by K (just to avoid the confusion with T )

public <K> void create(K o) {
    Something<K> s = new Something<K>();
}

Then, when you invoke the create() method several times, here's what will happen:

create(Object o)  -> will parametrize Something by Object

create(Integer i) -> will instantiate Something by Integer

No you can't do that. Type information of generics are erased at compile time. The type that you use as type arguments, must be known to the compiler. Any expression that gives you the runtime type of a reference, will be evaluated at runtime only, when it's too late to set the type argument.

At run-time all generic parameters are erased and everything is Object .

At compile-time, the compiler checks if the methods used on an instance are those of the generic type of that instance.

ArrayList<o.getType()> s is meaningless because at compile-time javac needs to know if it should make an error or not, of the following:

s.get(0).intValue()

What if o is Integer and what if it's String ?

If you need to create the right generic type for an explicit small number of classes, you could use the instanceof operator ... something like

  if (o instanceof T) { x = new Something<T>();}
  else if (o instanceof String) {x = new Something<String>();}
  else if ....

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