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