- Android系統下Java編程詳解
- 鄭萌等編著
- 4659字
- 2019-01-09 15:14:22
3.4數據類型
3.4.1 知識準備:簡單類型
Java有8種簡單類型:四種整型、兩種浮點型、一種字符型、一種用于表示true/false的布爾類型。表3-3列出了這8種簡單數據類型。
表3-3 簡單數據類型

在這些數據類型中,int、short、byte、long都是整型數據,而double和float是浮點型數據。char也可以看成是整型數據,但它是無符號的(沒有負數)。
1.布爾類型
與 C語言不同,Java 定義了專門的布爾類型,用于表示邏輯上的“真”或“假”。布爾類型用關鍵字boolean來定義,數據只能取值true或false,注意不能用整型的0或1來替代。布爾類型不是數值型變量,它不能被轉化成任意一種類型。布爾類型常常用在條件判斷語句中。
boolean sendMsg = true; boolean recieveMsg = false;
注意:
這里的true和false是不能用雙引號引起來的,如果用雙引號引起來,就成了String類型的數據了。
2.字符類型
字符(Char)類型數據用來表示通常意義上的“字符”。字符常量是用單引號括起來的單個字符。
Java 與眾不同的特征之一就是Java對各種字符的支持,這是因為Java中的字符采用16位的Unicode編碼格式,Unicode被設計用來表示世界上所有書面語言的字符。Char簡單類型保存一個16位的Unicode字符。Unicode字符通常用十六進制編碼形式表示,范圍是“\u0000”~“\Uffff”,其中前綴“\u”標志著這是一個Unicode編碼字符,其中前256個(“\u0000”~“\u00FF”)字符與ASCII碼中的字符完全重合。
下面來看一個字符型數據的應用實例:
源文件:CharTest.java
public class CharTest { public static void main(String args[]) { char Msg1 = 'M'; char Msg2 = '中'; char Msg3 = '5'; char Msg4 = '\u0001'; System.out.println(Msg1); System.out.println(Msg2); System.out.println(Msg3); System.out.println(Msg4); } }
char 型數據只能記錄單個的字符值,不能表述更多的文字信息,Java語言還提供了String類型——記錄由多個字符組成的字符串。String常量的表達形式為雙引號引起來的0~多個字符,例如:
String s = "Java小能手"; System.out.println("Hello,Android!");
注意:
String不是基本數據類型,而屬于引用類型。
char類型的數據用單引號表示,注意它和String類型數據的區別,例如,“A”表示的是一個char類型的數據,而“A”表示的是一個String類型的數據,它們的含義是不同的。
Java語言中還允許使用轉義字符“\”來將其后的字符轉變為其他的含義,例如,如果需要在輸出結果時換行,應給編譯器換行指令 n,但是如果直接在程序中寫System.out.println("n");則不會起到換行的效果。此時,需要在n之前輸入“\”,這時編譯器會知道“n”是被轉義的字符。
還有一種特殊情況,在Java中使用一個絕對路徑:c:\learning\java,如果直接在程序中寫String path = “c:\learning\java”,則不會得到你期望的結果,因為Java將“\”當成轉義符了。所以,這時候應該這樣寫:
String path = "c:\\learning\\java";
這時,第一和第三個“\”都是表示轉義符,表示后面的那個字符(此處都為“\”)有特殊的含義。
3.整數類型
整數類型分為4類:byte、short、int及long,它們的差別在于所占用的內存空間和表數范圍不同。表3-4列出了這4種整數類型數據的存儲空間及表數范圍。
表3-4 整數類型的存儲空間和表數范圍

通常情況下,int是最常用的一種整型數據,它也是Java中整數常量的默認類型。在表示非常巨大的數字時,則需要用到更大范圍的long。對于前面3種整數數據類型的數據,只需要直接寫出數據就可以了,而對于長整形(long)數據,需要在長整型數據后面加上L或l來表示。
整型常量雖然默認為int類型,但在不超過其表數范圍的情況下,可以將int類型的數據直接賦給char、byte、short類型的變量。
下面是這些整形數據類型的一些例子:
byte b = 12; short s = 12345; int i = 1000000; long l = 1000000000L;
Java中允許使用3種不同的進制形式表示整型變量:八進制、十進制、十六進制。
(1)十進制整數,如123、-456、0。
(2)八進制整數,以0開頭,如0123表示十進制數83,-011表示十進制數-9。
(3)十六進制整數,以0x或0X開頭,如0x123表示十進制數291,-0X12表示十進制數-18。
4.浮點類型
Java浮點類型有兩種:float和double。Java浮點類型有固定的表數范圍和字段長度。和整數類型一樣,在Java中,浮點類型的字段長度和表數范圍與機器無關。表3-5列出了符點類型數據的存儲空間和表數范圍。
表3-5 符點類型數據的存儲空間和表數范圍

