请考虑以下代码:
public class Context {
private final Class<?> clazz;
private final String resource;
private final com.thirdparty.Context context;
public Context(final String resource, final Class<?> clazz) {
this.clazz = clazz;
this.resource = resource;
this.context = com.thirdparty.Context.newInstance(this.clazz);
}
public String marshall(final Object element) {
return this.context.marshall(element);
}
public Object unmarshall(final String element) {
return this.context.unmarshall(element);
}
}
Context context = new Context("request.xsd", Request.class);
// Marshall
Request request = new Request();
String xml = context.marshall(request);
// Unmarshall
Request roundTrip = Request.cast(context.unmarshall(xml));
我试图将它替换为Context类的泛型版本:
public class Context<T> {
private final Class<T> clazz;
private final String resource;
private final com.thirdparty.Context context;
public Context(final String resource) {
this.clazz = initHere(); // <== HOW ??
this.resource = resource;
this.context = com.thirdparty.Context.newInstance(this.clazz);
}
public String marshall(final T element) {
return this.context.marshall(element);
}
public T unmarshall(final String element) {
return this.clazz.cast(this.context.unmarshall(element));
}
}
Context<Request> context = new Context<>("request.xsd");
// Marshall
Request request = new Request();
String xml = context.marshall(request);
// Unmarshall
Request roundTrip = context.unmarshall(xml);
因此,我不会将.class作为参数传递给构造函数,而unmarshall方法会自动转换返回对象。
我需要知道传递给newInstance()方法的T类,并调用cast()方法。即T.class或T.getClass()。
在我的例子中,我试图在构造函数中初始化clazz成员,以便我可以在两个位置使用它。
我尝试了以下内容:
this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
但是getClass()。getGenericSuperclass()返回一个无法强制转换为ParameterizedType的对象。我不能使用任何第三方反射库,我需要坚持Jdk内部的标准机制。
答案 0 :(得分:4)
你不能这样做。 在您的情况下,通用类型T链接到您的实例。反射数据绑定到Class,而您的类不定义类型T.
您尝试使用的代码仅在您定义了设置T的类时才有效。
public class RequestContext extends Context<Request> {}
如果您使用此类的实例,那么您的代码应该可以正常工作。
答案 1 :(得分:3)
您无法在构造函数中执行此操作。如果你没有将Class
实例传递给构造函数,那么Context
类就无法处理它所处理的对象。
看看这里: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#Reflection
要确定类型和泛型类型,您需要一个对象。而且你没有物体。
是否有特定原因可以将Class
参数添加到构造函数中?如果有,你的例子并没有说清楚。
答案 2 :(得分:1)
实际上,您非常接近实际的解决方案......您的第一个代码版本非常接近您的需求:
自:
public Context(final String resource, final Class<?> clazz) {
//...
}
要:
public Context(final String resource, final Class<T> clazz) {
// ...
}
单个?
到T
更改就可以了。