Java 和泛型。 0不是一个数字吗?
我对这段代码缺少什么?
public class Zero<N extends Number> {
public N zero() {
return new Integer(0);
}
}
它说:
类型不匹配:无法从 Integer 转换为 N
谢谢!
更新 我已更改代码片段以使用整数。同样的事情也会发生。即使创建 Number
的匿名子类也会发生这种情况。难道是 Eclipse 出了问题吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
虽然 Integer 是 Number,但 Integer 可能与 N 不兼容,N 可以是 Number 的任何子类。
While an Integer is a Number, an Integer might not be compatible to N which can be any subclass of Number.
Integer 不保证是 N 的超类,因此您不能只将 Integer 值设置为 N 类型的对象。
这样想:如果有人将,该类实际上变为:
Zero
实例化为 < code>Zero这显然是无效的。
此外,你也不能这样做
return 0
,因为以同样的方式,编译器无法知道如何将其转换为 N。(编译器只能自动装箱它知道的类型,但通过使用泛型,您扩大了可用类型,还包括 Number 的自定义实现。)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>
asZero<Double>
, the class effectively becomes: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.)您的代码的问题在于,Java 需要能够确认函数的返回类型需要可转换为任何
N
的N extends Number
。因此,特别是,如果我用Double
实例化该类,就像You 中那样,就会遇到麻烦,因为
zero
表示它返回一个Double
但它实际上返回一个Integer
。类型错误表明编译器担心会发生类似的情况。据我所知,在 Java 中没有好的方法可以做到这一点,因为泛型是通过擦除来实现的;它不知道参数的类型是什么。
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 anyN
. So, in particular, if I were to instantiate the class with aDouble
, as inYou'd run into trouble, because
zero
says that it returns aDouble
but it actually returns anInteger
. 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.
0 是一个
int
,但由于您的方法返回一个对象,因此它将自动装箱为Integer
。问题在于,编译器不允许返回允许 Number 的任何子类 的Integer
。这只是因为您可以实例化您的类,在这种情况下,返回
Integer
将与预期的返回类型:Double
不兼容。0 is an
int
, but since your method returns an object, it will be autoboxed to anInteger
. The problem is that returning anInteger
where any subclass of Number is allowed is not allowed by the compiler. That's simply because you can instantiate your class asand in this case, returning
Integer
would not be compatible with the expected return type:Double
.当“N”扩展“Number”时,“N”成为“Number”的特化,并且您无法将基类的实例分配给其特化的引用变量(向上转换问题)。返回时这也适用。无法使用专门化类型返回基类实例。
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.