I have a generic method which has generic type to return. I would like to call it properly in order to return compilation error in case the returning type, I use it for, does not comply the boundaries this way avoiding run-time errors (vs compilation) and use all the power of Java generic types.
public <T extends IDeserializable> T restoreObject(byte[] objectArray) {
T object = T.getDeserialized(objectArray);
return object;
}
However, calling it this way
File ret = restoreObject(new byte[] {1,2,3});
would not produce compilation error and therefore the error will be generated at runtime only. The File type does not implement IDeserializable, however java does not generate compilation error.
public interface IDeserializable {
public static <T> T getDeserialized(byte[] data) {
return null;
}
}
There are several problems here:
getDeserialized
is an instance method, not a static method, so you can't do T.getDeserialized(objectArray)
.T
just like that.T
will be inferred as the type of whatever you're assigning the result to. You need to give restoreObject
an argument of type T
so that the compiler can infer T
and so that you can call the getDeserialized
method:
public <T extends IDeserializable> T restoreObject(byte[] objectArray, T t) {
return t.getDeserialized(objectArray);
}
However, I suspect you meant getDeserialized
to be a static method. Unfortunately, you cannot do that, because static methods don't get overriden. You can, however, make restoreObject
take a Function
parameter:
public <T extends IDeserializable> T restoreObject(byte[] objectArray, Function<byte[], T> deserialize) {
return deserialize.apply(objectArray);
}
Then you can use a lambda or method reference for the deserialize
argument.
You can also use Serializable
, but @daniu has pointed out that Serializable
will be removed some time in the future and is not a good idea. There are tons of libraries out there already so you don't have to handle the serialization/deserialization yourself. Here are some alternatives for serialization in Java. Java also has its own XML API if you don't want to use outside libraries.
This gets obvious really fast, if you could imagine a theoretical type Weirdo
that could do:
class Weird extends File implements IDeserializable
And then:
static <T> T getDeserialized(byte[] data) {
return new Weirdo();
}
Or even simpler (since the cast to a type parameter can't be enforced):
static <T> T getDeserialized(byte[] data) {
return (T) "";
}
You can see that the problem is in your getDeserialized
to begin with and callers have to trust you. But if you think why static methods exist in interfaces (their main purpose is to return an instance of the interface), then you are abusing these methods. What is the point in making it static
if no one can override it? You might want to rethink what you are trying to do.
But anyway, if you replace that with a class
- you will get a compile time error (I will let you figure out why, though):
public static class IDeserializable {
static <T> T getDeserialized(byte[] data) {
return ...;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.