“造型”(Cast)的作用是“與一個模型匹配”。在適當的時候,java會將一種數據類型自動轉換成另一種。例如,假設我們為浮點變量分配一個整數值,計算機會將int自動轉換成float。通過造型,我們可明確設置這種類型的轉換,或者在一般沒有可能進行的時候強迫它進行。 為進行一次造型,要將括號中希望的數據類型(包括所有修改符)置于其他任何值的左側。下面是一個例子: void casts() { int i = 200; long l = (long)i; long l2 = (long)200; } 正如您看到的那樣,既可對一個數值進行造型處理,亦可對一個變量進行造型處理。但在這兒展示的兩種情況下,造型均是多余的,因為編譯器在必要的時候會自動進行int值到long值的轉換。當然,仍然可以設置一個造型,提醒自己留意,也使程序更清楚。在其他情況下,造型只有在代碼編譯時才顯出重要性。 在C和C++中,造型有時會讓人頭痛。在Java里,造型則是一種比較安全的操作。但是,若進行一種名為“縮小轉換”(Narrowing Conversion)的操作(也就是說,腳本是能容納更多信息的數據類型,將其轉換成容量較小的類型),此時就可能面臨信息丟失的危險。此時,編譯器會強迫我們進行造型,就好象說:“這可能是一件危險的事情——假如您想讓我不顧一切地做,那么對不起,請明確造型。”而對于“放大轉換”(Widening conversion),則不必進行明確造型,因為新類型肯定能容納原來類型的信息,不會造成任何信息的丟失。 Java答應我們將任何主類型“造型”為其他任何一種主類型,但布爾值(bollean)要除外,后者根本不答應進行任何造型處理。“類”不答應進行造型。為了將一種類轉換成另一種,必須采用非凡的方法(字串是一種非凡的情況,本書后面會講到將對象造型到一個類型“家族”里;例如,“橡樹”可造型為“樹”;反之亦然。但對于其他外來類型,如“巖石”,則不能造型為“樹”)。 1. 字面值 最開始的時候,若在一個程序里插入“字面值”(Literal),編譯器通常能準確知道要生成什么樣的類型。但在有些時候,對于類型卻是曖昧不清的。若發生這種情況,必須對編譯器加以適當的“指導”。方法是用與字面值關聯的字符形式加入一些額外的信息。下面這段代碼向大家展示了這些字符。 //: Literals.java class Literals { char c = 0xffff; // max char hex value byte b = 0x7f; // max byte hex value short s = 0x7fff; // max short hex value int i1 = 0x2f; // Hexadecimal (lowercase) int i2 = 0X2F; // Hexadecimal (uppercase) int i3 = 0177; // Octal (leading zero) // Hex and Oct also work with long. long n1 = 200L; // long suffix long n2 = 200l; // long suffix long n3 = 200; //! long l6(200); // not allowed float f1 = 1; float f2 = 1F; // float suffix float f3 = 1f; // float suffix float f4 = 1e-45f; // 10 to the power float f5 = 1e+9f; // float suffix double d1 = 1d; // double suffix double d2 = 1D; // double suffix double d3 = 47e47d; // 10 to the power } ///:~ 十六進制(Base 16)——它適用于所有整數數據類型——用一個前置的0x或0X指示。并在后面跟隨采用大寫或小寫形式的0-9以及a-f。若試圖將一個變量初始化成超出自身能力的一個值(無論這個值的數值形式如何),編譯器就會向我們報告一條出錯消息。注重在上述代碼中,最大的十六進制值只會在char,byte以及short身上出現。若超出這一限制,編譯器會將值自動變成一個int,并告訴我們需要對這一次賦值進行“縮小造型”。這樣一來,我們就可清楚獲知自己已超載了邊界。 八進制(Base 8)是用數字中的一個前置0以及0-7的數位指示的。在C,C++或者Java中,對二進制數字沒有相應的“字面”表示方法。 字面值后的尾隨字符標志著它的類型。若為大寫或小寫的L,代表long;大寫或小寫的F,代表float;大寫或小寫的D,則代表double。 指數總是采用一種我們認為很不直觀的記號方法:1.39e-47f。在科學與工程學領域,“e”代表自然對數的基數,約等于2.718(Java一種更精確的double值采用Math.E的形式)。它在象“1.39×e的-47次方”這樣的指數表達式中使用,意味著“1.39×2.718的-47次方”。然而,自FORTRAN語言發明后,人們自然而然地覺得e代表“10多少次冪”。這種做法顯得頗為古怪,因為FORTRAN最初面向的是科學與工程設計領域。理所當然,它的設計者應對這樣的混淆概念持謹慎態度(注釋①)。但不管怎樣,這種非凡的表達方法在C,C++以及現在的Java中頑固地保留下來了。所以倘若您習慣將e作為自然對數的基數使用,那么在Java中看到象“1.39e-47f”這樣的表達式時,請轉換您的思維,從程序設計的角度思考它;它真正的含義是“1.39×10的-47次方”。 ①:John Kirkham這樣寫道:“我最早于1962年在一部IBM 1620機器上使用FORTRAN II。那時——包括60年代以及70年代的早期,FORTRAN一直都是使用大寫字母。之所以會出現這一情況,可能是由于早期的輸入設備大多是老式電傳打字機,使用5位Baudot碼,那種碼并不具備小寫能力。乘冪表達式中的‘E’也肯定是大寫的,所以不會與自然對數的基數‘e’發生沖突,后者必然是小寫的。‘E’這個字母的含義其實很簡單,就是‘EXPonential’的意思,即‘指數’或‘冪數’,代表計算系統的基數——一般都是10。當時,八進制也在程序員中廣泛使用。盡管我自己未看到它的使用,但假若我在乘冪表達式中看到一個八進制數字,就會把它認作Base 8。我記得第一次看到用小寫‘e’表示指數是在70年代末期。我當時也覺得它極易產生混淆。所以說,這個問題完全是自己‘潛入’FORTRAN里去的,并非一開始就有。假如你真的想使用自然對數的基數,實際有現成的函數可供利用,但它們都是大寫的。” 注重假如編譯器能夠正確地識別類型,就不必使用尾隨字符。對于下述語句: long n3 = 200; 它并不存在含混不清的地方,所以200后面的一個L大可省去。然而,對于下述語句: float f4 = 1e-47f; //10的冪數 編譯器通常會將指數作為雙精度數(double)處理,所以假如沒有這個尾隨的f,就會收到一條出錯提示,告訴我們須用一個“造型”將double轉換成float。 2. 轉型 大家會發現假若對主數據類型執行任何算術或按位運算,只要它們“比int小”(即char,byte或者short),那么在正式執行運算之前,那些值會自動轉換成int。這樣一來,最終生成的值就是int類型。所以只要把一個值賦回較小的類型,就必須使用“造型”。此外,由于是將值賦回給較小的類型,所以可能出現信息丟失的情況)。通常,表達式中最大的數據類型是決定了表達式最終結果大小的那個類型。若將一個float值與一個double值相乘,結果就是double;如將一個int和一個long值相加,則結果為long。