简体   繁体   English

如何在运行时设置通用Java类的类型?

[英]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. 我目前遇到Java泛型的问题,其中必须在运行时确定参数T的类型。

Here's the class having a type parameter T: 这是具有类型参数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: 这是另一个类中的方法,应在其中创建Something的实例,但其中T的类型取决于给定对象的动态类型:

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? 有没有一种方法可以确定o的动态类型并将其作为类型参数传递给Something -class? It is no option to make use of an if -cascade using instanceof , since there are many possibilities what o might be. 不能通过instanceof使用if -cascade,因为o可能有很多可能性。

You can parametrize the create() method by K (just to avoid the confusion with T ) 您可以用K参数化create()方法(只是为了避免与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()方法时,将发生以下情况:

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. 任何为您提供引用的运行时类型的表达式,只有在为时已晚而无法设置type参数时,才会在运行时求值。

At run-time all generic parameters are erased and everything is Object . 在运行时,所有通用参数都将被擦除,并且所有Object都是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: ArrayList<o.getType()> s是没有意义的,因为在编译时,javac需要知道是否应该对以下内容进行错误处理:

s.get(0).intValue()

What if o is Integer and what if it's String ? 如果oInteger怎么办,如果它是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 如果您需要为少量的类创建正确的泛型类型,则可以使用instanceof运算符...类似

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

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

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