Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java6和Java7在自动取消装箱方面的差异_Java_Casting_Java 7_Unboxing - Fatal编程技术网

Java6和Java7在自动取消装箱方面的差异

Java6和Java7在自动取消装箱方面的差异,java,casting,java-7,unboxing,Java,Casting,Java 7,Unboxing,我注意到JavaSE6和JavaSE7之间在自动拆箱行为方面存在差异。我想知道为什么会这样,因为我找不到任何关于这两个版本之间这种行为变化的文档 下面是一个简单的例子: Object[] objs = new Object[2]; objs[0] = new Integer(5); int myInt = (int)objs[0]; 这可以使用JavaSE7中的javac进行很好的编译。但是,如果我向编译器提供“-source 1.6”参数,则最后一行会出现错误: inconvertible

我注意到JavaSE6和JavaSE7之间在自动拆箱行为方面存在差异。我想知道为什么会这样,因为我找不到任何关于这两个版本之间这种行为变化的文档

下面是一个简单的例子:

Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
这可以使用JavaSE7中的javac进行很好的编译。但是,如果我向编译器提供“-source 1.6”参数,则最后一行会出现错误:

inconvertible types
found   : java.lang.Object
required: int
我尝试下载JavaSE6以使用原生版本6编译器进行编译(没有任何源代码选项)。它同意并给出与上述相同的错误

那么是什么原因呢?从更多的实验来看,Java 6中的取消装箱似乎只能取消装箱(在编译时)显然是装箱类型的值。例如,这在两个版本中都适用:

Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
因此,在Java6和Java7之间,取消装箱功能似乎得到了增强,因此它可以一次性强制转换和取消装箱对象类型,而无需知道(在编译时)值是正确的装箱类型。然而,通过阅读Java语言规范或Java 7发布时编写的博客帖子,我看不到这方面的任何变化,所以我想知道变化是什么,这个“特性”叫什么

只是好奇:由于更改,可能会触发“错误”取消装箱:

Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];
这可以很好地编译,但在运行时会产生ClassCastException


这方面有什么参考吗?

你说得对;简而言之:

Object o = new Integer(1234);
int x = (int) o;
这在Java7中有效,但在Java6及以下版本中会出现编译错误。奇怪的是,这一特征并没有被显著地记录下来;例如,它没有被提及。这是一个有争议的问题,如果它是一个新的功能或一个错误修复(或一个新的错误?),请看一些。共识似乎指向了原始规范中的一个错误,这导致了Java 5/6上的一个稍微不正确/不一致的实现,该问题在7中得到了修复,因为它对于JSR 292(动态类型语言)的实现至关重要

Java自动装箱现在有了更多的陷阱和惊喜。比如说

Object obj = new Integer(1234);
long x = (long)obj;
将编译,但在运行时失败(使用
ClassCastException
)。相反,这将起作用:


long x=(long)(int)obj

中的语言似乎是相对于更新的,可能是为了澄清允许的转换

Java7JLS说

引用类型的表达式可以通过取消装箱转换进行转换为基元类型的强制转换,而不会出错

Java 5/6:

引用类型的值可以通过取消装箱转换转换转换为基元类型(§5.1.8)

Java 7 JLS还包含一个表(表5.1),其中包含从引用类型到原语的允许转换(该表不包括在Java 5/6 JLS中)。这将明确列出从对象到基本体的强制转换,作为使用取消装箱的缩小引用转换

原因解释如下:

底线:如果规范允许(Object)(int),那么它也必须允许(int)(Object)


有趣。一种新的自动包装材料。我认为您的示例可以更简单、更清晰地使用单个对象而不是数组<代码>整数obj=新整数(2);int x=(int)obj:在Java7上工作,在Java6上出现错误。您使用的是哪个JDK?它也可能与不同的供应商有关…@leonbloy:简化的好处是,我确实简化了一些(从我的原始代码),但不知何故停止得太早了@托马斯:我使用的是来自Oracle的最新JDK(每个版本)。这是我从不使用自动装箱的另一个原因。谢谢你的回答。然而,有一件事我不明白。这是对JLS及其附带实现的澄清(参见邮件讨论),但是为什么要这样做以适应JVM上的其他类型语言呢?毕竟,这是对语言的更改,而不是对VM的更改:VM的强制转换行为一如既往地工作,编译器使用现有的强制转换为整数并调用.intValue()的机制来实现此功能。那么,Java语言本身的这种变化如何帮助在VM上运行其他语言呢?我同意你的链接暗示了这一点,只是想知道。