java - 如何获取 Foo 类型的类实例(富.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
}
}
解决方案
由于类型擦除,泛型仅适用于编译时,在运行时没有任何意义。你能做的是
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>>
编辑对于您的具体示例,您可以这样做。
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>
推荐阅读
- c# - 在 foreach 循环中未修改值
- android - Android背景填充一半屏幕
- macos - 如何将我的安装程序版本从 packagesbuild 转换为 productbuild?
- c++ - 常量 X 不是类型名称,这里 x 是 KING
- oracle - 如何在 ADF 中单击按钮时更改表格的属性值
- winapi - C# 挂钩以获取原始鼠标/键事件
- dart - 如何在颤动中使用网格布局制作这种类型的布局
- python - 华生助手日文日志获取方法
- javascript - 使用 Javascript ASP.NET 将值从 Modal1 传递到另一个 Modal2
- gitlab-ci - Gitlab-CI 是否支持 only:refs 内的变量扩展?