方法参数的泛型类型转换不可能,为什么?

时间:2017-03-13 12:47:35

标签: java generics

我是仿制药的新手,当我试图在一个小程序中使用它们时遇到了以下问题,我将尝试提供必要的信息。

我会尝试只提供必要但如果遗漏任何内容,请告诉我,我会提供所需的信息。

首先是以下界面:

1: public interface IPrice<T extends IPrice<T>> {
2:     void setPriceToZero();
3:     T addPrice(T price);
4:     T subtractPrice(T price);
5:     T multiplyPriceByFactor(int factor);
6:     String priceToString();
7: }

它由BnSPrice类实现;这里可能是必要的一部分:

1: public class BnSPrice implements IPrice<BnSPrice> {
2:     public BnSPrice subtractPrice(BnSPrice price) {...}
2: }

现在是不会编译的部分,我真的不明白:

1: public static void main(String[] args){
2:     [...]
3:     IPrice<? extends BnSPrice> test = new BnSPrice(5);
4:     test.subtractPrice(new BnSPrice(5));
5:     [...]
6: }

我得到的是

  

“错误:(27,28)java:不兼容的类型:main.bnsCalculatorModel.BnSPrice&gt;无法转换为捕获#1的扩展&gt; main.bnsCalculatorModel.BnSPrice”

在我称之为减法方法的行中。

为什么会发生这种情况,如何纠正这个问题,以便我仍然可以编程到界面?

(我的目标是,将来以其他“各种价格”扩展我的计划应该很容易。)

2 个答案:

答案 0 :(得分:6)

首先,让我们看看如何使这项工作:

IPrice<BnSPrice> test = new BnSPrice(5);
test.subtractPrice(new BnSPrice(5));

好的,删除通配符? extends ...就行了。为什么呢?

您需要了解通用通配符的概念。 <? extends BnPrice>表示这可以是BnPrice的子类的任何类型。目前,你没有,但让我们创建一个,以证明我的观点。

class MyPrice extends BnPrice {}

请注意,您无法将BnPrice对象分配给MyPrice类型的变量。

大!现在我们有test个对象。我们来看看subtractPrice类型中IPrice<? extends BnPrice>的定义方式:

T subtractPrice(T price);

自您撰写<? extends BnPrice> T后,可以是BnPrice的任何子类,即BnPriceMyPrice。如果TBnPrice,则会编译:

test.subtractPrice(new BnSPrice(5));

您正在将BnPrice传递给期望BnPrice的方法。都好。 但是T不一定必须是BnPrice。它也可以是MyPrice!如果是MyPrice怎么办?然后上面的行无法编译,因为您无法将BnPrice传递给MyPrice参数。

由于参数可以是任何扩展BnPrice的类型,因此您无法将BnPrice传递给它。

答案 1 :(得分:0)

因为测试类型是IPrice<? extends BnSPrice>,所以减法参数的预期类型是? extends BnSPrice,而不是BnSPrice。

这将编译:

BnSPrice test = new BnSPrice(5);
test.subtractPrice(new BnSPrice(5));