文章目錄
6、內置的包裝類小結
Java 是一種面向對象的編程語言,Java 中的類把方法與數據類型連接在一起,構成了自包含式的處理單元。但在 Java 中不能定義基本類型對象,爲了能將基本類型視爲對象處理,並能連接相關方法,Java 爲每個基本類型都提供了包裝類
,如 int 型數值的包裝類 Integer,boolean 型數值的包裝類 Boolean 等。這樣便可以把這些基本類型轉換爲對象來處理了。
6.1 所有類的父類Object
Object 是 Java 類庫中的一個特殊類,也是所有類的父類。也就是說,Java 允許把任何類型的對象賦給 Object 類型的變量。當一個類被定義後,如果沒有指定繼承的父類,那麼默認父類就是 Object 類。
因此,以下兩個類表示的含義是一樣的。
public class MyClass{…}
等價於
public class MyClass extends Object {…}
由於 Java 所有的類都是 Object 類的子類,所以任何 Java 對象都可以調用 Object 類的方法
。常見的Object的方法如表 1 所示。
方法 | 說明 |
---|---|
Object clone() | 創建與該對象的類相同的新對象 |
boolean equals(Object) | 比較兩對象是否相等 |
void finalize() | 當垃圾回收器確定不存在對該對象的更多引用時,對象垃圾回收器調用該方法 |
Class getClass() | 返回一個對象運行時的實例類 |
int hashCode() | 返回該對象的散列碼值 |
void notify() | 激活等待在該對象的監視器上的一個線程 |
void notifyAll() | 激活等待在該對象的監視器上的全部線程 |
String toString() | 返回該對象的字符串表示 |
void wait() | 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待 |
其中,toString()、equals() 方法和 getClass() 方法在 Java 程序中比較常用。
6.1.1 toString() 方法
toString() 方法返回該對象的字符串,當程序輸出一個對象或者把某個對象和字符串進行連接運算時,系統會自動調用該對象的 toString() 方法返回該對象的字符串表示。
Object 類的 toString() 方法返回“運行時類名@十六進制哈希碼
”格式的字符串,但很多類都重寫了 Object 類的 toString() 方法,用於返回可以表述該對象信息的字符串。
哈希碼(hashCode),每個 Java 對象都有哈希碼屬性,哈希碼可以用來標識對象,提高對象在集合操作中的執行效率。
先看以下代碼:
package 內置包裝類的Test;
class Test{
//該類默認繼承Object類
}
public class Object_ThreeStaff {
/**
* 需求:演示Object類的三個常用的成員方法
* 1.toString;2。
*/
public static void main(String[]args){
Test test = new Test();//默認構造方法
System.out.println("不加toString:"+test);
System.out.println("加了toString:"+test.toString());
}
}
輸出結果爲:
以上的程序是隨機輸出了一些地址信息,從程序的運行結果可以清楚的發現,加和不加 toString() 的最終輸出結果是一樣的,包名類名@實例對象哈希碼
;也就是說對象輸出時一定會調用 Object 類中的 toString() 方法打印內容。所以利用此特性就可以通過 toString() 取得一些對象的信息,如下面代碼。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "姓名:" + this.name + ":年齡" + this.age;
}
public static void main(String[] args) {
Person per = new Person("李子", 30);// 實例化Person對象
System.out.println("對象信息:" + per);// 打印對象調用toString()方法
}
}
輸出結果爲:
對象信息:姓名:李子:年齡30
程序中的 Person 類中重寫了 Object 類中的 toString() 方法,這樣直接輸出對象時調用的是被子類重寫過的 toString() 方法。
6.1.2 equals() 方法
在前面學習字符串比較時,曾經介紹過兩種比較方法,分別是==運算符
和 equals() 方法
,==運算符是比較兩個引用變量是否指向同一個實例,equals() 方法是比較兩個對象的內容是否相等
,通常字符串的比較只是關心內容是否相等。
其使用格式如下:
boolean result = obj.equals(Object o);
其中,obj 表示要進行比較的一個對象,o 表示另一個對象。
6.1.3 getClass() 方法
getClass() 方法返回對象所屬的類,是一個 Class 對象
。通過 Class 對象可以獲取該類的各種信息,包括類名、父類以及它所實現接口的名字等。
例 2
編寫一個實例,演示如何對 String 類型調用 getClass() 方法,然後輸出其父類及實現的接口信息。具體實現代碼如下:
package 內置包裝類的Test;
public class Demo類 {
public static void printClassInfo(Object obj) {
// 獲取類名
System.out.println("類名:" + obj.getClass().getName());
// 獲取父類名
System.out.println("父類:" + obj.getClass().getSuperclass().getName());
System.out.println("實現的接口有:");
// 獲取實現的接口並輸出
for (int i = 0; i < obj.getClass().getInterfaces().length; i++) {
System.out.println(obj.getClass().getInterfaces()[i]);
}
}
public static void main(String[] args) {
String strObj = new String();
printClassInfo(strObj);//靜態方法在類定義時就已經分配內存了,可以直接調用。
}
}
該程序的運行結果如下:
類名:java.lang.String
父類:java.lang.Object
實現的接口有:
interface java.io.Serializable
interface java.lang.Comparable
interface java.lang.CharSequence
6.1.4 object類的應用
上個例子裏的pringClassInfo函數的參數可以接收任意引用類型的對象:
既然 Object 類是所有對象的父類,則所有的對象都可以向 Object 進行轉換,在這其中也包含了數組和接口類型,即一切的引用數據類型都可以使用 Object 進行接收。
interface A {
public String getInfo();
}
class B implements A {
public String getInfo() {
return "Hello World!!!";
}
}
public class ObjectDemo04 {
public static void main(String[] args) {
// 爲接口實例化
A a = new B();
// 對象向上轉型
Object obj = a;
// 對象向下轉型
A x = (A) obj;
System.out.println(x.getInfo());
}
}
輸出結果爲:
Hello World!!!
通過以上代碼可以發現,雖然接口不能繼承一個類,但是依然是 Object 類的子類,因爲接口本身是引用數據類型,所以可以進行向上轉型操作。
同理,也可以使用 Object 接收一個數組,因爲數組本身也是引用數據類型。
public class ObjectDemo05 {
public static void main(String[] args) {
int temp[] = { 1, 3, 5, 7, 9 };
// 使用object接收數組
Object obj = temp;
// 傳遞數組引用
print(obj);
}
public static void print(Object o) {
// 判斷對象的類型
if (o instanceof int[]) {
// 向下轉型
int x[] = (int[]) o;
// 循環輸出
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + "\t");
}
}
}
}
輸出結果爲:
1 3 5 7 9
以上程序使用 Object 接收一個整型數組,因爲數組本身屬於引用數據類型,所以可以使用 Object 接收數組內容,在輸出時通過 instanceof 判斷類型是否是一個整型數組,然後進行輸出操作。
因爲 Object 類可以接收任意的引用數據類型,所以在很多的類庫設計上都採用 Object 作爲方法的參數,這樣操作起來會比較方便。
6.2 Integer類(基本數據包裝類基本用法相似)
Integer 類在對象中包裝了一個基本類型 int 的值。Integer 類對象包含一個 int 類型的字段。此外,該類提供了多個方法,能在 int 類型和 String 類型之間互相轉換,還提供了處理 int 類型時非常有用的其他一些常量和方法。(Float,Double,Byte,Character類用法相似,差異不是很大,就只講Integer類)
6.2.1 Integer 類的構造方法
Integer 類中的構造方法有以下兩個:
Integer(int value):構造一個新分配的 Integer 對象,它表示指定的 int 值。
Integer(String s):構造一個新分配的 Integer 對象,它表示 String 參數所指示的 int 值。
例如,以下代碼分別使用以上兩個構造方法來獲取 Integer 對象:
Integer integer1 = new Integer(100); // 以 int 型變量作爲參數創建 Integer 對象
Integer integer2 = new Integer("100"); // 以 String 型變量作爲參數創建 Integer 對象
6.2.2 Integer 類的常用方法
在 Integer 類內部包含一些和 int 類型操作有關的方法,表 1 列出了這些常用的方法。
方法 | 返回值 | 功能 |
---|---|---|
byteValue() | byte | 以 byte 類型返回該 Integer 的值 |
shortValue() | short | 以 short 類型返回該 Integer 的值 |
intValue() | int | 以 int 類型返回該 Integer 的值 |
toString() | String | 返回一個表示該 Integer 值的 String 對象 |
equals(Object obj) | boolean | 比較此對象與指定對象是否相等 |
compareTo(Integer,anotherlnteger) | int | 在數字上比較兩個 Integer 對象,如相等,則返回 0;如調用對象的數值小於 anotherlnteger 的數值,則返回負值;如調用對象的數值大於 anotherlnteger 的數值,則返回正值 |
valueOf(String s) | Integer | 返回保存指定的 String 值的 Integer 對象 |
parseInt(String s) | int | 將數字字符串轉換爲 int 數值 |
在實際的編程過程中,經常將字符串轉換爲 int 類型的數值,或者將 int 類型的數值轉換爲對應的字符串。以下代碼演示如何實現這兩種功能:
String str = "456";
int num = Integer.parseInt(str); // 將字符串轉換爲int類型的數值
int i = 789;
String s = Integer.toString(i); // 將int類型的數值轉換爲字符串
注意:在實現將字符串轉換爲 int 類型數值的過程中,如果字符串中包含非數值類型的字符,則程序執行將出現異常。
例 1
編寫一個程序,在程序中創建一個 String 類型變量,然後將它轉換爲二進制、八進制、十進制和十六進制輸出。
public class Test03 {
public static void main(String[] args) {
int num = 40;
String str = Integer.toString(num); // 將數字轉換成字符串
String str1 = Integer.toBinaryString(num); // 將數字轉換成二進制
String str2 = Integer.toHexString(num); // 將數字轉換成八進制
String str3 = Integer.toOctalString(num); // 將數字轉換成十六進制
System.out.println(str + "的二進制數是:" + str1);
System.out.println(str + "的八進制數是:" + str3);
System.out.println(str + "的十進制數是:" + str);
System.out.println(str + "的十六進制數是:" + str2);
}
}
運行後的輸出結果如下:
40的二進制數是:101000
40的八進制數是:50
40的十進制數是:40
40的十六進制數是:28
6.2.3 Integer 類的常量
Integer 類包含以下 4 個常量。
常量名 | 含義 |
---|---|
MAX_VALUE | 值爲 231-1 的常量,它表示 int 類型能夠表示的最大值。 |
MIN_VALUE | 值爲 -231 的常量,它表示 int 類型能夠表示的最小值。 |
SIZE | 用來以二進制補碼形式表示 int 值的比特位數。 |
TYPE | 表示基本類型 int 的 Class 實例。 |
下面的代碼演示了 Integer 類中常量的使用。
int max_value = Integer.MAX_VALUE; // 獲取 int 類型可取的最大值
int min_value = Integer.MIN_VALUE; // 獲取 int 類型可取的最小值
int size = Integer.SIZE; // 獲取 int 類型的二進制位
Class c = Integer.TYPE; // 獲取基本類型 int 的 Class 實例
6.3 Number類(抽象類、父類)
Number 是一個抽象類,也是一個超類(即父類)。Number 類屬於 java.lang 包,所有的包裝類(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象類 Number 的子類。
Number 類定義了一些抽象方法,以各種不同數字格式返回對象的值。如 xxxValue() 方法,它將 Number 對象轉換爲 xxx 數據類型的值並返回。這些方法如下表所示:
方法 | 說明 |
---|---|
byte byteValue(); | 返回 byte 類型的值 |
double doubleValue(); | 返回 double 類型的值 |
float floatValue(); | 返回 float 類型的值 |
int intValue(); | 返回 int 類型的值 |
long longValue(); | 返回 long 類型的值 |
short shortValue(); | 返回 short 類型的值 |
我們知道抽象類不能直接實例化,而是必須實例化其具體的子類。如下代碼演示了 Number 類的使用:
Number num = new Double(12.5);//使用子類來實例化
System.out.println("返回 double 類型的值:" + num.doubleValue());
System.out.println("返回 int 類型的值:" + num.intValue());
System.out.println("返回 float 類型的值:" + num.floatValue());
執行上述代碼,輸出結果如下:
返回 double 類型的值:12.5
返回 int 類型的值:12
返回 float 類型的值:12.5
6.4 各種基本數據類型包裝類的常用量
6.4.1 Float 類的常用常量
在 Float 類中包含了很多常量,其中較爲常用的常量如下。
常量名 | 含義 |
---|---|
MAX_VALUE | 值爲 1.4E38 的常量,它表示 float 類型能夠表示的最大值。 |
MIN_VALUE | 值爲 3.4E-45 的常量,它表示 float 類型能夠表示的最小值。 |
MAX_EXPONENT | 有限 float 變量可能具有的最大指數。 |
MIN_EXPONENT | 標準化 float 變量可能具有的最小指數。 |
MIN_NORMAL | 保存 float 類型數值的最小標準值的常量,即 2-126。 |
NaN | 保存 float 類型的非數字值的常量。 |
SIZE | 用來以二進制補碼形式表示 float 值的比特位數。 |
TYPE | 表示基本類型 float 的 Class 實例。 |
例子
float max_value = Float.MAX_VALUE; // 獲取 float 類型可取的最大值
float min_value = Float.MIN_VALUE; // 獲取 float 類型可取的最小值
float min_normal = Float.MIN_NORMAL; // 獲取 float 類型可取的最小標準值
float size = Float.SIZE; // 獲取 float 類型的二進制位
6.4.2 Double 類的常用常量
在 Double 類中包含了很多常量,其中較爲常用的常量如下。
常量名 | 含義 |
---|---|
MAX_VALUE | 值爲 1.8E308 的常量,它表示 double 類型的最大正有限值的常量。 |
MIN_VALUE | 值爲 4.9E-324 的常量,它表示 double 類型數據能夠保持的最小正非零值的常量。 |
NaN | 保存 double 類型的非數字值的常量。 |
NEGATIVE_INFINITY | 保持 double 類型的負無窮大的常量。 |
POSITIVE_INFINITY | 保持 double 類型的正無窮大的常量。 |
SIZE | 用來以二進制補碼形式表示 double 值的比特位數。 |
TYPE | 表示基本類型 double 的 Class 實例。 |
6.4.3 Boolean 類的常用常量
在 Boolean 類中包含了很多的常量,其中較爲常用的常量如下。
常量名 | 含義 |
---|---|
TRUE | 對應基值 true 的 Boolean 對象。 |
FALSE | 對應基值 false 的 Boolean 對象。 |
TYPE | 表示基本類型 boolean 的 Class 對象。 |
6.4.4 Byte 類的常用常量
在 Byte 類中包含了很多的常量,其中較爲常用的常量如下。
常量名 | 含義 |
---|---|
MIN_VALUE | byte 類可取的最小值。 |
MAX_VALUE | byte 類可取的最大值。 |
SIZE | 用於以二進制補碼形式表示的 byte 值的位數。 |
TYPE | 表示基本類 byte 的 Class 實例。 |
6.5 System類詳解
System 類位於 java.lang 包,代表當前 Java 程序的運行平臺,系統級的很多屬性和控制方法都放置在該類的內部。由於該類的構造方法是 private 的,所以無法創建該類的對象,也就是無法實例化該類。
System 類提供了一些類變量和類方法,允許直接通過 System 類來調用這些類變量和類方法。
6.5.1 System 類的成員變量
System 類有 3 個靜態成員變量,分別是 PrintStream out、InputStream in 和 PrintStream err。
1. PrintStream out
標準輸出流。此流已打開並準備接收輸出數據。通常,此流對應於顯示器輸出或者由主機環境或用戶指定的另一個輸出目標。
例如,編寫一行輸出數據的典型方式是:
System.out.println(data);
其中,println 方法是屬於流類 PrintStream 的方法,而不是 System 中的方法。
2. InputStream in
標準輸入流。此流已打開並準備提供輸入數據。通常,此流對應於鍵盤輸入或者由主機環境或用戶指定的另一個輸入源。
3. PrintStream err
標準的錯誤輸出流。其語法與 System.out 類似,不需要提供參數就可輸出錯誤信息。也可以用來輸出用戶指定的其他信息,包括變量的值。
例 1
編寫一個 Java 程序,使用 System 類實現從鍵盤輸入字符並顯示出來。 具體實現代碼如下:
import java.io.IOException;
public class Test06 {
public static void main(String[] args) {
System.out.println("請輸入字符,按回車鍵結束輸入:");
int c;
try {
c = System.in.read(); // 讀取輸入的字符
while(c != '\r') { // 判斷輸入的字符是不是回車
System.out.print((char) c); // 輸出字符
c = System.in.read();
}
} catch(IOException e) {
System.out.println(e.toString());
} finally {
System.err.println();
}
}
}
以上代碼中,System.in.read() 語句讀入一個字符,read() 方法是 InputStream 類擁有的方法。
變量 c 必須用 int 類型而不能用 char 類型,否則會因爲丟失精度而導致編譯失敗。
以上的程序如果輸入漢字將不能正常輸出。如果要正常輸出漢字,需要把 System.in 聲明爲 InputStreamReader 類型的實例,最終在 try 語句塊中的代碼爲:
InputStreamReader in = new InputStreamReader(System.in, "GB2312");
c = in.read();
while(c != '\r') {
System.out.print((char) c);
c = in.read();
}
如上述代碼所示,語句 InputStreamReader in=new InputStreamReader(System.in,“GB2312”) 聲明一個新對象 in,它從 Reader 繼承而來,此時就可以讀入完整的 Unicode 碼,顯示正常的漢字。
6.5.2 System 類的成員方法
System 類中提供了一些系統級的操作方法,常用的方法有 arraycopy()、currentTimeMillis()、exit()、gc() 和 getProperty()。
1. arraycopy() 方法
該方法的作用是數組複製,即從指定源數組中複製一個數組,複製從指定的位置開始,到目標數組的指定位置結束。該方法的具體定義如下:
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
其中,src 表示源數組,srcPos 表示從源數組中複製的起始位置,dest 表示目標數組,destPos 表示要複製到的目標數組的起始位置,length 表示複製的個數。
例 2
下面的示例代碼演示了 arraycopy() 方法的使用:
public class System_arrayCopy {
public static void main(String[] args) {
char[] srcArray = {'A','B','C','D'};
char[] destArray = {'E','F','G','H'};
System.arraycopy(srcArray,1,destArray,1,2);
System.out.println("源數組:");
for(int i = 0;i < srcArray.length;i++) {
System.out.println(srcArray[i]);
}
System.out.println("目標數組:");
for(int j = 0;j < destArray.length;j++) {
System.out.println(destArray[j]);
}
}
}
如上述代碼,將數組 srcArray 中,從下標 1 開始的數據複製到數組 destArray 從下標 1 開始的位置,總共複製兩個。也就是將 srcArray[1] 複製給 destArray[1],將 srcArray[2] 複製給 destArray[2]。這樣經過複製之後,數組 srcArray 中的元素不發生變化,而數組 destArray 中的元素將變爲 E、B、C、 H,下面爲輸出結果:
源數組:
A
B
C
D
目標數組:
E
B
C
H
2. currentTimeMillis() 方法
該方法的作用是返回當前的計算機時間,時間的格式爲當前計算機時間與 GMT 時間(格林尼治時間)1970 年 1 月 1 日 0 時 0 分 0 秒所差的毫秒數。一般用它來測試程序的執行時間。例如:
long m = System.currentTimeMillis();
上述語句將獲得一個長整型的數字,該數字就是以差值表達的當前時間。
例 3
使用 currentTimeMillis() 方法來顯示時間不夠直觀,但是可以很方便地進行時間計算。例如,計算程序運行需要的時間就可以使用如下的代碼:
public class System_currentTimeMillis {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for(int i = 0;i < 100000000;i++) {
int temp = 0;
}
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("程序執行時間" + time + "秒");
}
}
上述代碼中的變量 time 的值表示代碼中 for 循環執行所需要的毫秒數,使用這種方法可以測試不同算法的程序的執行效率高低,也可以用於後期線程控制時的精確延時實現。
3. exit() 方法
該方法的作用是終止當前正在運行的 Java 虛擬機,具體的定義格式如下:
public static void exit(int status)
其中,status 的值爲 0 時表示正常退出,非零時表示異常退出。
使用該方法可以在圖形界面編程中實現程序的退出功能等。
4. gc() 方法
該方法的作用是請求系統進行垃圾回收,完成內存中的垃圾清除。至於系統是否立刻回收,取決於系統中垃圾回收算法的實現以及系統執行時的情況。定義如下:
public static void gc()
5. getProperty() 方法
該方法的作用是獲得系統中屬性名爲 key 的屬性對應的值
,具體的定義如下:
public static String getProperty(String key)
系統中常見的屬性名以及屬性的說明如表 1 所示。
屬性名 | 屬性說明 |
---|---|
java.version | Java 運行時環境版本 |
java.home | Java 安裝目錄 |
os.name | 操作系統的名稱 |
os.version | 操作系統的版本 |
user.name | 用戶的賬戶名稱 |
user.home | 用戶的主目錄 |
user.dir | 用戶的當前工作目錄 |
例 4
下面的示例演示了 getProperty() 方法的使用。
package 內置包裝類的Test;
public class GetPro {
public static void main(String[] args) {
String jversion = System.getProperty("java.version");
String oName = System.getProperty("os.name");
String user = System.getProperty("user.name");
String user_dir = System.getProperty("user.dir");
System.out.println("Java 運行時環境版本:"+jversion);
System.out.println("當前操作系統是:"+oName);
System.out.println("當前用戶是:"+user);
System.out.println("當前用戶的工作目錄是:"+user_dir);
}
}