Java and generics. Isn't 0 a Number?

只谈情不闲聊 提交于 2020-06-25 09:13:29

问题


What is that I'm missing about this snippet of code?

public class Zero<N extends Number> {
  public N zero() {
    return new Integer(0);
  }
}

It says:

Type mismatch: cannot convert from Integer to N

Thanks!

Update I've changed the snippet to use an integer. Same thing happens. And it happens even when creating an anonymous subclass of Number. Could it be Eclipse that is faulty about this?


回答1:


While an Integer is a Number, an Integer might not be compatible to N which can be any subclass of Number.




回答2:


Integer is not guaranteed to be a superclass of N, so you can't just set an Integer value to an object of type N.

Think about it this way: If someone instantiates Zero<N> as Zero<Double>, the class effectively becomes:

public class Zero {
  public Double zero() {
    return new Integer(0);
  }
}

which is obviously not valid.

Furthermore, you can't do return 0 either, because in the same manner, there is no way for the compiler to know how to convert it into N. (The compiler can only autobox types it knows about, but by using generics you widened the available types to also include custom implementations of Number.)




回答3:


The problem with your code is that Java needs to be able to confirm that the return type of the function needs to be convertible to N extends Number for any N. So, in particular, if I were to instantiate the class with a Double, as in

Zero<Double> z = new Zero<Double>();
z.zero();

You'd run into trouble, because zero says that it returns a Double but it actually returns an Integer. The type error indicates that the compiler is concerned that something like this will happen.

To the best of my knowledge, there is no good way to do this in Java because generics are implemented via erasure; it can't know what the type of the argument is.




回答4:


0 is an int, but since your method returns an object, it will be autoboxed to an Integer. The problem is that returning an Integer where any subclass of Number is allowed is not allowed by the compiler. That's simply because you can instantiate your class as

new Zero<Double>()

and in this case, returning Integer would not be compatible with the expected return type: Double.




回答5:


When 'N' extends 'Number', 'N' becomes a specialization of 'Number' and you cannot assign an instance of a base class to a reference variable of it's specialization (upcast issue). This holds good while returning as well. A base class instance cannot be returned using the specialization type.



来源:https://stackoverflow.com/questions/6822921/java-and-generics-isnt-0-a-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!