java中基本类型的转换规则

时间:2015-06-11 09:04:31

标签: java casting

在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?

1 个答案:

答案 0 :(得分:19)

JLS lists

  

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

  • byte to short,int,long,float或double
  • 简称为int,long,float或double
  • char to int,long,float或double
  • int to long,float或double
  • 长期漂浮或加倍
  • 浮动加倍

其他一切都需要明确的演员。 Narrowing稍微复杂一点:

  • doublefloat使用标准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

实际上,棘手的事情是 - char转换。 char是一个16位的unicode字符,因此char doubleToChar = (char)aDoubleValue会根据现在熟悉的规则为您提供'\uffff'

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

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