Consider the following code:
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));
I am trying to replace it with a generics version of the Context class:
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);
Thus I do not pass a .class as a parameter to the constructor, and the unmarshall method automatically casts the return object.
I need to know the Class of T to pass to the newInstance() method, and to invoke the cast() method. i.e. T.class or T.getClass().
In my example I am attempting to initialise the clazz member, during the constructor, so that I can use it in both locations.
I have tried the following:
this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
However getClass().getGenericSuperclass() returns an object which cannot be cast into a ParameterizedType. I cannot use any third party reflection libraries, I need to stick to the standard mechanisms inside the Jdk.
You can get around the superfluous reference by providing a generic static factory method. Something like public static <T> GenericClass<T> of(Class<T> type) {...} and then call it as such: GenericClass<String> var = GenericClass. of(String. class) .
The type parameter section of a generic class can have one or more type parameters separated by commas. These classes are known as parameterized classes or parameterized types because they accept one or more parameters.
The Java Object getClass() method returns the class name of the object. The syntax of the getClass() method is: object.getClass()
You can't do that. In your case, the Generic Type T is linked to your instance. Reflection data are bound to Class, and your class doesn't define the type T.
The code you are trying to use works only if you define a class where T is set up.
public class RequestContext extends Context<Request> {}
If you use an instance of this class, then your code should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With