目錄
== 和 equals 方法
== 代表比較雙方是否相同。
- 比較基本類型,表示 值相同
- 比較引用類型,表示 地址相等 即為同一對象
Object類中定義有: public boolean equals(Object obj) 方法,提供定義“ 對象內(nèi)容相等 ”的邏輯
Object 的 equals 方法默認就是比較兩個對象的 hashcode,是同一個對象的引用時返回 true 否則返回 false。可以根據(jù)自己的要求重寫equals方法。
封裝
需要讓用戶知道的才暴露出來,不需要讓用戶知道的全部隱藏起來,這就是封裝。即封裝就是把對象的屬性和操作結(jié)合為一個獨立的整體,并盡可能隱藏對象的內(nèi)部實現(xiàn)細節(jié)。
編程中封裝的具體優(yōu)點:
- 提高代碼的安全性。
- 提高代碼的復(fù)用性。
- “高內(nèi)聚”:封裝細節(jié),便于修改內(nèi)部代碼,提高可維護性
- “低耦合”:簡化外部調(diào)用,便于調(diào)用者使用,便于擴展和協(xié)作。
多態(tài)
多態(tài)指的是 同一個方法調(diào)用 ,由于對 象不同 可能會有 不同的行為 。現(xiàn)實生活中,同一個方法,具體實現(xiàn)會完全不同。 比如:同樣是調(diào)用人“吃飯”的方法,中國人用筷子吃飯,英國人用刀叉吃飯,印度人用手吃飯。
多態(tài)的要點:
- 多態(tài)是方法的多態(tài),不是屬性的多態(tài)( 多態(tài)與屬性無關(guān) )。
- 多態(tài)的存在要有3個必要條件: 繼承,方法重寫,父類引用指向子類對象。
- 父類引用指向子類對象后,用該父類引用調(diào)用子類 重寫 的方法,此時多態(tài)就出現(xiàn)了。
抽象類和抽象方法
抽象方法
使用 abstract 修飾的方法, 沒有方法體,只有聲明 。定義的是一種“規(guī)范”,就是告訴 子類 必須要給抽象方法提供具體的 實現(xiàn)。
抽象類
包含抽象方法的類就是抽象類。通過 abstract 方法定義規(guī)范,然后要求子類必須定義具體實現(xiàn)。通過抽象類,我們就可以做到 嚴格限制子類的設(shè)計 ,使子類之間更加通用。
抽象類的使用要點
- 有抽象方法的類只能定義成抽象類
- 抽象類不能實例化,即不能用new來實例化抽象類。
- 抽象類可以包含屬性、方法、構(gòu)造方法。但是構(gòu)造方法不能用來new實例, 只能用來被子類調(diào)用。
- 抽象類只能用來被繼承。
- 抽象方法必須被子類實現(xiàn)
接口
為什么需要接口? 接口和抽象類的區(qū)別?
- 接口就是比“抽象類”還“抽象”的“抽象類”,可以更加規(guī)范的對子類進行約束。全面地專業(yè)地實現(xiàn)了: 規(guī)范和具體實現(xiàn)的分離。
- 抽象類還提供某些具體實現(xiàn), 接口不提供任何實現(xiàn) ,接口中所有方法都是抽象方法。接口是 完全面向規(guī)范的 ,規(guī)定了一批類具有的公共方法規(guī)范。
- 接口和實現(xiàn)類不是父子關(guān)系,是實現(xiàn)規(guī)則的關(guān)系。比如:定義一個接口Runnable,Car實現(xiàn)它就能在地上跑,Train實現(xiàn)它也能在地上跑,飛機實現(xiàn)它也能在地上跑。就是說,如果它是交通工具,就一定能跑,但是一定要實現(xiàn)Runnable接口。
接口使用
[訪問修飾符] interface 接口名 [extends 父接口1,父接口2…] {
常量定義;
方法定義;
}
- 訪問修飾符:public 或默認
- extends:可多繼承
- 常量:接口中的屬性只能是常量,總是:public static final 修飾 or 省略
- 方法:接口中的方法只能是:public abstract or 省略
- JDK1.7之前,接口中只能包含靜態(tài)常量、抽象方法, 不能有普通屬性、構(gòu)造方法、普通方法。
- JDK1.8后,接口中包含普通的靜態(tài)方法
內(nèi)部類
內(nèi)部類的作用:
- 內(nèi)部類提供了更好的封裝。 只能讓外部類直接訪問 ,不允許同一個包中的其他類直接訪問。
- 內(nèi)部類可以 直接訪問外部類的私有屬性 ,內(nèi)部類被當成其外部類的成員。 但 外部類不能訪問內(nèi)部類 的內(nèi)部屬性。
- 接口只是解決了多重繼承的部分問題,而內(nèi)部類使得多重繼承的解決方案變得更加完整。
內(nèi)部類的使用場合:
- 由于內(nèi)部類提供了更好的封裝特性,并且可以很方便的訪問外部類的屬性。所以,在 只為外部類提供服務(wù) 的情況下可以優(yōu)先考慮使用內(nèi)部類。
- 使用內(nèi)部類間接實現(xiàn)多繼承:每個內(nèi)部類都能獨立地繼承一個類或者實現(xiàn)某些接口,所以無論外部類是否已經(jīng)繼承了某個類或者實現(xiàn)了某些接口,對于內(nèi)部類沒有任何影響。
String
String 類對象代表不可變的Unicode字符序列,因此我們可以將String對象稱為“不可變對象”。 那什么叫做“不可變對象”呢? 指的是對象內(nèi)部的成員變量的值無法再改變。
字符串常量拼接時的優(yōu)化
在遇到 字符串常量 之間的拼接時,編譯器會做出優(yōu)化,即在 編譯期間 就會完成字符串的拼接。
String s1 = "hello" + " world";
String s2 = "hello world";
System.out.println(s1 == s2); // true
String s3 = "hello";
String s4 = " world";
//編譯的時候不知道變量中存儲的是什么,所以沒辦法在編譯的時候優(yōu)化
String s5 = s3 + s4;
System.out.println(s2 == s5); //false
String Pool
字符串常量池( String Pool )保存著所有 字符串字面量 ,這些字面量在 編譯時期 就確定。使用String的 intern() 方法在 運行過程 中將字符串添加到常量池中。
當一個字符串調(diào)用 intern() 方法時,若 String Pool 中已存在字符串和該字符串值相等(通過 equals() 方法判斷),則返回String Pool 中字符串的引用;否則,就在S P 中添加一個新字符串并返回其引用。
String s1 = new String("aaa");
String s2 = new String("aaa");
sout(s1 == s2); // false
String s3 = s1.intern();
String s4 = s2.intern();
sout(s3 == s4); // true
若以字面量形式創(chuàng)建字符串,會自動將字符串放入String Pool。
String s5 = "bbb";
String s6 = "bbb";
sout(s5 == s6); // true
OutOfMemoryError
StringBuffer、StringBuilder
StringBuffer和StringBuilder 非常類似,均代表 可變的字符序列 (無final修飾的 char value[] )。 這兩個類都是抽象類AbstractStringBuilder的子類,方法幾乎一模一樣。
區(qū)別:
- StringBuffer JDK1.0版本提供的類, 線程安全,做線程同步檢查( synchronized ) , 效率較低。
- StringBuilder JDK1.5版本提供的類,線程不安全,不做線程同步檢查,因此效率較高。 建議采用該類。
自動裝箱/拆箱
自動裝箱和拆箱就是將 基本數(shù)據(jù)類型 和 包裝類 之間進行自動的互相轉(zhuǎn)換。
- 自動裝箱:基本類型的數(shù)據(jù)處于需要對象的環(huán)境中時, 會自動轉(zhuǎn)為“對象”。
- Integer i = 100; // 相當于 Integer i = Integer.valueOf(100);
- 自動拆箱:每當需要一個值時,對象會自動轉(zhuǎn)成基本數(shù)據(jù)類型,沒必要再去顯式調(diào)用 intValue()、doubleValue() 等轉(zhuǎn)型方法
- Integer i = 100; int j = i; // 自動拆箱 // 相當于 int j = i.intValue();
包裝類的緩存
整型、char類型所對應(yīng)的包裝類,在自動裝箱時,對于-128~127之間的值會進行緩存處理,其目的是提高效率。
緩存原理:
- 若數(shù)據(jù)在 -128~127 區(qū)間,則在類加載時就已經(jīng)為該區(qū)間的每個數(shù)值創(chuàng)建了對象,并將這256個對象放在 cache 數(shù)組中
- 每當自動裝箱過程發(fā)生時 (或者手動調(diào)用 valueOf() 時),就會 先判斷數(shù)據(jù)是否在該區(qū)間 ,如果在則直接獲取數(shù)組中對應(yīng)的包裝類對象的引用, 如果不在該區(qū)間,則會通過new調(diào)用包裝類的構(gòu)造方法來創(chuàng)建對象。
異常機制
JAVA是采用面向?qū)ο蟮姆绞絹硖幚懋惓5摹L幚磉^程:
- 拋出異常:在執(zhí)行一個方法時,如果發(fā)生異常,則這個方法生成代表該異常的一個對象,停止當前執(zhí)行路徑,并把異常對象提交給JRE。
- 捕獲異常:JRE得到該異常后,尋找相應(yīng)的代碼來處理該異常。JRE在方法的調(diào)用棧中查找,從生成異常的方法開始回溯,直到找到相應(yīng)的異常處理代碼為止。
Java 異常類層次結(jié)構(gòu):
- Error 是程序無法處理的錯誤,表示運行應(yīng)用程序中較嚴重問題。
- Exception 是程序本身能夠處理的異常。Exception類是所有異常類的父類,分為:
- RuntimeException 運行時異常
- 如被 0 除、數(shù)組下標越界、空指針(訪問空對象成員)等
- CheckedException 已檢查異常
- 所有不是RuntimeException的異常,統(tǒng)稱為Checked Exception.
捕獲異常
- try-catch-finally
-
- 如果異常類之間有繼承關(guān)系,越是頂層的類,越放在下面;或者直接把多余的catch省略掉,即先捕獲子類異常再捕獲父類異常
- 即使try和catch塊中存在return語句,finally語句也會執(zhí)行。是在執(zhí)行完finally語句后再通過return退出。
- finally語句塊只有一種情況是不會執(zhí)行的,那就是在執(zhí)行finally之前遇到了 System.exit(0) 結(jié)束程序運行。
- throws
- 如果一個方法中可能產(chǎn)生某種異常,但是并 不能確定如何處理這種異常 ,則應(yīng)根據(jù)異常規(guī)范在方法的首部聲明該方法可能拋出的異常。
- public static void readFile(String fileName) throws FileNotFoundException,IOException {...}
- 方法重寫中聲明異常原則: 子類重寫父類方法時,如果父類方法有聲明異常,那么子類聲明的異常范圍不能超過父類聲明的范圍 。