黑马程序员技术交流社区

标题: 类型提升问题 求解 [打印本页]

作者: 葬天    时间: 2012-10-29 23:12
标题: 类型提升问题 求解
/**
类型转换
疑问:char类型相加提升问题
*/
class VarDemo
{
        public static void main(String[] args)
        {

                char c = 'a';
                //c = 'a' + 'b';//编译通过,结果:?
                //c = c + 'b'; //编译失败,c int类型损失精度
                //c += 'b';//编译通过,结果:?
                c = (char)c + 'b';//编译失败,c int类型损失精度

                System.out.println(c);
        }
}

不知道出现上述情况何解??


作者: 打工人    时间: 2012-10-29 23:17
//c = 'a' + 'b';//编译通过,结果:?
这是因为ASCII码中,ASCII码值最大就到127,但是'a'对应的是97,‘b’对应的是98 ,两者相加位195,超出了这个范围,所以会出现?
作者: 葬天    时间: 2012-10-29 23:21
冯海霞 发表于 2012-10-29 23:17
//c = 'a' + 'b';//编译通过,结果:?
这是因为ASCII码中,ASCII码值最大就到127,但是'a'对应的是97,‘ ...

c = 'a' + 'b'; 编译通过 结果:?
说明 两个字符 相加没有 出现 类型 提升

那为什么
c = 'a';
c= c + 'b';编译失败呢

而且 c = char(c) + 'b'; 也失败呢
好像 两个字符相加 又 出现现了 类型 提升
出现矛盾了 为什么么呢?
作者: 打工人    时间: 2012-10-29 23:29
两个char类型的相加,会都提升成int型再做运算。
                   char c='0';
                c='A'+'2';
                System.out.println(c);//这个输出's',是因为,把A和2的和赋值给了c,c是char类型
                              System.out.println('A'+'2');//这个输出的是115,恰好验证了两个char类型的相加,会都提升成int型再做运算。

作者: 打工人    时间: 2012-10-29 23:32
c = 'a' + 'b'//这个过程就是首先ab都提升成int型,即97+98,结果为195,然后再赋值给c,因为c是char型的,所以195要转换为char类型,但是,ASCII码中,数值最大就到127.所以就出现问号了
作者: 葬天    时间: 2012-10-29 23:39
冯海霞 发表于 2012-10-29 23:29
两个char类型的相加,会都提升成int型再做运算。
                   char c='0';
                c='A'+'2';

我的
int c = 'a';
c = c + 'b';
也相当于把 'a' + 'b'的和赋值给c; 编译失败
或者 c = (char)c +'b' ;编译失败;
你的 c = 'A'+'2';也是 把和赋值给c,编译成功
何解?
作者: 打工人    时间: 2012-10-29 23:40
葬天 发表于 2012-10-29 23:39
我的
int c = 'a';
c = c + 'b';

我再想想
作者: 葬天    时间: 2012-10-29 23:42
冯海霞 发表于 2012-10-29 23:40
我再想想

恩呢 3Q。。。。。。。
作者: 马磊    时间: 2012-10-30 00:02
本帖最后由 马磊 于 2012-10-30 00:10 编辑

这是Java编译器处理的,它觉得你这个表达式有可能超过char类型的时候,就把表达式自动提升到了int类型。
拿byte型举例:
         byte a = 4;
         byte b = 5;
         byte c =100+10; //这个没问题
         byte d  = a + b;  //不行了,因为编译器担心这里的a+b 会超过byte类型,所以就给提升到了int类型,因此也就不能再给byte类型的d赋值了
含有变量的表达式在做运算时,编译器会把它们的类型自动提升,而c = 'a' + 'b' ,其和为195 还小于char的上限65535呢,所以编译器知道它俩的结果可以放到char类型的c里面,所以没有报错。




作者: 打工人    时间: 2012-10-30 00:14
马磊 发表于 2012-10-30 00:02
这是Java编译器处理的,它觉得你这个表达式有可能超过char类型的时候,就把表达式自动提升到了int类型。
拿 ...

这个是不是跟什么隐式转换和显式转换有关
作者: 马磊    时间: 2012-10-30 00:14
'�'  这个字符在java中的编码是'\ufffd', 也就是说再多两个就超过'\uffff'的上限,所以拿这个字符和其它键盘能录入的字符相加,编译都不能通过,因为它超过了char的上限了

可以试试  char  c  = '�' +  'a';   // 这个也会报错的
作者: 马磊    时间: 2012-10-30 00:21
冯海霞 发表于 2012-10-30 00:14
这个是不是跟什么隐式转换和显式转换有关

表达式的类型自动提升就是隐式转换,就像上面例子中的 c = c + 'a';一样 ,因为c是变量,java认为表达式有可能会超过char的范围(即使现在没超过,因为变量可以赋值,以后或许有肯能),所以把表达式自动提升到了int类型。

显式转换就是强制类型转换,非要把一个int类型的转回char来: c = (char) (c+'a')
作者: 马磊    时间: 2012-10-30 00:44
损失精度的后果是很难以预计,甚至很严重的,所以Java为了安全起见会给表达式做自动提升。

参考: Cluster 宇宙飞船,http://en.wikipedia.org/wiki/Ariane_5_Flight_501
这个宇宙飞船的发射程序里面的bug,也就一行代码的错误,造成了整型数据的溢出,在发射后37秒就偏离了航道,最后不得不启动自毁程序。

1996年,这行代码造成了3.7亿美元的损失,哇呀呀呀呀!!!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2