A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱玉玺 中级黑马   /  2013-2-1 12:26  /  2737 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张向辉 于 2013-2-3 11:45 编辑
  1. public class Test {         
  2.     public static void main(String[] args) {
  3.             
  4.            int m=2147483647;//int的最大值
  5.            m=m+m;
  6.            byte b =127;    //就算是 b=0;b+b之和也没有超过byte的取值范围~但也不能通过编译
  7.       
  8.            b=b+b;//这句会报错,为什么?           
  9.            System.out.println(m);
  10.            System.out.println(b);        
  11.            
  12.     }

  13. }
复制代码
为什么x=x+x这样的操作,为啥x是int型的就可以,而是byte却不行?
————————————————————————————————————————
看到了下边兄弟们的回复,我知道老毕视频里讲的时候,是举得“byte b = 0;b=b+2;”这里例子由于b是一个字节,而2是四个字节,所以导致了b的类型提升;但b+b,它们的内存都是一个字节,为什么也要提升?不提升会出现什么问题导致编译器报错?

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

15 个回复

倒序浏览
b=b+b;//这句会报错,为什么?     在加的时候b得类型自动提升为int类型了  毕老师视频里uou讲到
希望能帮助你
回复 使用道具 举报

如果想运行成功 需要进行强制类型转换将
b=b+b;//改成b=(byte)(b+b);
就可以了
回复 使用道具 举报
本帖最后由 黑马唐贤来 于 2013-2-1 13:15 编辑

byte b =127;   
由于byte的取值范围是-128~127,b+b的结果是254,超出了byte范围,所以254提升为了int,最后使用强转为byte就可以解决

             int m=2147483647+1;
            //m+=m;
            System.out.println(m);
  上面代码运行结果是-2147483648;而m+=结果为-2所以可以装进int
回复 使用道具 举报
这里java又有自己的一个机制,就是防止两个小数相加超出自己所表示的范围,把b2变成 int 在相加。相加后也是int 型(注意这里的int 和 上面说的没有指出类型的整数默认是int 有区别,这里相当于你自己实际定义的了 例 int c=0; 系统不会在将这种明确规定数据类型的数做出自动转换的。转换也要自己强制类型转换b=byte(b+b);   这样看来好像更符合防止两个数相加超出自己表示范围的机制)。
回复 使用道具 举报
黑马唐贤来 发表于 2013-2-1 13:12
byte b =127;   
由于byte的取值范围是-128~127,b+b的结果是254,超出了byte范围,所以254提升为了int,最后 ...

如果b=0,也不能通过,这是为什么?
回复 使用道具 举报
黑马唐贤来 发表于 2013-2-1 13:12
byte b =127;   
由于byte的取值范围是-128~127,b+b的结果是254,超出了byte范围,所以254提升为了int,最后 ...

你把b=127,换成b=0,也不能通过
回复 使用道具 举报
byte  b = 127;  定义的是一个byte型变量b,初始化赋值为127.
注意b是一个变量
而下一句  b  =  b + b; 这句里右边两个都是变量,变量 + 变量范围是未知,不确定。不能赋值给= 左边,因此系统编译时会出错。
希望对楼主有帮助!毕老师视频里边也是有的!  

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

回复 使用道具 举报
本帖最后由 王昕 于 2013-2-1 13:34 编辑

int型的 m 编译器虽然没报错,但是结果实际上溢出了。byte型的 b 在被 b+b 的结果赋值时,编译器检查了类型,发现会损失精度,所以报错。

要牢记,变量被声明成什么类型,它永远就是什么类型,可以把变量想成一个杯子,类型就是杯子的大小,变量名就是杯子的名字(或者你也可以认为是杯子的位置),杯子的大小(也就是变量的类型)是不会因为强制类型转换而改变的,强制类型转换只是把杯子里的二进制码复制到临时存储单元以后进行转换,然后参加运算,这些都在临时存储单元中进行,最后把计算结果放回杯子的时候,byte的杯子不够大,所以报错了。int的没报错,但是更糟糕,因为它溢出了,结果-2实际是错的,-2只是相加结果(用补码表示的)换成十进制,但是编译器没发现。这种错比编译器能发现的错危害还要大。

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

回复 使用道具 举报
朱玉玺 发表于 2013-2-1 13:25
你把b=127,换成b=0,也不能通过

这里  你拿 2个byte 类型   的 127+0  事实上,127+0他们是在int空间里面算的 所以算出来127+0=127的结果  结果的类型是int  所以就编译不通过
回复 使用道具 举报
王昕 发表于 2013-2-1 13:31
int型的 m 编译器虽然没报错,但是结果实际上溢出了。byte型的 b 在被 b+b 的结果赋值时,编译器检查了类型 ...

呵呵,因为发现byte的报错,我就一直想找个int + int结果超出取值范围的例子,没能找到
回复 使用道具 举报
txl 中级黑马 2013-2-1 18:25:49
12#
朱玉玺 发表于 2013-2-1 13:20
如果b=0,也不能通过,这是为什么?

你换成b+=b;
回复 使用道具 举报
刘岳林 发表于 2013-2-1 13:31
byte  b = 127;  定义的是一个byte型变量b,初始化赋值为127.
注意b是一个变量
而下一句  b  =  b + b; 这 ...

那  int m=0;m=m+m,却可以通过编译,又作何解释?
回复 使用道具 举报
黑马唐贤来 发表于 2013-2-1 18:25
你换成b+=b;

问题不在这儿,在为什么b是整型就能通过,同样的情境,java为什么采取了两种机制~
回复 使用道具 举报
本帖最后由 薛虎 于 2013-2-3 13:05 编辑

虚拟机规定,short、boolean、byte、char在运算时都会转为int,而int、long、float可以直接运算。
所以这里b=b+b要写成b=(byte)(b+b)或者b+=b。
回复 使用道具 举报
朱玉玺 发表于 2013-2-3 12:28
那  int m=0;m=m+m,却可以通过编译,又作何解释?

视频里边讲到这点了,因为整数默认是int类型吧,所以编译可以通过。你可以用short类型试一下,也是不能通过的,说的可能不是很准确,因为看完很长时间了,但大概就是这个意思,记住就好了。如果想弄清楚,可以去视频里边找到!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马