如何获取类型为 Foo<T> (Foo<T>.class 不起作用的类实例



我想得到Foo<T>.class(恰好是Foo<T>,既不是T.class也不是Foo.class(

public class A extends B<C<D>>{
public A() {
super(C<D>.class); // not work
}
}

在StackOverflow上有一条通过注入构造函数来获得泛型类的指令,但我的情况并非如此,因为C<D> .class(例如List<String>.class(是语法错误。在这里,它似乎与语法有关,而不是与代码结构有关。

为了显示更多细节,更高级别的视图,原始代码如下,其在Spring框架中的HATEOAS模块:

public class CustomerGroupResourceAssembler extends ResourceAssemblerSupport<CustomerGroup, CustomerGroupResource>{
public CustomerGroupResourceAssembler() {
super(CustomerGroupController.class, CustomerGroupResource.class);
}
}
public class CustomerGroupResource extends ResourceSupport {
private CustomerGroup data;
}

但现在我想将CustomerGroupResource参数化为

public class Resource<T> extends ResourceSupport {
private T data;
}

然后

public class CustomerGroupResourceAssembler extends ResourceAssemblerSupport<CustomerGroup, Resource<CustomerGroup>>{
public CustomerGroupResourceAssembler() {
super(CustomerGroupController.class, Resource<CustomerGroup>.class); // not work here, even Resource.class
}
}

不幸的是,由于类型擦除,您试图做的事情是不可能的。

有关泛型类型的信息只能在编译时提供,而不能在运行时提供。这是在Java中使用泛型的最大限制之一。这样做的原因是为了保持向后兼容性。

请参阅Java泛型类型擦除:何时以及发生什么?

由于类型擦除,泛型只在编译时应用,在运行时没有任何意义。你能做的是

public class A extends B<C<D>>{
public A() {
super((Class<C<D>>) C.class);
}
}

但是,您将无法在运行时确定D的类型。但是,您可以使用反射来获得超类型。

public class Main {
public static abstract class B<X> {
protected B() {
Type type = getClass().getGenericSuperclass();
System.out.println(type);
}
}
public static class A extends B<Supplier<String>> {
public A() {
}
}
public static void main(String[] args) {
new A();
}
}

打印

Main.Main$B<java.util.function.Supplier<java.lang.String>>

EDIT对于您可以执行的特定示例。

import java.lang.reflect.Type;
public interface Main {
class ResourceSupport {
}
class CustomerGroup {
}
public class Resource<T> extends ResourceSupport {
private T data;
}
abstract class ResourceAssemblerSupport<C, R> {
protected ResourceAssemblerSupport() {
Type type = getClass().getGenericSuperclass();
System.out.println(type);
ParameterizedType pt = (ParameterizedType) type;
Type[] actualTypeArguments = pt.getActualTypeArguments();
Class first = (Class) actualTypeArguments[0];
ParameterizedType second = (ParameterizedType) actualTypeArguments[1];
System.out.println(pt.getRawType() + " <" + first + ", " + second + ">");
}
}
public class CustomerGroupResourceAssembler extends ResourceAssemblerSupport<CustomerGroup, Resource<CustomerGroup>>{
public CustomerGroupResourceAssembler() {
}
}
public static void main(String[] args) {
new CustomerGroupResourceAssembler();
}
}

打印

Main.Main$ResourceAssemblerSupport<Main$CustomerGroup, Main.Main$Resource<Main$CustomerGroup>>
class Main$ResourceAssemblerSupport <class Main$CustomerGroup, Main.Main$Resource<Main$CustomerGroup>>

一种通用的方法是使用辅助函数,但我认为在您的情况下不需要这样做。

public static void main(String[] args) {
System.out.println(new ClassType<List<String>>() {}.getType());
}
interface ClassType<T> {
default Type getType() {
ParameterizedType type = (ParameterizedType) getClass().getGenericInterfaces()[0];
return type.getActualTypeArguments()[0];
}
}

打印

java.util.List<java.lang.String>

相关内容

  • 没有找到相关文章

最新更新