2

很抱歉一直问基础知识,但我不明白这个简单的代码以及为什么第一个 print 语句通过编译器 ok 甚至打印为 true,但第二个 print 语句没有编译,给我一个“无法比较的类型”错误:

int in1 = 38;
Number Nn1 = in1;
System.out.println(in1 == Nn1);
System.out.println(Nn1 == in1);

我不期待这个结果,我认为 == 是对称的很标准?

我正在使用 javac 1.6.0_26 和 NetBeans 但得到相同的结果,第一个 println 语句编译没有问题,第二个没有..

4

5 回答 5

3

我相信,根据 Java 语言规范,任何一种方式都不应该编译。

首先重要的是要了解自动(取消)装箱仅适用于满足某些条件的表达式,并且仅适用于特定的包装类(整数、长整数等,而不是数字)。

现在,在 == 的情况下,当一个是 [primitive] 数字类型而另一个根据规则可转换为 [primitive] 数字类型 (JLS 15.12.1) 时,将特别应用自动拆箱。正如我们刚才所说,“根据规则”,Number 不能转换为数字原始类型

例如,不应将 int 转换为 Integer 然后进行参考比较:自动装箱未指定应用于 == 参考比较(JLS 15.21.3)。

因此,如果您的编译器允许编译引用的代码,则它不遵守 Java 语言规范

这种行为是有意义的,因为要执行数字比较,编译器需要知道两个操作数的实际特定类型才能执行数字提升。你可能认为你可以比较一个数字和一个整数,编译器应该只在数字上调用 .intValue() 。但这是不合适的,因为如果原始数字类型实际上是浮点数,那么正确的比较实际上是首先将整数转换为浮点数,而不是反过来。换句话说,对于 Number,编译器没有所有信息来正确执行与原语的数字比较

于 2012-11-18T01:27:38.947 回答
2

我的编译器(jdk1.7.0_03在 Windows 上)说这两行都不正确:

在此处输入图像描述

运算符 == 不能应用于intandjava.lang.Number

于 2012-11-18T00:34:36.543 回答
1

当您检查 anint和 an之间的相等性Integer时,会发生拆箱。事实上,编译器知道Integer操作数只包含int. 这就像一个线索。

然而,Number尽管由Integer(和其他人)实现,但过于通用,编译器需要做太多工作来提取原始原始类型以操作拆箱。

因此,编译器会抱怨它并期望您使用更细粒度的类型。

于 2012-11-18T00:57:49.443 回答
0

这两行都是编译错误。如果不是,则 NetBeans 中存在错误。

如果更改NumberInteger,则两行都会编译。

int in1 = 38;
Integer Nn1 = in1; // Changed to Integer
System.out.println(in1 == Nn1); // compiles
System.out.println(Nn1 == in1); // compiles
于 2012-11-18T00:48:39.993 回答
0

因为您将值引用类型值与原始值进行比较,所以它可以工作的唯一方法是自动取消装箱转换。但是这种类型的转换似乎没有在Java Language Specification中指定。

它可能不是对称的,因为它根本不可能。也许是编译器错误。

于 2012-11-18T01:04:50.873 回答