雖然 Java 語言是典型的面向對象編程語言,但其中的八種基本數據類型并不支持面向對象編程,基本類型的數據不具備“對象”的特性——不攜帶屬性、沒有方法可調用。 沿用它們只是為了迎合人類根深蒂固的習慣,并的確能簡單、有效地進行常規數據處理。
這種借助于非面向對象技術的做法有時也會帶來不便,比如引用類型數據均繼承了 Object 類的特性,要轉換為 String 類型(經常有這種需要)時只要簡單調用 Object 類中定義的toString()即可,而基本數據類型轉換為 String 類型則要麻煩得多。為解決此類問題 ,Java為每種基本數據類型分別設計了對應的類,稱之為包裝類(Wrapper Classes),也有教材稱為外覆類或數據類型類。
每個包裝類的對象可以封裝一個相應的基本類型的數據,并提供了其它一些有用的方法。包裝類對象一經創建,其內容(所封裝的基本類型數據值)不可改變。
基本類型和對應的包裝類可以相互裝換:
由基本類型向對應的包裝類轉換稱為裝箱,例如把 int 包裝成 Integer 類的對象;
包裝類向對應的基本類型轉換稱為拆箱,例如把 Integer 類的對象重新簡化為 int。
包裝類的應用
八個包裝類的使用比較相似,下面是常見的應用場景。
1) 實現 int 和 Integer 的相互轉換
可以通過 Integer 類的構造方法將 int 裝箱,通過 Integer 類的 intValue 方法將 Integer 拆箱。例如:
1
2
3
4
5
6
7
8
9
10
11
|
public class Demo { public static void main(String[] args) { int m = 500 ; Integer obj = new Integer(m); // 手動裝箱 int n = obj.intValue(); // 手動拆箱 System.out.println( "n = " + n); Integer obj1 = new Integer( 500 ); System.out.println( "obj 等價于 obj1?" + obj.equals(obj1)); } } |
運行結果:
1
2
|
n = 500 obj 等價于 obj1?true |
2) 將字符串轉換為整數
Integer 類有一個靜態的 paseInt() 方法,可以將字符串轉換為整數,語法為:
1
|
parseInt(String s, int radix); |
s 為要轉換的字符串,radix 為進制,可選,默認為十進制。
下面的代碼將會告訴你什么樣的字符串可以轉換為整數:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Demo { public static void main(String[] args) { String str[] = { "123" , "123abc" , "abc123" , "abcxyz" }; for (String str1 : str){ try { int m = Integer.parseInt(str1, 10 ); System.out.println(str1 + " 可以轉換為整數 " + m); } catch (Exception e){ System.out.println(str1 + " 無法轉換為整數" ); } } } } |
運行結果:
1
2
3
4
|
123 可以轉換為整數 123 123abc 無法轉換為整數 abc123 無法轉換為整數 abcxyz 無法轉換為整數 |
3) 將整數轉換為字符串
Integer 類有一個靜態的 toString() 方法,可以將整數轉換為字符串。例如:
1
2
3
4
5
6
7
|
public class Demo { public static void main(String[] args) { int m = 500 ; String s = Integer.toString(m); System.out.println( "s = " + s); } } |
運行結果:
1
|
s = 500 |
自動拆箱和裝箱
上面的例子都需要手動實例化一個包裝類,稱為手動拆箱裝箱。Java 1.5(5.0) 之前必須手動拆箱裝箱。
Java 1.5 之后可以自動拆箱裝箱,也就是在進行基本數據類型和對應的包裝類轉換時,系統將自動進行,這將大大方便程序員的代碼書寫。例如:
1
2
3
4
5
6
7
8
9
10
11
|
public class Demo { public static void main(String[] args) { int m = 500 ; Integer obj = m; // 自動裝箱 int n = obj; // 自動拆箱 System.out.println( "n = " + n); Integer obj1 = 500 ; System.out.println( "obj 等價于 obj1?" + obj.equals(obj1)); } } |
運行結果:
1
2
|
n = 500 obj 等價于 obj1?true |
自動拆箱裝箱是常用的一個功能,讀者需要重點掌握。
包不但可以包含類,還可以包含接口和其他的包。
目錄以"\"來表示層級關系,例如 E:\Java\workspace\Demo\bin\p1\p2\Test.java。
包以"."來表示層級關系,例如 p1.p2.Test 表示的目錄為 \p1\p2\Test.class。
如何實現包
通過 package 關鍵字可以聲明一個包,例如:
1
|
package p1.p2; |
必須將 package 語句放在所有語句的前面,例如:
1
2
3
4
5
6
|
package p1.p2; public class Test { public Test(){ System.out.println( "我是Test類的構造方法" ); } } |
表明 Test 類位于 p1.p2 包中。
包的調用
在Java中,調用其他包中的類共有兩種方式。
1) 在每個類名前面加上完整的包名
程序舉例:
1
2
3
4
5
6
|
public class Demo { public static void main(String[] args) { java.util.Date today= new java.util.Date(); System.out.println(today); } } |
運行結果:
1
|
Wed Dec 03 11:20:13 CST 2014 |
2) 通過 import 語句引入包中的類
程序舉例:
1
2
3
4
5
6
7
8
9
|
import java.util.Date; // 也可以引入 java.util 包中的所有類 // import java.util.*; public class Demo { public static void main(String[] args) { Date today= new Date(); System.out.println(today); } } |
運行結果與上面相同。
實際編程中,沒有必要把要引入的類寫的那么詳細,可以直接引入特定包中所有的類,例如 import java.util.*;。
類的路徑
Java 在導入類時,必須要知道類的絕對路徑。
首先在 E:\Java\workspace\Demo\src\p0\ 目錄(E:\Java\workspace\Demo\src\ 是項目源文件的根目錄)下創建 Demo.java,輸入如下代碼:
1
2
3
4
5
6
7
|
package p0; import p1.p2.Test; public class Demo{ public static void main(String[] args){ Test obj = new Test(); } } |
再在 E:\Java\workspace\Demo\src\p1\p2 目錄下創建 Test.java,輸入如下代碼:
1
2
3
4
5
6
|
package p1.p2; public class Test { public Test(){ System.out.println( "我是Test類的構造方法" ); } } |
假設我們將 classpath 環境變量設置為 .;D:\Program Files\jdk1.7.0_71\lib,源文件 Demo.java 開頭有 import p1.p2.Test; 語句,那么編譯器會先檢查 E:\Java\workspace\Demo\src\p0\p1\p2\ 目錄下是否存在 Test.java 或 Test.class 文件,如果不存在,會繼續檢索 D:\Program Files\jdk1.7.0_71\lib\p1\p2\ 目錄,兩個目錄下都不存在就會報錯。顯然,Test.java 位于 E:\Java\workspace\Demo\src\p1\p2\ 目錄,編譯器找不到,會報錯,怎么辦呢?
可以通過 javac 命令的 classpath 選項來指定類路徑。
打開CMD,進入 Demo.java 文件所在目錄,執行 javac 命令,并將 classpath 設置為 E:\Java\workspace\Demo\src,如下圖所示:
運行Java程序時,也需要知道類的絕對路徑,除了 classpath 環境變量指定的路徑,也可以通過 java 命令的 classpath 選項來增加路徑,如下圖所示:
注意 java 命令與 javac 命令的區別,執行 javac 命令需要進入當前目錄,而執行 java 命令需要進入當前目錄的上級目錄,并且類名前面要帶上包名。
可以這樣來理解,javac是一個平臺命令,它對具體的平臺文件進行操作,要指明被編譯的文件路徑。而java是一個虛擬機命令,它對類操作,即對類的描述要用點分的描述形式,并且不能加擴展名,還要注意類名的大小寫。
這些命令比較繁雜,實際開發都需要借助 Eclipse,在Eclipse下管理包、編譯運行程序都非常方便。Eclipse 實際上也是執行這些命令。
包的訪問權限
被聲明為 public 的類、方法或成員變量,可以被任何包下的任何類使用,而聲明為 private 的類、方法或成員變量,只能被本類使用。
沒有任何修飾符的類、方法和成員變量,只能被本包中的所有類訪問,在包以外任何類都無法訪問它。