Java扩展转换

我正在准备Java 7认证,并有以下问题。

Byte b = 10编译好。 看起来编译器正在缩小int 10到byte 10然后装箱。 Byte b = new Byte(10)怎么会编译? 为什么编译器不能像第一种情况那样缩小int 10到byte 10?

为什么Long l = new Long(10)编译好但Long l = 10失败?

我不清楚它是如何工作的。 有人可以提供清楚的解释吗?

JLS的5.2节介绍了赋值上下文中允许的转换类型。

赋值上下文允许使用以下之一:

  • 身份转换(第5.1.1节)

  • 扩展的原始转换(第5.1.2节)

  • 扩大参考转换(第5.1.5节)

  • 一个拳击转换(第5.1.7节),可选地后跟一个加宽的引用转换

另外,

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

  • 如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。

  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:

    • 字节和常量表达式的值可在类型字节中表示。

    • Short和常量表达式的值可以在short类型中表示。

    • 字符和常量表达式的值可在char类型中表示。

Byte b = 10编译好,因为10是一个常量表达式,可以表示为一个byte

Byte b = new Byte(10)将不会编译,因为10是一个int文字,并且方法调用转换不会执行原始缩小转换。 要调用Byte构造函数进行编译,可以显式地将10byte

 Byte b = new Byte( (byte) 10); 

Long l = new Long(10)编译因为方法调用转换将执行原始扩展转换,包括从intlong

Long l = 10将无法编译,因为Java将不会特别允许扩展转换,然后进行装箱转换, 正如我在最近的回答中所讨论的那样 。 要使其编译,您可以使用long文字,因此只需要装箱。

 Long l = 10L; 

基本规则是:

  • 你不能一步转换和自动转换( JLS 5.1.7定义装箱转换,它不包括转换和自动转换类型转换,所以不允许)
  • 你不能隐含地缩小类型

这些规则解释了为什么Long l = 10不起作用,以及new Byte(10) 。 第一个要求将int literal 10扩展为long ,然后将其装箱,这是不允许的。 (更准确地说,它需要从int转换为Long ,JLS 5.1.7没有定义。)第二个要求将int literal 10隐式缩小为一个byte ,这是不允许的。

但该规则有例外。 JLS 5.2明确允许Byte b = 10

此外,如果表达式是byteshortcharint类型的常量表达式(第15.28节):

  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:
    • Byte和常量表达式的值可在类型byte表示。

(省略了一些不相关的部分)

最后, new Long(10)可以工作,因为int literal 10 可以自动扩展到10L长。

字节构造函数采用字节类型或字符串类型。 看到这个

Long的构造函数需要很长时间才能成为一个参数。 由于long可以采用整数,因此它允许在构造函数中使用。

10是一个整数文字,你必须向下传播它以将它传递给Byte构造函数。 不幸的是,没有字节文字语法来删除演员表。

为什么Long l = new Long(10)编译好但Long l = 10失败?

因为10,一个整数,可以适合长而没有问题。 整数不能放入一个字节,因此在这种情况下需要强制转换(扩展转换)。

这个演员阵容也是编译时间,因为它也是一个扩大的转换。 查看JLS中的5.1.5节 :

扩展引用转换在运行时从不需要特殊操作,因此不会在运行时抛出exception。 它们只是简单地将引用视为具有某种其他类型,其方式可以在编译时certificate是正确的。

我想我有一个解决你问题的方法……

 //constructor for Byte class Byte(byte value){ } 

java类型转换有两个规则

  1. 两种类型都兼容
  2. 目标类型大于源类型

现在在你的情况下,你试图将int转换为字节,这是违反我们的第二条规则….但下面是解决方案

 Byte b = new Byte((byte)10); 

现在让我们谈谈你的第二个问题……

  Long x = 10;//incompatible type 

这是autoboxing的问题……现在我们都知道autoboxing自动将原始类型转换为它的包装类..但是在自动装箱的情况下转换不会发生…. int转换为整数 字节转换为字节 。现在,当你将int基本类型赋给Long时,它会给你错误的类型…….解决方案

 Long x = (long) 10;//works fine....