I have this interface
public interface Deserializable{
static <T> T deserialize(byte[] bytes) {
ReflectionDeserializer rd = new ReflectionDeserializer();
return rd.Deserialize(bytes);
}
}
There is a problem in that ReflectionDeserializer needs a class instance in its constructor. In this case, the class I want to pass in is the class of whatever class the implements
statement is on, so if I have public class Cat implements Deserializable
, I want the interface to put Cat.class
into the constructor.
How do I do this?
CodePudding user response:
I have run into this with persistence framework development before. You must pass the desired class into the static method.
static <T extends Deserializable> T deserialize(byte[] bytes, Class<T> targetType) {
ReflectionDeserializer rd = new ReflectionDeserializer();
return rd.Deserialize(bytes, targetType);
}
then your RefDes will have something like this
public <T extends Deserializable> T deserialize(byte[] bytes, Class<T> targetType) {
T target = targetType.newInstance();
populateFromBytes(target, bytes);
return target;
}
This is obviously not production quality code but the basic idea is how I've achieved this in the past. I might have minor details confused about the <>
syntax works but this is how I solved this problem for my current project.
CodePudding user response:
You mention "I need the method to be static to be overridable by implementing classes"
That is contradictory, static methods can't be overridden. However, I think what you want is to have it default
so that you provide a basic implementation, that can eventually be overridden by another implementation.
If you do that and you declare an abstract getClazz()
, you will be able to do as such:
public interface Deserializable<T extends Deserializable> {
default T deserialize(byte[] bytes) {
ReflectionDeserializer rd = new ReflectionDeserializer();
return rd.Deserialize(bytes, getClazz());
}
Class<T> getClazz();
}
... So if your class wants to override the deserialize
it will be able to do so, else it just returns its implementing class and lets the default implementation to do the job for it.
CodePudding user response:
You might want to consider a different approach to this problem, where Deserializable becomes a generic class holding type T, and has a method that deserializes and returns type T
public class Deserializable<T> {
public <T> T deserialize(byte[] bytes) {
ReflectionDeserializer rd = new ReflectionDeserializer(T.getClass());
return rd.Deserialize(bytes);
}
}
So whenever you'd want to deserialize your Cat object you'd just do
return new Deserializable<Cat>().deserialize(bytes);
You won't have to sort of redundantly state Cat twice like in this example
return Cat.deserialize(bytes, Cat.class)
CodePudding user response:
Use getClass()
. It is implemented on all Object
s and returns the concrete runtime Class
for the object it's called on.