Day13 Object類,包裝類
技術標籤:Java學習 30天java
Day13
instanceof 操作符(關鍵字)
x instanceof A //檢驗x是不是A類物件,返回值為 boolean
// 要求 x 和 A 必須是 子類父類的關係,否則編譯錯誤
子類呼叫特有的方法
在多型的應用時,記憶體中實際上已經載入了子類特有的屬性方法。但由於變數宣告是父類型別,導致編譯時只能呼叫的父類中定義過的方法,子類特有的方法不能呼叫。
可以使用強制型別轉換將物件賦值給子類物件,從而呼叫子類特有的方法。
Person - > Man
Person p = new Man();
p.eat(); // Right
p.earnMoney (); // Wrong
Man m = p; // Wrong
Man m = (Man)p; // Wrong
m.earnMoney();// Right
低->高 自動,高->低 強制
使用強制轉換,可能ClassCastException異常
此時需要使用instanceof判斷
為了避免出現ClassCastException異常,在向下轉型之前進行instanceof判斷
如果,x instanceof A :true,x instanceof B:true 則AB也可以進行轉換
向下轉型要求 new 的是 子類
Object類
- Object類是所有java類的根父類
- 如果在類的宣告中沒有使用extends指明其父類,預設繼承java.lang.Object類
- Object類中宣告的功能(屬性,方法)具有通用性
- Object類中聲明瞭一個空參構造器
方法:
- clone()
- equals()
- finalize()垃圾回收,在沒有物件指向的時候自動執行,然後執行垃圾回收機制==子類重寫此方法,可以在釋放物件前進行一些操作
- getClass()獲得自身的類
- int hashCode()返回自身雜湊值
- toString()返回記憶體值?列印物件值時呼叫
== 和 equals()區別
== :
可以使用在 基本資料型別變數 和 引用資料型別變數中
比較特別的,10 == 10.0 : ture
當比較的是基本資料型別,比較兩個變數儲存的資料是否相(不一定要型別相同)
當比較的是引用資料型別,比較兩個物件的地址值是否相同,即兩個引用是否指向同一個物件主體。
equals():
是一個java.lang.Object的方法,而非運算子
只適用於引用資料型別 (不能用於引用資料型別)
Object類中equals()的定義
public boolean equals(Object obj){ return (this == obj); } //說明:Object類中定義的equals()和==的作用是相同的,比較兩個物件的地址值是否相同,即兩個引用是否指向相同物件 //即:若沒有重寫,預設為==
像String,Date,File,包裝類等,都重寫了Object類equals()方法。重寫以後,比較的不是地址值,而是兩個物件的實體是否相同。
通常情況下,我們自己定義的類使用equals(),通常也是比較兩者實體內容是否都相同,我們應當自行重寫該函式。
重寫的原則:比較兩個物件的實體內容(需要強制轉換)
對稱性:x.equals(y) <-> y.equals(x)
自反性: x.equals(x)
傳遞性: x.equals(y) ,y.equals(z) -> x.equals(z)
一致性: 可重複
任何情況下,x.equals(null) :false
x.equals(與x不同的類的物件):false
可以使用IDE的自動生成equals()
所以Answer:
==既可以比較基本資料型別,也可以比較引用資料型別,對於基本資料型別比較值,對於引用資料型別是比較記憶體地址
equals的話,屬於java.lang.Object類的方法,如果該方法沒有重寫,預設等同於==,我們可以看到,String等類的equals()的方法都是被重寫過的,而且String類在日常開發中用的比較多,久而久之,形成了equals就是比較值的錯誤觀點
具體看自定義型別及其父類中有沒有重寫equals方法類判斷
通常,重寫equals方法,要比較類中的相應屬性是否都相等
final ,finally,finalize 區別?
toString()
-
當我們輸出一個物件的引用,實際呼叫該物件的toString()
-
Object類中toString()的定義:
public String toString(){ return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
-
像String,Date,File,包裝類等都重寫類Object類中的toString()方法
使得呼叫物件的toString()時,返回“實體內容”資訊
單元測試的使用方法
Java中的JUnit單元測試
步驟:
-
建立Java類,進行單元測試
Java類的要求:
- 此類為public
- 此類提供公共的無參構造器
-
此類中宣告單元測試方法
許可權為public,沒有返回值,沒有形參
-
此單元此時方法上需宣告註解:@Test,並在單元測試類中匯入 org.junit.Test;
-
宣告單元測試方法以後,可以在方法體中測試相關方法
-
寫完,雙擊測試方法,run as JUnitTest
綠條-無異常;紅條-異常;
包裝類的使用(Wrapper)
- 針對八種基本資料型別定義對應的引用型別——包裝類(封裝類)
- 有了類的特點,就可以呼叫類中的方法,Java才是真正面向物件
基本資料型別,String類,包裝類的轉換
// 基本資料型別 - 》包裝類
public void test1(){
int num1 = 10;
Integer in1 = new Integer(num1);
Integer in2 = new Integer("123");
Integer in3 = new Integer("123abc"); // Wrong
Integer in4 = new Integer(123);
Float f1 = new Float("123.0F");
Float f2 = new Float(123.0F);
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean("true123"); // 可通過,但b2.value : false;
}
//包裝類->基本資料型別
public void test2(){
Integer in1 = new Integer(123);
int i1 = in1.intValue();
}
JDK5.0 新增特性 自動裝箱,自動拆箱
// 自動裝箱
int num1 = 10;
Integer in1 = num1;
// 自動拆箱
Integer in1 = 10;
int num1 = in1;
但是,仍然不能像C++過載運算子那樣直接進行運算子運算
String型別 <- 基本資料型別,包裝類呼叫String過載的方法valueOf()
String型別 -> 基本資料型別,包裝類呼叫包裝類的parseXxx(String s)方法
- 對於Number類的,可能發生NumberFormatException,可能提供的String含有非數字內容
- boolean則非true即false
關於包裝類使用的面試題:
下列兩組程式碼輸出結果相同麼?分別是什麼?
public class day13 {
public static void main(String[] args){
Object o1 = true ? new Integer(1) : new Double(2.0);
Object o2;
if(true)
o2 = new Integer(1);
else
o2 = new Double(2.0);
System.out.println("o1 : " + o1);
System.out.println("o2 : " + o2);
System.out.println("o1 : " + o1 + " o2 : " + o2);
// 輸出為 1.0 1
// 這裡注意 三目運算子 會自動將 ‘:’ 兩側的 資料型別統一
}
}
判斷輸出結果?
Integer x = new Integer(1);
Integer y = new Integer(1);
System.out.println(x == y); // false
Integer m = 1;
Integer n = 1;
System.out.println(m == n); // true
Integer p = 128;
Integer q = 128;
System.out.println(p == q); // false
// 對於較小的 數字 -128~127 ,Integer中封裝類一個數組,儲存這些數字的位置,也就是說,當處於這個範圍時,其地址相同
// 超出這個範圍,則轉換為 new 物件的形式,地址值自然不同