泛型类型和赋值问题

时间:2013-05-29 21:39:34

标签: java oop generics

我知道,每个泛型类型变量都替换为上限,这是从方法“类型参数部分”的开头的通用定义中确定的。

这是来自Deitel的书

  

实际上,所有类型的参数都被所谓的鞋面所取代   type参数的绑定,在type-parameter中指定   部分。

据此,该子代码必须为真

public  static <E extends Number> void A(  )
 {

E x=  new Double(2.2);

 }

但是编译器告诉我 E x = new Double(2.2); 中的编译错误,虽然这必须是真的,因为 double是数字

我知道如何通过施法来处理和解决问题,但我想问为什么会发生这种情况?

4 个答案:

答案 0 :(得分:6)

仅因为E是一个数字并不意味着它是Double

想想这样,如果E是整数,那该怎么办? E仍然是一个数字,但现在您将Double分配给整数。因此,铸造行为是一致的,Number可以是各种不同的类型,因此E.

编辑操作:Deitel语句仍然正确,如果您将Double分配给一个数字或一个对象,那么您将不需要转换。但在这种情况下,E不分配“向上”,它在两个可能的不同数字类型之间“横向”分配。如果E是Short或Integer,在这些情况下你不希望能够在没有强制转换的情况下为它们分配Double。

答案 1 :(得分:3)

当您指定E extends Number时,这意味着ENumberNumber本身的任何子类型。例如,E可以是IntegerLongDouble等。这就是您的代码无法编译的原因 - 如果E为{{1}例如,能够将Integer分配给Double类型的变量是错误的。

答案 2 :(得分:1)

然而这完美无缺!

public static <E extends Number> void A() {
  E x = (E)new Double(2.2);
}

对你的编译器很好,这对你很好。你需要做的就是告诉它你的意思。

而且 - 当然 - 因为我们实际上是在骗我们的编译器现在它让我们做了可怕的事情,如:

public class Test {
  public static <E extends Number> E makeOne() {
    E x = (E) new Double(2.2);
    return x;
  }

  // Some real compiler abuse.
  public void test() {
    Integer one = Test.<Integer>makeOne();
    Double two = Test.<Double>makeOne();
    Number three = Test.<Double>makeOne();
  }

}

对于我们在家的读者......这是如何使用泛型。

哦 - 顺便说一下,你看到你的问题的原因是你没有选择不匹配的类型。

你的问题是一个概念问题。 Generic子句<E extends Number>中传递的类型是您最终决定使用的类型的占位符。您不只是在推迟决定使用哪种类型。您承诺只使用与该子句匹配的类型,如果您违反该承诺,编译器必须警告您。

您的代码不被接受的原因是因为您正在这样做,您违背了承诺。您是说虽然来电者可以使用任何 Number,但您会使用特定的NumberDouble),因此您违反了规定的规则你自己和编译器告诉你。

答案 3 :(得分:0)

你所知道的是E延伸Number。类型E可以是Integer,它也是Number的子类。

new Double(2.2)分配给名为x的名为Integer的变量没有多大意义。