java object 详解_Java基础之Object类详解
類Object是類層次結構的根類。每個類都直接或者間接地繼承Object類。所有對象(包括數組)都實現這個類的方法。Object類中的構造方法只有一個,并且是無參構造方法,這說明每個類中默認的無參構造方法調用的就是Object類的無參構造方法。
1、hashCode方法
hashCode方法返回給調用者此對象的哈希碼(其值由一個hash函數計算得來,一般是通過將該對象的內部地址轉換成一個整數)。這個方法通常用在基于hash的集合類中(像java.util.HashMap,java.until.HashSet和java.util.Hashtable)以提高性能。
1 @Test2 public voidtestHashCode() {3 Student student = newStudent();4
5 for (int i = 0; i < 3; i++) {6 System.out.println(student.hashCode());7 }8 }
1 249123537
2 249123537
3 249123537
我們可以看到運行了3次(Student類在文章最后),結果是一樣的,Java中對hashCode方法有如下約定:
在Java應用程序執行期間,在對同一對象多次調用hashCode方法時,必須一致地返回相同的整數,前提是將對象進行equals比較時所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
如果根據equals(Object)方法,兩個對象是相等的,那么對這兩個對象中的每個對象調用hashCode方法都必須生成相同的整數結果。
如果根據equals(java.lang.Object)方法,兩個對象不相等,那么對這兩個對象中的任一對象上調用hashCode方法不要求一定生成不同的整數結果。但是,程序員應該意識到,為不相等的對象生成不同整數結果可以提高哈希表的性能。
上面3句話可以理解為:
兩個對象相等 <=> equals相等? => hashCode相等
hasCode不相等 => equals不相等 <=> 兩個對象不相等
說來說去還是不知道這個hasCode方法是用來做什么的,上面提到該方法通常用在基于hash的集合類中,以提高性能,以Set集合為例,當往集合中添加一個新的對象時,需要知道在當前集合中是否存在存在該對象,Java會先調用hasCode方法判斷集合中是否有對象的哈希碼值與新的對象相等,如果不相等,則添加,如果相等,則繼續用equals方法判斷2個對象是否相等,只有當哈希碼相等時,并且equals方法返回為true時,2個對象才認為是相等的。
2、equals方法
該方法可以用來檢查一個對象與調用這個equals()的這個對象是否相等。equals字面意思是相等,說到相等,我們想到==這個運算符也是用來比較相等的,那么這兩個有什么區別呢,當==用于基本類型時比較的是基本類型的值是否相同,用于引用類型時,比較的是引用類型的地址是否指向同一個地方,Object中的equals方法與==運算符是一樣的
1 public booleanequals(Object obj) {2 return (this ==obj);3 }
既然有了==運算符,那還需要equals方法做什么呢,通常情況下,比較2個兩個對象的地址值意義不大,所以需要重寫Object類中的equals方法來滿足自己的需求,例如String類中的equals方法表示的是字符串的內容是否相等。
1 public booleanequals(Object anObject) {2 if (this ==anObject) {3 return true;4 }5 if (anObject instanceofString) {6 String anotherString =(String) anObject;7 int n =value.length;8 if (n ==anotherString.value.length) {9 char v1[] =value;10 char v2[] =anotherString.value;11 int i = 0;12 while (n-- != 0) {13 if (v1[i] !=v2[i])14 return false;15 i++;16 }17 return true;18 }19 }20 return false;21 }
如果重寫了equals方法,則hashCode也有必要重寫。
3、getClass方法
返回此 Object 的運行時類(類對象),我們知道類是對具有一組相同特征或行為的實例的抽象并進行描述,對象則是此類所描述的特征或行為的具體實例。作為類,其本身也具有某些共同的特性,如都具有類名稱、由類加載器去加載,都具有包,具有父類,屬性和方法等。在Java中用Class這個類來表示其他類所具有的這些特征,因此,類本身也都是屬于Class類的對象。為了與平時所說的對象區分開,通常情況稱之為類對象。
1 @Test2 public voidtestGetClass() {3 Student student = newStudent();4 System.out.println(student.getClass());5 }
class com.java.test.Student
4、toString方法
返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。我們看Object類中的toString方法
1 publicString toString() {2 return getClass().getName() + "@" +Integer.toHexString(hashCode());3 }
當我們使用System.out.println(object)時,內部也是通過調用toString()來實現的。
1 @Test2 public voidtestToString() {3 Student student = newStudent();4 System.out.println(student);5 System.out.println(student.toString());6 System.out.println(student.getClass().getName() + "@" +Integer.toHexString(student.hashCode()));7 }
由于這個信息一般沒有什么太大作用,所以建議所有子類都重寫此方法。 重寫了Student類中的toString方法后
1 Student [name=null, age=0]2 Student [name=null, age=0]
這時候的信息我們就可以很容易的理解了。
5、clone方法
創建并返回此對象的一個副本。副本可以這么理解,原來有一個文檔,通過Ctrl+C復制,然后Ctrl+V黏貼一個新的文檔出來,這個新的文檔就叫做文檔的副本,你在副本上面所做的操作不會影響到原來的文檔。注意在調用clone()方法時,被調用對象需要實現Cloneable接口,如果沒有實現Cloneable接口,并且子類直接調用Object類的clone()方法,則會拋出CloneNotSupportedException異常。Cloneable接口是標記接口,接口本身不包含任何方法,表示實現了這個接口,就可以實現對象的復制了。
1 @Test2 public void testClone() throwsCloneNotSupportedException {3 Student student1 = new Student("John", 23);4 Student student2 =(Student) student1.clone();5 System.out.println(student1);6 System.out.println(student2);7 System.out.println("改變student1的屬性值后:");8 student1.setName("Jack");9 student1.setAge(22);10 System.out.println(student1);11 System.out.println(student2);12 }
1 Student [name=John, age=23]2 Student [name=John, age=23]3 改變student1的屬性值后:4 Student [name=Jack, age=22]5 Student [name=John, age=23]
從運行結果也可以看出,被調用對象student1更改了屬性值后,不會影響到副本的屬性值,也說明了兩者在堆空間中的位置不同。
6、finalize方法
1 protected void finalize() throws Throwable { }
當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。通常情況下,這個方法一般不會用到。
附完整代碼:
1 packagecom.java.test;2
3 importorg.junit.Test;4
5 public classStudentTest {6
7 @Test8 public voidtestHashCode() {9 Student student = newStudent();10
11 for (int i = 0; i < 3; i++) {12 System.out.println(student.hashCode());13 }14 }15
16 @Test17 public voidtestGetClass() {18 Student student = newStudent();19 System.out.println(student.getClass());20 }21
22 @Test23 public voidtestToString() {24 Student student = newStudent();25 System.out.println(student);26 System.out.println(student.toString());27 System.out.println(student.getClass().getName() + "@" +Integer.toHexString(student.hashCode()));28 }29
30 @Test31 public void testClone() throwsCloneNotSupportedException {32 Student student1 = new Student("John", 23);33 Student student2 =(Student) student1.clone();34 System.out.println(student1);35 System.out.println(student2);36 System.out.println("改變student1的屬性值后:");37 student1.setName("Jack");38 student1.setAge(22);39 System.out.println(student1);40 System.out.println(student2);41 }42 }
1 packagecom.java.test;2
3 public class Student implementsCloneable {4 privateString name;5 private intage;6
7 publicStudent() {8 super();9 }10
11 public Student(String name, intage) {12 super();13 this.name =name;14 this.age =age;15 }16
17 publicString getName() {18 returnname;19 }20
21 public voidsetName(String name) {22 this.name =name;23 }24
25 public intgetAge() {26 returnage;27 }28
29 public void setAge(intage) {30 this.age =age;31 }32
33 @Override34 publicString toString() {35 return "Student [name=" + name + ", age=" + age + "]";36 }37
38 @Override39 protected Object clone() throwsCloneNotSupportedException {40 return super.clone();41 }42
43 }
總結
以上是生活随笔為你收集整理的java object 详解_Java基础之Object类详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java abort_Java中“...
- 下一篇: java 异常堆栈输出_打印Java异常