Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 generics compatibility

Tags:

java

java-8

I have the following method declaration:

public <T extends Serializable,
        Method extends BotApiMethod<T>,
        Callback extends SentCallback<T>>
    void executeAsync(Method method, Callback callback)

When I use it in the following way:

executeAsync(editMessage, new SentCallback() {

it works fine but shows the type safety warnings.

But when I provide the generic type to the SentCallback, like:

executeAsync(editMessage, new SentCallback<Message>()

it show the following compilation error:

The method executeAsync(Method, Callback) in the type AbsSender is not applicable for the arguments (EditMessageReplyMarkup, new SentCallback(){})

Why I can't use it with new SentCallback<Message> ?

like image 493
alexanoid Avatar asked Jun 09 '18 22:06

alexanoid


People also ask

Is Java 11 fully backward compatible with Java 8?

Java 11 is backwards compatible with Java 8. So you can swiftly change from Java 8 to 11.

Is Java 8 backwards compatible?

Backward Compatibility Java versions are expected to be binary backwards-compatible. For example, JDK 8 can run code compiled by JDK 7 or JDK 6. It is common to see applications leverage this backwards compatibility by using components built by different Java version.

Is Java 8 and Java 1.8 the same?

In short – 8 is product version number and 1.8 is the developer version number (or internal version number). The product is the same, JDK 8, anyways.


1 Answers

First, let us take a look at the inferred type of T. Given the types of your parameters (BotApiMethod<Serializable> and SentCallback<Message>), T should be either inferred to Serializable or to Message. But at the same time the current implementation forces that both parameters have the exact same T. This is the reason the presented attempt does not work. Keep in mind that in Java, generics are invariant.

If one cannot change the given definition of executeAsync(...), the problem is not solvable with the parameters provided.

If parameter T is essential and the design allows for different generic parameters of Method and Callback, which only need to have a common supertype T, the definition of executeAsync(...) could be changed to:

public <T extends Serializable,
        Method extends BotApiMethod<? extends T>,
        Callback extends SentCallback<? extends T>>
    void executeAsync(Method method, Callback callback)

If parameter T is not essential it could be dropped completely, leading to the following definition of executeAsync(...):

public <Method extends BotApiMethod<? extends Serializable>,
        Callback extends SentCallback<? extends Serializable>>
    void executeAsync(Method method, Callback callback)
like image 68
Turing85 Avatar answered Oct 12 '22 00:10

Turing85