java - 如何从两个现有的类文字构造参数化类文字?

标签 java class generics literals

我想知道,是否以及如何能够实现以下目标,同时只能使用两个类文字变量:

Class<Foo<Bar>> getFoobar(){

    Class<Foo> fooClass = Foo.class;
    Class<Bar> barClass = Bar.class;

    // ... combine and return Class<Foo<Bar>>
}

...有限制,不可能按字面意思使用类型,但可以通过编程方式从类字面量变量中检索类型。

最佳答案

我们不能从字面上使用类型参数(正如您已经正确注意到的那样),即我们不能期望像 T.class 这样的表达式或new T()会起作用,因为我们不能“以编程方式”对泛型类型做太多事情。参数化类型在编译后会丢失其类型参数,因此对于以下 Foo<T> 实例类型:

Foo<String> foostr...;
Foo<Bar> foobar...;

我们将有相同的Class对象,即

foostr.getClass() == foobar.getClass() == Foo.class

因此,允许类文字如 Foo<String>.class 是没有意义的。或Foo<Bar>.class .

这就是编译类型中泛型类型的许多限制背后的原因:由于运行时没有有关类型参数的信息(由于类型删除),我们必须在编译时限制许多可能性.

在运行时使用泛型类型的一种可能性是提取有关类 Foo 的信息。及其类型参数 Bar作为ParameterizedType对象,例如

class Bar {
  ...
}

class Foo<T> {
  ...
}

class Foobar extends Foo<Bar> {

  ParameterizedType getFoobar() {
    return (ParameterizedType)getClass().getGenericSuperclass();
  }
}

...

Foobar foobar = new Foobar();
System.out.println(foobar.getFoobar().getRawType()); // Foo.class
System.out.println(foobar.getFoobar().getActualTypeArguments()[0]); // Bar.class

另一种方法基于第一种方法,但更容易实现,是使用 TypeReference (或创建您自己的类)从 FasterXML Jacson 项目捕获参数化类型:

class Foo<T> { ... }

class Bar { ... }

TypeReference typeReference = new TypeReference<Foo<Bar>>() {};  
ParameterizedTypeImpl parametrizedType = (ParameterizedTypeImpl) typeReference.getType();
System.out.println(parametrizedType.getTypeName()); // Foo<Bar>
System.out.println(parametrizedType.getRawType()); // Foo
System.out.println(parametrizedType.getActualTypeArguments()[0]); // Bar

看看 ParameterizedTypeImpl#toString() 的实现即可详细方法。

关于java - 如何从两个现有的类文字构造参数化类文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45507258/

相关文章:

typescript - 创建映射类型以 promise 返回值

java - 通配符类型在类型参数中提供了哪些灵活性?

java - P 作为泛型中的占位符

java - Hadoop 查找任务尝试的主机名

python - 为什么同一类的两个实例会发生相同的实例变量更改?

class - 如何在Scala构造函数中声明类型别名?

c++ - 如何合并两个类A和B以定义C++中抽象类的功能

Java Spring WS org.springframework.ws.soap.saaj.SaajSoapEnvelopeException : Could not access envelope

java - 过滤器 servlet 不适用于 Netbeans 中的 glassfish

java - Eratosthenes 筛法实现不检查某些数字