本帖最后由 厦门校区 于 2020-3-4 12:06 编辑
今天给大家讲几个课程相关的问题 第一个问题:诡异的语法? 很多同学会有疑惑,上课老师不是说的直接定义一个整数是int类型么? 那为什么byte b = 10 不用强制转换呢? 这是因为编译器给我们搞的鬼,想搞懂这个问题,就需要提前明白一个道理。 在Java中,有很多时候,我们的编译器为了给我们省事,他会让我们以一种简单的形式帮我们简化常用的写法,自己却在后面默默做了很多事情,除了今天这个例子,我们在以后还会见其他的例子。 当你发现你写的语法看似不符合规范但是却成功的时候,不要觉得是侥幸,程序时很严谨的,之所以成功,一定是有人(编译器)帮你将剩下的事情做了。 前情回顾: 我们都知道,直接定义一个整数,默认是int类型 但是我们这样定义: [Java] 纯文本查看 复制代码 byte b = 10; 按说左边是byte类型,右边是int类型,应该强转之后才能赋值成功,但是我们没有强转,却赋值成功了。
原理解析: 其实这里面并没有少强转这一步,而是由编译器在编译之前帮我们做了强转的这一步操作 相当于: 我们写的 [Java] 纯文本查看 复制代码 byte b = 10; 编译器 拿到的 [Java] 纯文本查看 复制代码 byte b = (byte)10; 所以我们直接写 [Java] 纯文本查看 复制代码 byte b = 10; 不会报错 第二个问题:奇怪的数字? [Java] 纯文本查看 复制代码 int a = 200;byte b = (byte)a;System.out.println(b); 我们会观察到,控制台的输出结果是-56,这里为什么是-56呢? 这是因为强转之后,数据溢出造成的
要说明这个问题,先要说明几个相关概念,在这里,如果各位同学对二进制的 转换不熟悉,可以移步到我的b站,查看相关知识点:十进制和二进制的转换关系 【1】所有的计算机的进行数据计算,都是需要将10进制转为2进制计算的 【2】有关二进制有三个概念: 以200举例 他的二进制 为 1100 1000
(1)原码:十进制转为的二进制是原码 1100 1000 (2)反码: 正数的反码就是原码本身 1100 1000 负数的反码是符号位不变,数值位取反 1011 0111 (3)补码: 正数补码是原码 1100 1000 负数的补码是反码的基础上 + 1 1011 1000 【3】所有的二进制计算都是先将原码->补码,计算完毕之后再由补码->原码,然后根据原码的表示形式显示最终的效果 原码->补码 200的int类型因为是4个字节,所以原反补都是一样的
然后强转为byte之后,4个字节变为1个字节 补码->原码
我们需要拿到展示结果需要将补码转为反码 所以应该-1 再转为 原码,除符号位不变,其他位取反,这就是强转之后的原码,而这个数对应的就是-56,其实很好理解,0011 1000 是56,那么1011 1000就是-56了,因为符号位取反操作了
最后引入一张流程图,帮助大家理解
|