java中基元类型的转换规则

在java中,

有整数类型( char / short / int / long / byte

有浮动类型( float / double

与C语言不同,有布尔类型( boolean ),而不是整数类型。

问题1)

是否有一个通用规则用于转换(根据JLS)会话,哪种类型可以转换为另一种类型? 出于常识,我知道,不允许使用整数和浮动类型转换为boolean

问题2)

请帮我理解下面输出的原因:

  /* * Casting rules for primitive types */ double aDoubleValue = 30000000000000000000.123438934; int doubleToInt = (int)aDoubleValue; //stores max value 2147483647, makes sense!! byte doubleToByte = (byte)aDoubleValue; //stores -1, why not 127? short doubleToShort = (short)aDoubleValue; // stores -1, why not 32767? long doubleToLong = (long)aDoubleValue; // stores 9223372036854775807, makes sense!! float doubleToFloat = (float)aDoubleValue; // stores 3.0E19, 3.0 x 10^19 max value of float char doubleToChar = (char)aDoubleValue; // what does this store? 

JLS 列表

对原始类型的19个特定转换称为扩展原始转换:

  • byte to short,int,long,float或double
  • 短,int,long,float或double
  • char到int,long,float或double
  • int到long,float或double
  • 长期浮动或加倍
  • 漂浮加倍

其他一切都需要一个明确的演员。 缩小比较复杂:

  • double to float使用标准IEEE 754舍入。
  • 整数值的最高有效位被剥离到目标类型的可用宽度。 这可能导致符号位出现,例如(byte)0xfff == (byte)-1 ;
  • 如果源类型是浮点且目标类型为long ,则通过向零舍入来转换该值。
  • 如果源类型是浮点并且目标类型是整数但不long ,则首先通过向零舍入将值转换为int 。 然后使用整数转换将结果int转换为目标类型。

例子:

 int doubleToInt = (int)aDoubleValue; 

根据舍入规则产生Integer.MAX_VALUE

 byte doubleToByte = (byte)aDoubleValue; 

首先转换为int ,产生Integer.MAX_VALUE ,然后将其转换为byteInteger.MAX_VALUE0x7fffffff ,因此字节值0xff-1

 short doubleToShort = (short)aDoubleValue; 

同样:转换为int ,产生Integer.MAX_VALUE0x7fffffffshort收益率0xffff ,即-1

棘手的事实是to- char转换。 char是一个16位的unicode字符,因此char doubleToChar = (char)aDoubleValue通过现在熟悉的规则为你提供'\uffff'

可以看出,浮点和整数缩小操作之间存在差异。 浮点运算执行实际舍入,而整数运算执行按位钳位。

整数语义可能是从Cinheritance的。至少浮点到积分缩小操作的第一步也是你所期望的。 第二个缩小的步骤,从double / float到short,byte和char可能看起来有点令人惊讶,但是如果你真的把浮动缩短,你可能应该仔细检查你知道你在做什么。