表达式

表达式由运算符,变量和字面值组成.从其他编程经验或代数中,你可能已经知道了表达式的基本形式.然而,这里还需要对表达式的几个方面进行介绍.
1.表达式中的类型转换
只要类型兼容,在表达式总就可以混合使用一种或多种不同类型的数据.例如,可以在表达式中混合使用short和long,因为他们都是数值类型.当在表达式中混合使用不同类型的数据时,他们都被转换为同一类型.这是通过使用Java的类型升级规则(type promotion rule)完成的.
首先,所有的char,byte和short值都被升级为int.其次,如果有一个操作数是long类型,整个表达式就全部升级为long类型.如果有一个操作数是float类型,整个表达式就全部升级为float类型.如果有一个操作数是double类型,整个表达式就全部升级为double类型.
当计算表达式时,类型升级只应用于被操作的值,理解这一点是非常重要的.例如,如果在一个表达式中,一个byte类型变量的值升级为int.那么在表达式以外,该变量仍然是byte类型.类型升级只影响表达式的计算.
然而类型升级可能导致某些不可预测的错误.例如,当一个算术运算包括两个byte值时,就会顺序发生以下事情:首先,byte类型的操作数升级为int;然后,进行运算,生成一个int类型的结果.因此,包括两个byte类型的运算结果将会成为一个int类型的值.而这可能不是一下就能预见到的.
    public static void main(String args[])
    {
        byte b;
        int i;
        
        b = 10;
        i = b * b;
        
        b = 10;
        b = (byte)(b * b);
    }
有些出乎意料的是,因为当计算表达式时b被升级为int,所以把b*b赋值给i时不需要强制转换.然而当试图将b*b赋值给b时,却需要强制转换回byte类型!如果看上去表达式完全没有问题,但是却出现意外的类型不兼容错误,那就应该想到这一点.
在执行有关char的运算时也会有同样的情况发生.例如,在下面的代码段中,因为表达式中ch1和ch2升级为int,所以需要将其强制转换为char;
        char ch1,ch2;
        
        ch1 = 'a';
        ch2 = 'b';
        
        ch1 = (char)(ch1 + ch2);
如果没有强制转换,ch1+ch2的结果为int类型,这是无法赋值给一个char类型的变量的.
强制转换不只在赋值的时候有用,考虑下面的程序,从整除强制转换为double来获得小数部分.
    public static void main(String args[])
    {
        int i;
        for(i = 0;i<5;i++)
        {
            System.out.println(i+" / 3 :"+i/3);
            System.out.println(i+" / 3 with  fractins : "+(double)i/3);
            
        }
    }
输出:
0 / 3 :0
0 / 3 with fractins : 0.0
1 / 3 :0
1 / 3 with fractins : 0.3333333333333333
2 / 3 :0
2 / 3 with fractins : 0.6666666666666666
3 / 3 :1
3 / 3 with fractins : 1.0
4 / 3 :1
4 / 3 with fractins : 1.3333333333333333
2.间距和圆括号
Java中的表达式可以使用制表符和空格来增强可读性,例如,下面的两个表达式作用相同,但是第二个表达式更易读:
x=10/y*(127/x)

x=10 / y * ( 127 / x )
与代数中圆括号的作用一样,增加了所包括的运算的优先级.使用多余或附加的圆括号不会引发错误,也不会减慢表达式的执行.Java提倡使用圆括号以使计算的顺序清晰,帮助你自己以及其他阅读程序的人更好的理解程序.