摘要:如果我們想要多次輸出類中的成員信息,就需要多次書寫方法每用一次就得寫而調(diào)用就簡(jiǎn)單多了補(bǔ)充兩者等價(jià)輸出結(jié)果。注一般選擇重寫方法,比較對(duì)象的成員變量值是否相同,不過(guò)一般重寫都是自動(dòng)生成。
第三階段 JAVA常見(jiàn)對(duì)象的學(xué)習(xí) 第一章 常見(jiàn)對(duì)象——Object類 引言:
在講解Object類之前,我們不得不簡(jiǎn)單的提一下什么是API,先貼一組百度百科的解釋:
API(Application Programming Interface,應(yīng)用程序編程接口)是一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開發(fā)人員基于某軟件或硬件得以訪問(wèn)一組例程的能力,而又無(wú)需訪問(wèn)源碼,或理解內(nèi)部工作機(jī)制的細(xì)節(jié)。
簡(jiǎn)單的說(shuō):就是 Java 中有好多現(xiàn)成的類庫(kù),其中封裝了許多函數(shù),只提供函數(shù)名和參數(shù),但隱藏了函數(shù)的具體實(shí)現(xiàn),這些可見(jiàn)的部分作為與外界聯(lián)系的橋梁,也就是我們所稱的 API ,不過(guò)由于Java是開源的,所以這些隱藏的實(shí)現(xiàn)我們也是可以看到的。
(一) Object 類的概述(1) Object是類層次結(jié)構(gòu)的根類,所有的類都隱式的(不用寫extends)繼承自O(shè)bject類。
(2) Java 所有的對(duì)象都擁有Object默認(rèn)方法
(3) Object類的構(gòu)造方法有一個(gè),并且是無(wú)參構(gòu)造
這就對(duì)應(yīng)了前面學(xué)習(xí)中的一句話,子類構(gòu)造方法默認(rèn)訪問(wèn)父類的構(gòu)造是無(wú)參構(gòu)造
我們需要了解的方法又有哪些呢?
A: hashCode() B: getClass() C: finalize() D: clone
E: notify() F: notifyAll()
我們需要掌握的方法又有哪些呢?
A: toString() B: equals()
(1) hashCode返回對(duì)象的哈希值(散列碼),不是實(shí)際地址值,不過(guò)可以理解為地址值。
它實(shí)際上返回一個(gè)int型整數(shù),用于確定該對(duì)象在哈希表中的索引位置
暫時(shí)了解即可,學(xué)習(xí)集合框架內(nèi)容后將會(huì)專篇深入學(xué)習(xí)
//Student類 public class Student extends Object { }
//StudentDemo類 public class StudentDemo { public static void main(String[] args) { Student s1 = new Student(); System.out.println(s1.hashCode()); Student s2 = new Student(); System.out.println(s2.hashCode()); Student s3 = s1; System.out.println(s3.hashCode()); } } //運(yùn)行結(jié)果: 460141958 1163157884 460141958(2) getClass
返回對(duì)象的字節(jié)碼文件對(duì)象,在反射篇章詳細(xì)解釋, 暫做簡(jiǎn)單了解。
public class StudentDemo { public static void main(String[] args) { Student s = new Student(); Class c = s.getClass(); String str = c.getName(); System.out.println(str); //鏈?zhǔn)骄幊? String str2 = s.getClass().getName(); System.out.println(str2); } } //運(yùn)行結(jié)果 cn.bwh_02_getClass.Student cn.bwh_02_getClass.Student(3) finalize()
在對(duì)象將被垃圾回收器清除前調(diào)用,但不確定時(shí)間,并且對(duì)象的finalize()方法只會(huì)被調(diào)用一次,調(diào)用后也不一定馬上清除該對(duì)象。
(4) clone()以實(shí)現(xiàn)對(duì)象的克隆,包括成員變量的數(shù)據(jù)復(fù)制,但是它和兩個(gè)引用指向同一個(gè)對(duì)象是有區(qū)別的。
我們先來(lái)解釋一下后半句話
如果我們想要復(fù)制一個(gè)變量,可以這樣做 Eg:
int a = 20; int b = a;
那么我們想要復(fù)制一個(gè)對(duì)象,是不是也可以這樣做呢?
//Student public class Student { int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
//StudentDemo public class StudentDemo { public static void main(String[] args) { Student s1 = new Student(); s1.setAge(20); Student s2 = s1;//將引用賦值 System.out.println("學(xué)生1年齡:" + s1.getAge()); System.out.println("學(xué)生2年齡:" + s2.getAge()); System.out.println("------------------------------"); s2.setAge(25); System.out.println("學(xué)生1年齡:" + s1.getAge()); System.out.println("學(xué)生2年齡:" + s2.getAge()); } } //運(yùn)行結(jié)果 學(xué)生1年齡:20 學(xué)生2年齡:20 --------------------------- 學(xué)生1年齡:25 學(xué)生2年齡:25
很明顯,即使將對(duì)象s1賦值給對(duì)象s2,但是通過(guò)set傳值的時(shí)候,兩者仍然會(huì)同時(shí)變化,并沒(méi)有起到克隆(獨(dú)立)的作用,這是因?yàn)橘x值時(shí)只是將存儲(chǔ)在棧中,對(duì)對(duì)象的引用賦值,因此它們兩個(gè)的引用指向同一個(gè)對(duì)象(堆中),所以無(wú)論如何賦值,只要堆中的對(duì)象屬性發(fā)生了變化,通過(guò)引用顯示屬性的時(shí)候,均是相同的。
實(shí)現(xiàn)Cloneable接口
重寫clone方法
淺拷貝: 僅拷貝對(duì)象,不拷貝成員變量,僅復(fù)制了變量的引用,拷貝前后變量使用同一塊內(nèi)存,內(nèi)存銷毀后,必須重新定義(兩者同生共死)深拷貝: 不僅拷貝對(duì)象,也拷貝成員變量(真正意義上的復(fù)制, 兩者獨(dú)立無(wú)關(guān))
//淺拷貝 public class Person implements Cloneable{ private int age = 20; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
//深拷貝 public class Person implements Cloneable { public int age = 20; @Override protected Object clone() throws CloneNotSupportedException { //拷貝對(duì)象 Person person = (Person) super.clone(); //拷貝成員變量 person.age = (int) age.clone(); //返回拷貝對(duì)象 return person; } }
我們來(lái)利用淺拷貝解決剛開始那個(gè)問(wèn)題
//Person類,寫出get、set方法、重寫clone方法 //PersonDemo類 public class PersonDemo { public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person(); p1.setAge(20); Person p2 = (Person) p1.clone(); System.out.println("第一個(gè)人的年齡:"+ p1.getAge() ); System.out.println("第二個(gè)人的年齡:"+ p2.getAge() ); System.out.println("--------------------------"); p2.setAge(25); System.out.println("第一個(gè)人的年齡:"+ p1.getAge() ); System.out.println("第二個(gè)人的年齡:"+ p2.getAge() ); } } 運(yùn)行結(jié)果: 第一個(gè)人的年齡:20 第二個(gè)人的年齡:20 -------------------------- 第一個(gè)人的年齡:20 第二個(gè)人的年齡:25(5) wait、notify和notifyAll
三者屬于線程通信間的Api,此部分放在日后講
(6) toString()——重要public static toString(): 返回該對(duì)象的字符串表示
//Student類 public class Student { private String name; public int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
//StudentDemo類 package cn.bwh_04_toString; public class StudentDemo { public static void main(String[] args) { Student s = new Student(); s.setName("admin"); s.setAge(20); //直接輸出s也會(huì)默認(rèn)的調(diào)用toString方法 System.out.println(s.toString()); } } //通過(guò)set方法賦值后,直接調(diào)用toString() 運(yùn)行結(jié)果: cn.bwh_04_toString.Student@1b6d3586
很明顯,給我們返回這樣的信息意義是不大的,所以我們建議對(duì)所有子類重寫該方法
//在Student類中重寫 toString() @Override public String toString() { return "Student[" + "name=" + name + ", " + "age=" + age + "]"; //運(yùn)行結(jié)果: Student[name=admin, age=20]
通過(guò)重寫toString后,結(jié)果按照我們所定的規(guī)則以字符串的形式輸出
(重寫后會(huì)優(yōu)先使用類中的toString方法)
主要目的還是為了簡(jiǎn)化輸出
在類中重寫toString()后,輸出類對(duì)象就變得有了意義(輸出s 和 s.toString()是一樣的 ,不寫也會(huì)默認(rèn)調(diào)用),變成了我們實(shí)實(shí)在在的信息,而不是上面的cn.bwh_04_toString.Student@1b6d3586。
如果我們想要多次輸出 類中的成員信息,就需要多次書寫get方法(每用一次就得寫)
System.out.println("Student[" + "name=" + s.getName() + ", " + "age=" + s.getAge() + "]");
而調(diào)用toString()就簡(jiǎn)單多了
//兩者等價(jià) toString(); getClass().getName()+ "@" + Integer.toHexString(hashCode()) //輸出結(jié)果 cn.bwh_04_toString.Student@1b6d3586。(7) equals()——重要
比較兩個(gè)對(duì)象是否相同
默認(rèn)情況下,比較的是地址值是否相同。
而比較地址值是沒(méi)有意義的,所以,一般子類也會(huì)重寫該方法。
在諸多子類,如String、Integer、Date 等均重寫了equals()方法
改進(jìn)思路:
我們可以將比較地址值轉(zhuǎn)變?yōu)楸容^成員變量
因?yàn)閚ame為String類型,而String類型為引用類型,所以不能夠用==比較,應(yīng)該用equal()
String中默認(rèn)重寫過(guò)的equal()方法是用來(lái)比較字符串內(nèi)容是否相同
我們要使用的是學(xué)生類的成員變量,所以父類 Object不能調(diào)用子類Student的特有功能
所以使用向下轉(zhuǎn)型
//重寫v1.0 public boolean equals(Object o) { Student s = (Student) o; if (this.name.equals(s.name) && this.age == s.age) { return true; } else { return false; } }
//重寫v2.0 (可作為最終版) public boolean equals(Object o) { if (this.name == o) { return true; } //測(cè)試它左邊的對(duì)象是否是它右邊的類的實(shí)例,返回 boolean 的數(shù)據(jù)類型。 if (!(o instanceof Student)) { return false; } Student s = (Student) o; return this.name.equals(s.name) && this.age == s.age; }
//idea自動(dòng)生成版 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); }
?== 的作用:
基本類型:比較值是否相同
引用類型:比較的就是堆內(nèi)存地址是否相同
equals 的作用:
引用類型:默認(rèn)情況下,比較的是地址值。
注:一般選擇重寫方法,比較對(duì)象的成員變量值是否相同 ,不過(guò)一般重寫都是自動(dòng)生成。
結(jié)尾:如果內(nèi)容中有什么不足,或者錯(cuò)誤的地方,歡迎大家給我留言提出意見(jiàn), 蟹蟹大家 !^_^
如果能幫到你的話,那就來(lái)關(guān)注我吧?。ㄏ盗形恼戮鶗?huì)在公眾號(hào)第一時(shí)間更新)
在這里的我們素不相識(shí),卻都在為了自己的夢(mèng)而努力 ?一個(gè)堅(jiān)持推送原創(chuàng)Java技術(shù)的公眾號(hào):理想二旬不止
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74865.html
摘要:采用完全獨(dú)立于任何程序語(yǔ)言的文本格式,使成為理想的數(shù)據(jù)交換語(yǔ)言為什么需要提到,我們就應(yīng)該和來(lái)進(jìn)行對(duì)比。也是一種存儲(chǔ)和交換文本信息的手段。那么好在哪里呢比更小更快,更易解析。使用的時(shí)候,也支持將轉(zhuǎn)成但是,我們不一定使用框架來(lái)做開發(fā)呀。 什么是JSON JSON:JavaScript Object Notation 【JavaScript 對(duì)象表示法】 JSON 是存儲(chǔ)和交換文本信息的語(yǔ)法...
摘要:前言上一次我們對(duì)的應(yīng)用進(jìn)行了一次全面的分析,這一次我們來(lái)聊聊。 showImg(https://segmentfault.com/img/remote/1460000020077803?w=1280&h=853); 前言 上一次我們對(duì)Paging的應(yīng)用進(jìn)行了一次全面的分析,這一次我們來(lái)聊聊WorkManager。 如果你對(duì)Paging還未了解,推薦閱讀這篇文章: Paging在Recy...
摘要:目錄前言架構(gòu)安裝第一個(gè)爬蟲爬取有道翻譯創(chuàng)建項(xiàng)目創(chuàng)建創(chuàng)建解析運(yùn)行爬蟲爬取單詞釋義下載單詞語(yǔ)音文件前言學(xué)習(xí)有一段時(shí)間了,當(dāng)時(shí)想要獲取一下百度漢字的解析,又不想一個(gè)個(gè)漢字去搜,復(fù)制粘貼太費(fèi)勁,考慮到爬蟲的便利性,這篇文章是介紹一個(gè)爬蟲框架, 目錄 前言 架構(gòu) 安裝 第一個(gè)爬蟲:爬取有道翻譯 創(chuàng)建項(xiàng)目 創(chuàng)建Item 創(chuàng)建Spider 解析 運(yùn)行爬蟲-爬取單詞釋義 下載單詞語(yǔ)音文件 ...
摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡(jiǎn)單 注解就這么簡(jiǎn)單 Druid數(shù)據(jù)庫(kù)連接池...
摘要:豐富的特性還支持通知過(guò)期等等特性。到這個(gè)就說(shuō)明測(cè)試通過(guò)了。主要針對(duì)方法配置,能夠根據(jù)方法的請(qǐng)求參數(shù)對(duì)其進(jìn)行緩存,常用于查詢操作主要針對(duì)方法配置,能夠根據(jù)方法的請(qǐng)求參數(shù)對(duì)其進(jìn)行緩存,常用于修改操作清空緩存,主要用于刪除操作。 [TOC] Redis簡(jiǎn)介 Redis 是一個(gè)開源的使用 ANSI C 語(yǔ)言編寫、遵守 BSD 協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value 數(shù)...
閱讀 688·2021-11-22 15:32
閱讀 2778·2021-11-19 09:40
閱讀 2394·2021-11-17 09:33
閱讀 1345·2021-11-15 11:36
閱讀 1934·2021-10-11 10:59
閱讀 1541·2019-08-29 16:41
閱讀 1840·2019-08-29 13:45
閱讀 2222·2019-08-26 13:36