Java generic type mismatch

I have an abstract class defined as:

public abstract class TCV<T extends MF> {
    public Map<String, MVR<T>> operation() {
        ...
    }
}

Main code:

TCV<? extends MF> o = new TCVConcrete();
Map<String, MVR< ? extends MF>> map = o.operation();

Eclipse Error:

Type mismatch: cannot convert from Map<String,MVR<capture#5-of ? extends MF>> to Map<String,MVR<? extends MF>>

EDIT

public class TCVConcrete extends TCV<MFV2> {
}

public class MFV2 extends MF {
}
+5
source share
4 answers

The main problem is that you cannot throw Box<Tiger>in Box<Cat>, why? You may think this,

A Box<Cat>can contain cats and tigers, but Box<Tiger>can only contain tigers. If you drop Box<Tiger>before Box<Cat>, then you throw BlackCatin Box<Tiger>:

Box<Cat> catBox = tigerBox;
catBox.throwHere(new BlackCat());

and then the tigerBox is damaged.

Let me reformulate your question as:

public abstract class Company<T extends Cat> {
    public Box<T> getFavBox() {
        // ...
    }
    public Set<Box<T>> getBoxes() {
        // ...
    }
}

Company<? extends Cat> o = new ETCatCompany();
Box<? extends Cat> boxes = o.getFavBox();        // ok
Set<Box<? extends Cat>> boxes = o.getBoxes();    // error

As you can see, it o.getFavBox()will work, but o.getBoxes()no, why?

- Cat Box<? extends Cat>, . Box<BlackCat> Set<Box<? extends Cat>>, a Set<Box<Tiger>>.

, :

Cat ^ Tiger => Cat
Box<Cat> ^ BigBox<Cat> => Box<Cat>
Box<Cat> ^ Box<Tiger> => Box<? extends Cat>
Box<Cat> ^ BigBox<Tiger>
    => (Box<Cat> ^ BigBox<Cat>) ^ (BigBox<Cat> ^ BigBox<Tiger>)
    => Box<Cat> ^ BigBox<? extends Cat>
    => Box<? extends Cat> ^ BigBox<? extends Cat>
    => Box<? extends Cat>

Set<Box<Cat>> ^ Set<BigBox<Cat>> => Set<? extends Box<Cat>>
Set<Box<Cat>> ^ Set<Box<Tiger>> => Set<? extends Box<? extends Cat>>
Set<Box<Cat>> ^ Set<BigBox<Tiger>> => Set<? extends Box<? extends Cat>>

? extends Cat ^ ? extends Tiger => ? extends Cat
Box<? extends Cat> ^ BigBox<? extends Cat> => Box<? extends Cat>
Box<? extends Cat> ^ Box<? extends Tiger> 
    => ? extends Box<? extends (? extends Cat)>
    => ? extends Box<? extends Cat>

Set<Box<? extends Cat>> ^ Set<BigBox<? extends Cat>> 
    => Set<? extends Box<? extends Cat>>

Set<Box<? extends Cat>> ^ Set<Box<? extends Tiger>>     // You are here.
    => Set<? extends Box<? extends Cat>>

Set<Box<? extends Cat>> ^ Set<BigBox<? extends Tiger>> 
    => Set<? extends Box<? extends Cat>>

, , (

Map<String, MVR<?1 extends MF>> x1 = o.operation();
Map<String, MVR<?2 extends MF>> x2 = o.operation();
...
Map<String, MVR<?n extends MF>> x2 = o.operation();

, ?

x1 ^ x2 ^ ... ^ xn
    => Map<String, MVR<?1 extends MF>> ^ Map<String, MVR<?2 extends MF>> ^ ...
    => Map<String, ? extends MVR<? extends MF>> ^ ...
    ...
    => Map<String, ? extends MVR<? extends MF>>

, , ...

+4

, , :

TCV<? extends MF> o = new TCVConcrete();
    ^^^^^^^^^^^^
Map<String, MVR< ? extends MF>> map = o.operation();
                ^^^^^^^^^^^^^^

, MF. .

.
:

public void <T extends MF> doSomething(){
    TCV<T> o = new TCVConcrete();
    Map<String, MVR<T>> map = o.operation();
}
+2

, ( ) , .

TCV<? extends MF> o = new TCVConcrete();
Map<String, MVR< ? extends MF>> map = o.operation();

Serializable , Serializable, , , . , MF , .

0

The problem is that you are using two? which basically say "MF or some unspecified subclass of MF." But this may mean two different subclasses of MF; and why the types for assignment do not match.

What you probably want is not to use wildcards at all. This should work:

TCV<MF> o = new TCVConcrete();
Map<String, MVR<MF>> map = o.operation();
0
source

All Articles