java筆記----Object小結

初識Object

位於Java.lang.Object 中,編譯時會自動導入:
(1)超類,所有類都直接或間接地繼承這個類;
(2)所有對象(包括數組)都實現這個類的方法;
(3)Object 類型的變量,可以裝載任何類型的對象。

Object方法(共11種)

簡單介紹常用的5個方法
(1) public String toString()
return getClass().getName() + “@” + Integer.toHexString(hashCode());
默認返回的是一個類名@對象的hashcode值的十六進制(0~ffffff)
將一個對象轉成一個字符串,建議所有子類重寫該方法

特別說明:
當我們打印一個對象==>System.out.println(Object)的時候,JVM會自動調用這個對象的toString()方法

(2)public final native Class<?> getClass();

==>返回的是Object的運行時類

**(3)protected void finalize() **
在實際中,不是程序員調用,而是JVM幫我們自動調用
這個方法一般在該對象被GC回收之前一刻調用==>臨終遺言
如果你的類不是系統類型,不需要重寫,像FileInputStream等和操作系統底層資源有關係的類型才需要重寫,爲什麼呢?
因爲系統資源往往是和操作系統底層的東西有關,而底層,大多是用C/C++實現,C/C++對象的回收,就需要我們手動回收
特別說明:
每一個對象的finalize()只會調用一次,若在finalize()中,有某句代碼,使得當前對象被重新引用,會使得這個對象復活
那麼等他再次成爲垃圾的時候就會直接被回收,不會再調用這個方法。

面試題final.finalize,finally的區別
finalize()是對象被確認爲垃圾(不再有對該對象的引用時),由垃圾回收器去調用,每個對象調用一次

(4)public int hashCode()
返回對象的哈希碼值
==》每個對象都會有一個數字代表這個對象,理想狀態下是一個對象對應一個哈希值
支持這種方法是爲了散列表,如HashMap提供的那樣 。

規定:

A:如果一個對象的內容沒用改變。在執行Java應用程序時,多次在同一個對象上調用該方法, hashCode方法必須始終返回相同的整數,前提是修改了對象中equals比較中的信息。
B:如果equals(Object)方法兩個對象相等,則在調用hashCode方法必須產生相同的整數結果。
C:如果兩個對象equals(Object)不相等,那麼調用hashCode方法產生不同的整數結果,也可能相同。
equals(Object)不等,hashCode相等的特例如下:

System.out.println("Aa".hashCode());//2112
System.out.println("BB".hashCode());//2112

(但是,程序員應該意識到,爲不等對象生成不同的整數結果會提高哈希表的性能。 )

(5)public boolean equals(Object obj)

  • 1:建議子類重寫是,要一起將hashCode也重寫,保證equals()方法兩個對象相等,則在調用hashCode方法必須產生相同的整數結果
  • 2:重寫遵循原則:
    自反性: x.equals(x) 爲true
    對稱的 :x.equals(y) 爲true,則y.equals(x) 爲true(對於任何非空引用值x和y )
    傳遞性 :x.equals(y) 爲true,y.equals(z) 爲true,則z.equals(x) 爲true(對於任何非空引用值x和y,z )
    一致性 :對於任何非空引用值x和y ,多次調用x.equals(y)始終返回true或始終返回false ,沒有設置中使用的信息equals比較上的對象被修改。
    對於任何非空的參考值x , x.equals(null)應該返回false 。

例子:

	public static class Student {
		private String name;
		private int id;	
		public Student(String name, int id) {
			super();
			this.name = name;
			this.id = id;
		}
		public Student() {
			super();
		}
		@Override
		public String toString() {
			return "Student [name=" + name + ", id=" + id + "]";
		}	
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			//result = prime * result + getEnclosingInstance().hashCode();
			result = prime * result + id;
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			return result;
		}		
		/*
		 * s1.equals(s2)
		 * this  ->s1
		 * obj ->s2
		 */	
		@Override
		public boolean equals(Object obj) {
			if (this == obj)//地址相同,直接返回
				return true;
			if (obj == null) //既然能進入到該方法,則表明s1必定不爲空,否則會報空指針異常
			//當obj==null,則兩者內容必然不相等	
				return false;			
			/*
			 * 既然能進入到該方法,則表明s1必然爲student類型,而obj可能不是Student類型,因此要獲取obj的運行時類型
			 */
			if (getClass() != obj.getClass())
				return false;
			//obj向下轉型,否則,obj爲Object類型,無法訪問到Student的成員變量id,name
			//不需要instanceof來判斷obj類型,因爲,如obj不是Student,上一個判斷已經返回false
			Student other = (Student) obj;
			if (id != other.id)
				return false;			
			if (name == null) {//this.name ==null
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			/*
			 * 不可以if(name == other.name)
			 * 因爲這樣就就比較的是對象的地址,而不是內容,
			 * if(name.equals(other.name))
			 * 這樣的話,如果name爲空,就會報空指針異常
			 * equals()的調用者要確保是不爲空的。
			 */
			return true;
		}


	
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章