Java interface generic method implementation problems

53 Views Asked by At

I have an interface IHuman.java

public interface IHuman<K, V> {
    V execute(K request) throws Exception;
}

and I have an implementation, MaleHuman.java

public class MaleHuman implements IHuman<String, String> {
    @Override
    public String execute(String request) throws Exception {
        return ...;
    }
}

According to the generic method in the above interface, the sub-class implementation will not report an error.

However, if the method itself declares the type variables <K, V>, this implementation will no longer be valid:

Interface IHuman changed:

public interface IHuman {
    <K, V> V execute(K request) throws Exception;
}

If I implement the interface the same as before, it will cause a compilation error:

public class MaleHuman implements IHuman {
    @Override
    public String execute(String request) throws Exception {
        return ...;
    }
}

Generic types <K,V> can no longer be set to String.

With the interface changed, what would be the correct way to write the MaleHuman implementation class?

1

There are 1 best solutions below

0
entpnerd On

TL;DR Your method isn't compiling in the second case because in the second case, the method is a "generic method", without letting the calling code set the type parameters. For reference, see the Java Tutorial pertaining to Generic Methods.

Now for the more detailed version of the answer...

In the first example of the question, the type parameters are on the interface, IHuman, and are populated by the implementing class, MaleHuman. The method is not generic in the first example, only the interface is. The implementing class sets the type parameters, since they are on the type, and not the method.

In the second example, the interface and implementing class are no longer generic. But, the declared method, execute() is now a generic method. This generic method doesn't just have a parameter, request. Instead, it has two new "type parameters", K and V. None of these parameters are meant to be set by the implementation of the method. These parameters are meant to be set by the caller. Setting the type parameters K and V in the implementation is analogous to writing a version of the method where the method, itself, sets the request parameter. Parameters are variable by nature. By setting the type parameters as is the case in the second version of the implementation, they are no longer parameters, as they are no longer variables set by the caller, even though IHuman declares them to be parameters.

Note that the key difference between the first implementation and the second implementation is that for the first implementation, the implementing class is meant to set the type parameters, whereas for the second implementation, the calling code is meant to set the type parameters.

I hope that helps.