Java泛型类型不匹配

Syd*_*ney 5 java generics

我有一个抽象类定义为:

public abstract class TCV<T extends MF> {
    public Map<String, MVR<T>> operation() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

主要代码:

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

日食错误:

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

编辑

public class TCVConcrete extends TCV<MFV2> {
}

public class MFV2 extends MF {
}
Run Code Online (Sandbox Code Playgroud)

Xiè*_*léi 5

主要问题是因为你不能投射Box<Tiger>Box<Cat>,为什么?你可以认为它是,

ABox<Cat>可以包含猫和老虎,但 aBox<Tiger>只能包含老虎。如果您将 a 投射Box<Tiger>Box<Cat>,然后将 a 投射BlackCatBox<Tiger>

Box<Cat> catBox = tigerBox;
catBox.throwHere(new BlackCat());
Run Code Online (Sandbox Code Playgroud)

然后,tigerBox 就损坏了。

让我将你的问题改写为:

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
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,o.getFavBox()可以工作但o.getBoxes()不行,为什么?

因为,您不能将任何具体的 Cat 放入 中Box<? extends Cat>,这可能会损坏未知的盒子。但是,您可以将 aBox<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>>
Run Code Online (Sandbox Code Playgroud)

或者更有可能在您的情况下,进行多次操作()调用:

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();
Run Code Online (Sandbox Code Playgroud)

那么,所有的共同类型是什么?

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>>
Run Code Online (Sandbox Code Playgroud)

嗯,两个通配符肯定没什么问题,是数学归纳法……