8种数据类型及其所占空间大小

注意:

  1. 为什么 float 占4个字节,而 long 占8个字节,float 表示的范围却比 long 要大得多呢?

    原因简单说是因为二者存储的模式不同

    long 类型是是直接用 64 位二进制位去存储数据的二进制原码

    float 作为浮点数类型,在 java 里遵循IEEE754标准,将 32 位分为 3 个部分,第一部分 1 位存储符号,第二部分 8 位存储浮点数的科学表示后的指数,第三部分23,位存储浮点数的科学表示后的纯小数(有效数字部分),所以浮点数的范围要比其他任何数据类型都要大得多

    https://blog.csdn.net/i6223671/article/details/88312191

  2. boolean 类型是否占一位

    我们通常默认为boolean值的长度为1/8字节也就是1位,因为1个二进制位就完全可以表示 turefalse 这两个值,但是在实际的内存中,boolean 的占位的大小其实是和 java 的虚拟机有关,毕竟用 java 输出 boolean 类型的值是"true"或者"false"这样的字段,而不是0,或者1

  3. 整数默认都是整型,小数默认都是double

    所以表示 long 型常量时要在后面加L(注意大写,小写容易和1混淆),float 型后面需要加F,注意但是 byte/short 类型没有这样的写法,因为 byteshort 可以直接赋值范围类的整数

  4. 既然整数默认都是整型的,那为什么 byte b = 127; 不会报错

    JVM对常量有优化机制(具体可以看我下一篇文章java常量优化机制),虚拟机编译器是认识常量的,知道 -128~127 是在 byte 的取值,但是一旦超出范围就出错,这也是为什么没有 123b 来表示 byte22s 来表示 short 的写法了

  5. byte 和 short 类型赋值给 char 类型为什么会报错

    虽然说 byte 占一个字节,short 和 char 占两个字节,但是 char 表示的范围是正数的一部分,没有负数的,和 short、byte 类型之间有交叉但是没有包含,所以转换不了

  6. 这个编译为什么会报错:byte a = 127; byte b = -128; byte c = a + b;

    因为 ab 都是变量,编译器虽然可以确定 ab 两个变量的值都是 byte 的取值范围,但是由于他们是变量,他们相加的值编译器在编译期间是无从得知的,而且JVM中只有 int、long、float、double 四个数字类型支持,所以比 int 小的加法运算自动转化成 int 的加法运算,结果也是 int 类型,因此,编译器会把 bytebyte 相加的值默认提升为 int 进行处理

  7. 这个编译为什么会报错:byte a = 10; a = a + 10;byte a = 10; a += 10; 不会报错呢

    前者原因跟上条一样,编译器会把 bytebyte 相加的值默认提升为 int 进行处理

    后者是因为JVM对 += 运算符做了优化,会默认帮我们进行强转,相当于 a = (byte)(a + 10)

隐性转换(自动转换)

取值范围小的,自动转换为取值范围大的类型

注意:boolean 类型不参与类型转换

double d = 10; // 这里会出现类型的自动转换, int 自动转换成了 double 类型
System.out.println(d); // 10.0, 这里看出是做了隐式转换了, 因为如果是 int, 是没有后面的 .0 的
byte b = 10;
int i = b; // 当编译 int i = b; 时, b 隐式转换为 int 类型, 在赋值给 i 
int i = 2;
double d = 5.0;
System.out.println(d / i); // 结果为 2.5, 这里会将 i 隐式转换为 double 类型

强制转换

取值范围大的, 转换成取值范围小的

注意:不推荐使用强制类型转换,因为会损失精度