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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qmayuan 中级黑马   /  2013-8-18 02:20  /  1832 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

byte b = 1; b = b + 1; 为什么编译不通过,
byte b = 1; b = b += 1;  而编译就通过了呢?

10 个回复

倒序浏览
呵呵。。。。。。
回复 使用道具 举报
byte b = 1; b = b + 1;  [byte] b1 = [byte] b1 + [int] 1 类型不匹配
b += 1;   [byte] b1 = [byte] b1 + [byte] 1  这个样子类型符合,就可以正常编译过了

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

回复 使用道具 举报
第一个编译不过是因为1的默认类型是int类型的,需要强制转换,把他改成byte b = 1;b =(byte)(b+1);就OK了!
第二个中编译通过的原因在于b+=1这里,这里似乎有一个隐藏着的类型转换,这个表达式等价于b = byte(b+1),不过至于为什么会是隐藏的,我也是迷糊的,等等看,下面大神们很厉害的...

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

回复 使用道具 举报
第二个网上也说是有强制类型转换的过程, 难道这个是需要背下来的么?
回复 使用道具 举报
本帖最后由 straw 于 2013-8-18 17:13 编辑

byte b = 1;
b = b + 1;
编译不过是因为类型不比配, "+" 在这里是一个运算符,只有int doubel float 等类型数据才有运算功能,所以
虚拟机会将b自动转换成int类型然后再与1相加,到这里"="右边已经是int类型了,而左边则还是byte类型,所以虚拟机就会包类型不比配异常!
如果把右边的结果强制转换成byte就可以了,如:b = (byte)b + 1;
(注意!)java中是有自动拆装箱功能,但是"="左右不能自动拆装的.如:String s=1;这样也是错误的.因为String类型变量不能应用一个非String类型的值.

byte b = 1;
b = b += 1;
这个能编译通过,同样也是因为"+"的作用,b += 1相当于b和1相加后在赋值给b,但在此过程中由于"+"的作用,虚拟机会将"+"两边的数据自动转换成int类型后
在进行相加计算.也就是我们实际看到的b += 1;中的变量b其实已经是转换成int类型的了.
在这里我们有个误区,就是认为b+=1同等于b=b+1,其实b+=1真实的运算过程是同等于b=(原b的声明类型)b+1.如果有兴趣的可以去翻看"+="在java中
算法的源代码就知道了.

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

回复 使用道具 举报
straw 发表于 2013-8-18 17:09
byte b = 1;
b = b + 1;
编译不过是因为类型不比配, "+" 在这里是一个运算符,只有int doubel float 等类型 ...

那  byte b = 1+1; 这个右面 运算之后也是int类型  就可以通过
跟 byte b = 1;  b = b+1;  右面运算之后也是int型 为什么不对呢?
回复 使用道具 举报
straw 中级黑马 2013-8-18 17:33:31
8#
本帖最后由 straw 于 2013-8-18 17:36 编辑
qmayuan 发表于 2013-8-18 17:17
那  byte b = 1+1; 这个右面 运算之后也是int类型  就可以通过
跟 byte b = 1;  b = b+1;  右面运算之 ...


呵呵,淡定啊!
首先"="两边是不能自动拆装箱的,那么为什么byte b=1+1;?
由0~9的数字组成的数据如1,2,2999.......等等,这些数字是一个很特别的数字,默认情况下java会将他们定义为int类型,但实际上他们可以是double float byte
类型.所以double db=1;
               float fl=2;
               byte b=3;
都不会报错!
所以byte b=1+1;是不报错的.
而b=b+1;是将b强制转换成int类型后再相加,结果是2,但是不能将b+1=2来看,因为2还可以是其他类型数据,而b+1则是一个没有被引用的int类型值.
所以b=b+1;是会报类型不比配异常的.如果要使等式两边成立,那么就必须进行强制类型转换:b=(byte)(b+1);
回复 使用道具 举报
byte b = 1; b = b + 1;
Java中,整数的默认类型是int,那么 为什么byte b=1; 可以编译通过,而b=b+1;会报错。
其实,在编译过程中,编译器在检查时,判断1在byte类型的取值范围内(-128~127),就会将1强转为byte类型(这里有隐式强转的过程)。当检查 b=b+1;发现b是一个变量,b的取值不确定,b+1的运算结果就不确定,是否在byte类型的取值范围内,编译器报错。

byte b=1; b+=1;
byte b=1;与上面同理,但是,b+=1,为什么编译通过可以运算出结果?这就是,b=b+1和b+=1的区别。b+=1;在编译过程中,会有一个隐式强转,相当于:b=(byte)(b+1);所以编译通过。


如:byte b=0;b=3+1;编译通过(3,1是两个明确的数字,且运算结果在byte取值范围内,编译可以通过)。。  
byte b=0;byte b1=3;byte b2=4; b=b1+b2;编译报错(b1  b2虽然赋过直,但是变量,值不确定)。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

回复 使用道具 举报
straw 中级黑马 2013-8-19 01:10:40
10#
本帖最后由 straw 于 2013-8-19 01:24 编辑
花伟昌 发表于 2013-8-18 21:36
byte b = 1; b = b + 1;
Java中,整数的默认类型是int,那么 为什么byte b=1; 可以编译通过,而b=b+1; ...


哥们,你是不是在百度里得知b=b+1;报错是因为b是变量,编译器不知道b+1是否在-128~127的范围而报错的?
其实这是错误的!
事实上b+1可以是大于127或者小于-128的数值,下面我用小段代码来演示:
  1. byte b1=127;
  2. byte b2=0;
  3. byte b3=(byte)(b1+b2);
  4. System.out.println(b3);
复制代码
输出: 127
再将b2改成1:
  1. byte b1=127;
  2. byte b2=1;
  3. byte b3=(byte)(b1+b2);
  4. System.out.println(b3);
复制代码
输出: -128
以此类推b3会不断增加到127然后又从-128开始增长.说明b=b+1;报类型比配异常不是因为编译器不确定b的大小而造成的.

byte类型值也是数值,为什么不能进行数学运算呢?
因为byte的数值是在-128~127之间,如果让byte类型可以进行数学运算那么结果有可能会导致超出范围.所以JVM才会先将byte转换成可运算的数据类型
后在进行数学运算.最后将运算得出的结果强制转换成byte类型,在转换成byte过程中JVM会判断是否在byte的范围,如果在就直接赋值,如果大于127就依次减去256直到结果在byte为止,如果小于-128就依次加上256直到结果在byte范围为止.如果我说得没错的话上面的代码还可以这么改:
  1. byte b1=127;
  2. byte b2=2;
  3. byte b3=(byte)((double)b1+(float)b2);//将b1强行转换成double类型,b2强行转换成float类型后在相加,最后转换成byte类型
  4. System.out.println(b3);
复制代码
输出结果: -127


回复 使用道具 举报
qmayuan 发表于 2013-8-18 11:41
第二个网上也说是有强制类型转换的过程, 难道这个是需要背下来的么?

网上查了一下,+=是Java语言规定的运算符,其实并不需要我们去背下来,Java编译器会对它进行特殊处理,所以编译的时候不会报错,编译器知道是怎么回事,会正确处理
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马