楔子

  • java 中整数默认int(4个字节)类型,小数默认double(8 个字节)类型
  • 类型转换优先级
    • (byte, short, char)<int<long<float<double
      • 为什么float 4 个字节,long8 个字节,还是long转float
        • 浮点数在内存中存储有关,能表示的数多于long
  • 类型提升规则:
    • byte、short和char类型的值都被提升为int类型;
    • 如果有一个操作数是long类型,就将整个表达式提升为long类型;
    • 如果有一个操作数是float类型,就将整个表达式提升为float类型;
    • 如果任何一个操作数为double类型,结果将为double类型。

正文

  1. 如果在赋值时等号右边是数值,如果数值没有超过等号左边(short,byte,char),在底层就会补一个强转,如果是大于 int 那么数值会自动类型提升

    1. byte a = 20;//正确 既然java中整数默认为 Int 类型,为什么不需要强制转换
  2. 如果右边全是常量,javac 会将若干个常量表达式计算得到结果,再看数值有没有超过左边,叫做编译器的常量优化

    1. byte a = 1 + 3;//正确
  3. 如果等号右边是带有变量运算,要看类型转换优先级,左边大,不用管,右边大则需要强转

    1. 变量运算不管是 byte + short 等(可能会考虑类型是不是提升为short),只要是<int 的都先转换成 Int在计算
      1. byte a = 1;
      2. byte b = 2;
      3. byte c = a + b;//错误 a,b都转成int进行计算,计算结果是int,所以需要强转
  4. 除非强转否则任何数都不能自动转成 char

    1. 意义不一样(表示范围并不完全重合或包含),不管是char转换成short,还是short转换成char,都可能“丢失精度”,因此必须强制转换
      1. //byte 1字节 short 2字节 char 4字节
      2. byte a = 1;
      3. short b = 2;
      4. short c = a; //正确 short>byte
      5. char d = a; //错误 char d = (char)a;
  5. byte a = 3; a+=3;不会报错,而a = a+3;却会报错

    1. 因为+=是一个运算符

      1. public class Difference{
      2. public static void main(String[] args){
      3. byte a = 4;
      4. a+=3;
      5. system.out.println(a);
      6. //不会报错因为+=是一个运算符,3 默认是int 类型,但是会做自动类型转换,相当于 byte a = 4;
      7. byte a = 4;
      8. a = a+3;
      9. //会报错,因为 3 是int类型,a+3 会被自动提升为 Int 类型,赋值给byte需要强转a=(byte)(a+3);
      10. //但是这种转换可能会导致溢出或者精度的下降,如果容忍可能出现的误差,可以使用这种转换
      11. }
      12. }