Java泛型返回类型方法派生为对象返回类型

时间:2018-05-09 05:49:41

标签: java generics type-erasure

我遇到了这个有线问题。

class Foo<R, C> {

    public C fooMethod() {
        Bar bar = new Bar();
        Map<String, String> m = new HashMap<>();
        return bar.barMethod(m);
    }
}

class Bar {
    public <T> T barMethod(Map<String, String> m) {
        Object barObj = null;
        ...
        return (T) barObj;
    }
}

如果我将m声明为原始类型Map m = new Map(),则会出现编译错误:

  

不兼容的类型:对象无法转换为C,其中C是a   型可变。

但如果m是上面声明的类型化对象,那么编译错误就消失了。

我无法弄清楚为什么参数会为编译器做出不同的决定,以确定返回类型是什么。对我来说,编译器不应该认为Bar类示例中的泛型类型T在任何情况下都是Object类型。有人能说出我错了吗? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

Map m = new HashMap<>();
return bar.barMethod(m); //error

引发错误,因为barMethod(Map<String, String> m)特别需要Map<String, String>。你可以做一些事情来使编译错误变得更加糟糕。

  • barMethod参数更改为原始类型。

    public <T> T barMethod(Map m) {...}
    

    或者

  • 在方法C

    中将投放返回值转换为fooMethod
    return (C) bar.barMethod(m);
    

    或者

  • 将方法fooMethod的返回类型更改为对象

    public Object fooMethod()
    

答案 1 :(得分:0)

我在规范中找不到任何来源,但基本上,因为您使用原始类型Map代替通用Map<String, String>,Java转换所有类型擦除Map的通用参数(不仅仅是Object)。方法签名有效地变为:

public Object barMethod(Map<Object, Object> m)

由于barMethod返回ObjectObject不一定是C(由fooMethod返回),因此类型不兼容。这就是导致编译器错误的原因。