官术网_书友最值得收藏!

2.6 表達式

表達式是由操作數和運算符按一定的語法形式組成的符號序列。每個表達式結果運算后都會產生一個確定的值,稱為表達式的值。表達式的值是有類型的,該類型稱為表達式類型。表達式類型由運算符和參與運算的數據的類型決定。可以是簡單類型,也可以是復合類型。

一個常量或一個變量是最簡單的表達式,表達式的值即該常量或變量的值。用運算符連接幾個表達式構成的式子仍是表達式。

可以按表達式值的類型將表達式分類。

2.6.1 類型轉換

在一個表達式中可能有不同類型的數據進行混合運算,這是允許的,但在運算時,Java將不同類型的數據轉換成相同類型,再進行運算。

1.自動類型轉換

整型、實型和字符型數據可以進行混合運算。在運算中,不同類型的數據先轉換成相同類型,然后再進行運算。轉換從低級到高級。可混合運算數據類型從低到高排列如下:

           (低)->byte,short,char,int,long,float,double ->(高)

不同類型數據之間的轉換規則如表2.14。

表2.14 不同類型數據之間的轉換規則

2.強制類型轉換

高級數據要轉換為低級數據時,需進行強制類型轉換。例如:

                    int a;
                    char b;
                    b=(char)a;

加括號的char告訴編譯器想把整型的a轉換為字符類型并把它賦值給b。

由于整型和字符型變量位長是不同的,整型是32 位長,字符型是16 位長,所以從整型轉換到字符型可能會丟失信息。同樣,當把64 位的長整型數轉換為整型時,由于長整型可能有比32 位更多的信息,也很可能會丟失信息。即使兩個量具有相同的位數,比如整型和單精度實型數據(都是32位),在轉換小數時也會丟失信息。當進行類型轉換要注意使目標類型能夠容納原始類型的所有信息,不會丟失信息的類型轉換見表2.15。

表2.15 不會丟失信息的類型轉換

需要說明的是,當執行一個這里并未列出的類型轉換時可能并不總會丟失信息,不過進行這樣一個理論上并不安全的轉換總是很危險的。

3.表達式求值中的自動類型提升

在表達式的求值過程中,運算中間值的精度有時會超出操作數的取值范圍。例如:

              byte x = 30,y = 50,z = 100;
              int a = x * y / z;

在運算x*y項時,結果1500 已經超出了操作數byte類型的范圍。為解決這類問題,Java語言在對表達式求值時,自動提升byte或short類型的數據為int類型的。Java語言對表達式求值的自動類型提升規則為:

(1)所有byte和short類型提升為int類型。

(2)若一個操作數是long類型,則整個表達式提升為long類型。

(3)若一個操作數是float類型,則整個表達式提升為float類型。

(4)若有double類型,則表達式值為double類型。

自動類型提升對數據的運算帶來了方便,但也容易引起編譯錯誤。例如:

              byte x = 30;
              x = - x;       // 編譯錯誤!不能向byte變量賦已提升的int類型值

【例2.6】不同類型數據的混合運算。

              class Promote {
                public static void main(String args[]) {
                  byte b = 42;
                  char c = 'a';
                  short s = 1024;
                  int i = 50000;
                  float f = 5.67f;
                  double d = .1234;
                  double result = (f * b) + (i / c) - (d * s);
                  System.out.println((f * b) + " + " + (i / c) + " - " + (d * s));
                  System.out.println("result = " + result);
                }
              }

程序運行結果如下:

              238.14 + 515-126.3616
              result = 626.7784146484375

2.6.2 優先級

在一個表達式中可能有各種運算符,Java語言規定了表達式中出現各種運算符的時候,哪種運算符先進行運算,哪種運算符后進行運算的運算符的運算順序,稱為運算符的優先級,它指明了同一表達式中多個運算符被執行的次序,同一級里的操作符具有相同的優先級。在表達式中,優先級高的運算符先進行運算。例如對于表達式:

                    a = b + c * d / (c ^ d)

Java處理時將按照表2.16 所列從最高優先級到最低優先級的次序進行。在上例中,因為括號優先級最高,所以先計算c^d,接著是c*d,然后除以c^d,最后,把上述結果與b的和存儲到變量a中。

不論任何時候,若一時無法確定某種計算的執行次序時,可以使用加括號的方法明確為編譯器指定運算順序,這也是提高程序可讀性的一個重要方法。例如,對表達式:

              a | 4 + c >> b & 7 || b > a % 3

運算次序的理解就不如下面的表達式清晰,因為在下面的表達式中用括號()顯式地表明了運算次序。

              (a | (((4 + c) >> b) & 7)) || (b > (a % 3))

表2.16按從高到低的優先級列出了運算符。同一行中的運算符優先級相同。

表2.16 運算符優先級

2.6.3 結合性

在表達式中出現多個相同優先級的運算符時,就需要考慮結合性。結合性確定同級運算符的運算順序。運算符有左結合性和右結合性兩種。左結合性指的是從左向右使用運算符。例如二元算術運算符具有左結合性,計算a + b - c時,操作數b的左、右運算符 +、-是同級運算符,計算時,b先與左邊的 + 結合,計算a + b,其和再與c相減;而右結合性是從右向左使用運算符。例如,賦值運算符具有右結合性,計算a = b = c時,操作數b的左、右運算符都是同級的賦值運算符,所以,先執行b = c,再執行a = b。

主站蜘蛛池模板: 涿州市| 靖江市| 永嘉县| 邹平县| 石林| 隆回县| 连山| 奉节县| 潞城市| 孟州市| 莎车县| 运城市| 南澳县| 北海市| 洛宁县| 石棉县| 密云县| 同江市| 老河口市| 砚山县| 九龙城区| 汶川县| 汉川市| 潜江市| 象山县| 建湖县| 洪湖市| 万安县| 汾西县| 泾川县| 三门峡市| 登封市| 山西省| 呼图壁县| 元江| 个旧市| 阿拉尔市| 马关县| 凤台县| 高台县| 泗洪县|