Java Generics: Warning requires an uncontrolled act to match <InterfaceName>

I have an interface

interface x {
    A getValue();
}

and implementation

class y implements x {
    public B getValue() { return new B();}
}

B is a subclass of A. This works because of covariant redefinition, I think.

But if I rewrote the interface as

interface x{
    <T extends A> T getValue();
}

I get a warning in the implementation that

Warning requires an uncontrolled cast to match A.getValue ()

What is the difference between the two versions of the interface? I thought they were the same.

+5
source share
4 answers

The second version of the interface is incorrect. It says that it getValuewill return any subclass that you request - the type of the return value will be inferred based on the expression in the left hand.

, x ( obj), :

x obj = ...;
B b = obj.getValue();

, , C, A, :

C c = obj.getValue();

, T , , .

+4

, <T extends A>, , A, A, :

 A getValue();

, , A, A.

EDIT: , B A, A. .

B A C A, B

:

public void someMethod(x value) {
    C c = x.getValue();
}

, , , , , , - ).

, y ?

, B C. , .

+3

, , . T , - ? T:

interface x <T extends A> {
    T getValue()
}

, , , :

interface x {
    <T extends A> T getValue(T someArgument)
}

interface x {
    <T extends A> T getValue(Class<T> someArgument)
}

Then there would be no warning.

edit: see waxwing post for an explanation of why you should not use generics for this particular problem. I just show how generics will be used.

+1
source

So, to build on two answers from AlbertoPL and Yishai, try the following:

class y implements x {
    A getValue(){ return new B();}
}

B extends A, so fine. The caller does not need to know which subclass of A is returning, only that it extends A. So, we go :)

0
source

All Articles