double類型的浮點類型數據正如它的名字所揭示的,它表示精度是float的兩倍(因此也將double類型的數據稱為雙精度類型的數據)。表示float類型的數據需要在數字后面加上F,用于和double類型數據相區別。
Java語言浮點類型常量有兩種表示形式:
□ 十進制數形式,必須含有小數點,例如3.14、314.0、0.314。否則將被當做int型常量處理,例如314。
□ 科學計數法形式,如3.14e2、3.14E2、314E2。注意,只有浮點類型才能采用科學計數法表示,因此,314E2也是浮點型常量,而不是int型。
Java語言的浮點型常量默認為double型,要聲明一個常量為float型,則要在它數字的后面加f或F。例如:
3.0表示一個double型常量,占64位內存空間。
3.0f表示一個float型常量,占32位內存空間。
3.4.2 知識準備:非boolean簡單數據類型之間的轉換
在Java程序中,一些不同的數據類型之間可以進行數據類型的相互轉換。簡單數據類型的轉換一般分為兩種:
(1)低級到高級的自動轉換。
(2)高級到低級的強制類型轉換。
二者的區別主要在于數據類型的表述范圍是不同的。比如,有一個int類型的數據,賦給一個long類型的變量,或者反之。這就類似于將水(數據)從一個容器(某種數據類型)倒入到另一個容器(另一種數據類型)一樣,因為容器的大小不同,能夠裝盛的水也是不同的。如果將從小容器中的水倒入到大容器中,不會有什么問題,但是,如果將大容器中的水倒入到小容器中,就可能會造成部分水溢出。同樣的,在數據類型轉換上面,也有類似的問題,如果將表數范圍比較小的數據類型數據轉換成表數范圍大的數據類型,則可以順利轉換;反之,則有可能發生數據的溢出(損失一部分信息)。
在圖3-3所示的數據類型的轉換中,實線條表示這種轉換不會引起信息的損失,而虛線條表示此種轉換可能會引起信息的損失。

