The generics interface signature is invalid

It was hard for me to think about the title for this, so forgive me.

I have an interface with the following methods:

public interface Algorithm<E,F> { public Set<? extends Algorithm<E,F>> map(int numPartitions); public F reduce(Set<? extends Algorithm<E,F>> partitions); } 

and a class that implements Algorithm with the following methods:

 public class LinearSearch<T> implements Algorithm<List<T>, Integer> { @Override public Set<LinearSearch<T>> map(int numPartitions) { return null; } @Override public Integer reduce(Set<LinearSearch<T>> partitions) { return null; } } 

Now it’s strange that Eclipse complains about the second method, reduce .

The method reduce(Set<LinearSearch<T>>) of type LinearSearch<T> must override or implement a supertype method.

This is despite the fact that the map method is wonderful. So where am I going wrong?

+7
java generics inheritance
source share
2 answers

Overriding methods and parameter types

In the reduce method, the parameter must be Set<? extends Algorithm<List<T>,Integer>> Set<? extends Algorithm<List<T>,Integer>> . Should it accept any Set<? extends Algorithm<List<T>,Integer>> Set<? extends Algorithm<List<T>,Integer>> , and not just a Set<LinearSearch<T>> . You cannot narrow down a parameter type by overriding a method.

JLS, section 8.4.8.1 details the signatures of overriding methods:

The instance method m1 declared in class C overrides the other instance method m2 declared in class A if all of them are true:

C is a subclass of A.

The signature m1 is a sub-sticker (§8.4.2) of the signature m2.

Or:

m2 is public, secure, or declared with default access in the same package as C, or

m1 redefines the method m3 (m3 different from m1, m3 different from m2) such that m3 redefines m2.

Here, “sub-heading” refers to matching parameter types after type erasure.

Overriding Methods and Return Types

But why does the map method work? Because Java allows the developer to narrow the return type of overriding methods in subclasses.

A different part of JLS, 8.4.5 , covers return types in overriding methods:

The return types may vary depending on the methods that override each other if the return types are reference types. The concept of a return-type substitution function supports covariant returns, that is, specialization of the return type to a subtype.

Declaring a method d1 with return type R1 is a return type-replaceable for another method d2 with return type R2, if and only if the following conditions are true:

If R1 is invalid, then R2 is invalid.

If R1 is a primitive type, then R2 is identical to R1.

If R1 is a reference type, then:

R1 is either a subtype of R2, or R1 can be converted to a subtype of R2 by unverified conversion (§5.1.9) or

R1 = | R2 |

(my accent)

+10
source share

The title of your method should be as follows:

 public Integer reduce(Set<? extends Algorithm<List<T>, Integer>> partitions) 

To override a method, you must use exactly the same types of parameters. If not, this is not considered the same method.

Note that the <E,F> types are a parameterized part of this header, so where Java gives you some freedom and allows you to use the types specified in the class definition.

+2
source share

All Articles