圖3-3 不同數據類型之間的合法數據轉換
如果數據的轉換按照圖3-3中箭頭所示的方式來完成,則程序會自動轉換,不需要在程序中干預,這種轉換是低級到高級的自動轉換,也成為“擴展轉換(Widening Conversion)”。但是,如果不按照圖中的方向來轉換,則可以通過“強制類型轉換”的方式來完成,此時,可能會引起信息的丟失。當按照圖3-3中箭頭所示的反方向來轉換時,非常有可能造成數據精度的損失,這種轉換也經常稱為“縮小轉換(Narrowing Conversion)”。
例如。int類型的數據在必要時可以自動轉換成double的數據,但是,如果需要將double類型的數據轉換成int類型的數據,則需要通過強制類型轉換來完成。下面這條語句可以實現這個功能:
double d = 1.2345; int i = (int)d;
這樣,就可以將double類型的數據d轉換成int類型的數據,此時,i的值為1,顯然,小數后面的值都丟失了。
3.4.3 任務三:簡單數據類型轉換實例
1.任務描述
編寫程序驗證低級到高級的自動轉換和高級到低級的強制類型轉換。
2.技能要點
□ 理解類型轉換的原理。
□ 掌握強制類型轉換的方法和用途。
3.任務實現過程
(1)編寫源文件:DataOper.java,使int類型變量自動轉化為double類型變量,double類型變量強制轉化為int類型變量。
源文件:DataOper.java
public class DataOper { public static void main(String[] args) { // int類型數據將會自動轉換成double類型 double db1; int i = 123; db1 = i; System.out.println("db1=" + db1); // double類型數據轉換成int時,將會損失精度 double db2 = 1.234; int j = (int) db2; System.out.println("j=" + j); } }
(2)編譯并運行這個程序,可以得到如下的輸出:
Db1=123.0 j=1
int類型的數據已經自動轉換成了double類型的數據,而double類型數據在強制轉換成int類型數據的時候,小數點后面的值已經損失了。
3.4.4 知識準備:引用類型
Java語言中除了8種基本數據類型以外的數據類型稱為引用類型,或復合數據類型。如第2章中所述,引用類型的數據都是以某個類的對象的形式存在的,在程序中聲明的引用類型變量只是為該對象起的一個名字,或者說是對該對象的引用,變量的值是對象在內存空間中的存儲地址而不是對象本身。
Java中的所有對象都要通過對象引用訪問,引用類型數據以對象的形式存在,其構造和初始化及賦值的機制都與基本數據類型的變量有所不同。聲明基本數據類型的變量時,系統同時為該變量分配存儲器空間,此空間將直接保存基本數據類型的值。而聲明引用類型變量時,系統只為該變量分配引用空間,并未創建一個具體的對象或者說并沒有為對象分配存儲器空間,將來在創建一個該引用類型的對象后,再使變量和對象建立對應關系。
這就好比用遙控器(引用)操縱電視機(對象),只要控制遙控器就可以保持與電視機的連接。如果需要換臺,實際上操控的是遙控器(引用),再用遙控器操作電視機(對象)。此外,即使沒有電視機,遙控器也可以獨立存在。也就是說,你擁有一個引用,并不是一定需要有一個對象與它關聯。因此,如果想操縱一個詞,可以創建一個String引用:
String s;
這里所創建的只是引用,并不是對象。如果此時向 s 發送一個消息,就會返回一個運行時的錯誤,因此,一種比較安全的做法是創建引用的同時就進行初始化。
String s = "Hello android";
在這里用到了Java語言的一個特性:字符串可以用帶引號的文本初始化。通常,對其他對象需要一種更通用的初始化方法。參看任務四的引用過程。
3.4.5 任務四:引用類型程序示例
1.任務描述
編寫程序定義引用類型變量,了解引用類型的使用方法和特點。
2.技能要點
□ 聲明引用類型。
□ 了解引用類型和普通類型在使用上的區別。
3.任務實現過程
(1)構造有引用類型成員變量的類Email,在這個類中,定義了3個屬性:address、title、group,以及一個具有3個參數的構造器,用于在創建對象時初始化3個屬性。通過定義這個類,也就定義了一個引用類型的數據類型:Email。
源文件: Email.java
public class Email { // 定義屬性 String address; String title; int group; // 定義一個構造器 public Student(String Email_address, String Email_title, int Email_group) { address = Email_address; title = Email_title; group = Email_group; } // 定義屬性“address”的設置方法 public void setAddress (String Email_address) { address = Email_address; } // 定義屬性“title”的獲取方法 public String getTitle() { return title; } // 其他屬性的設置和讀取方法從略 }
(2)再定義一個TestEmail.java類,用于說明引用類型的用法。
源文件:TestEmail.java
public class TestEmail { public static void main(String[] args) { Email e1; e1 = new Email("Android@gmail.com", "capter 3", 2); System.out.println("第一封郵件地址是:" + e1.getAddress()); Email e2; e2 = e1; e1.setAddress("Java@gmail.com"); System.out.println("第二封郵件地址是:" + e2.getAddress()); } }
執行上面的TestEmail應用程序,可以在控制臺上得到如下的輸出結果:
第一封郵件地址是:Android@gmail.com。
第二封郵件地址是:Java@gmail.com。
3.4.6 技能拓展任務:分析對象的構造和初始化
1.任務描述
分析任務四的代碼,了解對象的構造和初始化的原理和過程。
2.技能要點
□ 理解引用類型變量的初始化過程和內存分配過程。
3.任務實現過程
分析一下TestEmail.java中的代碼段:
Email e1; e1 = new Email("Android@gmail.com", "capter 3", 2); System.out.println("第一封郵件地址是:" + e1.getAddress()); Email e2; e2 = e1; e1.setAddress("Java@gmail.com"); System.out.println("第二封郵件地址是:" + e2.getAddress());
這個代碼段的作用是建立并初始化了兩個Email引用類型數據,以對象e1為例講解引用類型數據的初始化過程(對象的初始化過程)。
(1)執行語句“Email e1;”時,系統為引用類型變量e1分配引用空間(定長32位),此時只是定義了變量e1,還未進行初始化等工作,因此還不能調用Email類中定義的方法,如圖3-4所示為此時內存的分配情況。

圖3-4 步驟(1)執行后的內存情況
(2)執行語句“e1 = new Email("Android@gmail.com", "capter 3", 2);”,先調用構造方法創建一個Email類的對象——新對象分配的內存空間用來存儲該對象所有屬性(address, title,group)的值,并對各屬性的值進行默認的初始化(關于默認初始化請參考3.5節內容)。注意,在這個程序中,因為address和title的類型是String類型,也是屬于引用類型,所以它們的默認初始值也為null,圖3-5為此時內存中的情況。

圖3-5 步驟(2)執行后的內存情況
(3)接下來執行Email類的構造方法,繼續此新對象的初始化工作,構造方法中又要求對新構造的對象的成員變量進行賦值,因此,此時 address、title、group的值變成了"Android@gmail.com"、"capter 3"和2,圖3-6所示為此時的內存情況。

圖3-6 步驟(3)執行后的內存情況
(4)至此,一個Email類的新的對象的構造和初始化構成已完成。最后再執行“e1 = new Email("Android@gmail.com", "capter 3", 2)”中的“=”號賦值操作,將新創建對象存儲空間的首地址賦值給Email類型變量e1,如圖3-7所示為此時的內存情況。

圖3-7 執行步驟(4)的內存情況
于是引用類型變量e1和一個具體的對象建立了聯系,稱s1是對該對象的一個引用。最后,總結一下對象的構造及初始化程序的步驟:
(1)分配內存空間。
(2)進行屬性的默認初始化。
(3)進行屬性的顯式初始化。
(4)執行構造方法。
(5)為引用型變量賦值。
- Flask Web全棧開發實戰
- JavaScript全程指南
- 精通軟件性能測試與LoadRunner實戰(第2版)
- Python高效開發實戰:Django、Tornado、Flask、Twisted(第2版)
- Visual Basic程序設計習題解答與上機指導
- MySQL數據庫基礎實例教程(微課版)
- 零基礎學單片機C語言程序設計
- JAVA程序設計實驗教程
- 量化金融R語言高級教程
- Haskell Data Analysis Cookbook
- Learning Apache Karaf
- Building Dynamics CRM 2015 Dashboards with Power BI
- 軟件體系結構
- Django 5企業級Web應用開發實戰(視頻教學版)
- Learning Unreal Engine Game Development