這個(gè)是我個(gè)人閱讀《Java核心技術(shù)》和《Java編程思想》總結(jié)出來的筆記,清晰明了,但是沒有細(xì)致講解,如果碰到疑惑的地方,可以另行查閱。
封裝
- 從形式上看,封裝將數(shù)據(jù)和行為組合在一個(gè)包中,并對對象的使用者隱藏了數(shù)據(jù)的實(shí)現(xiàn)方式
- 實(shí)現(xiàn)封裝的關(guān)鍵在于絕對不能讓類中的方法直接訪問其他類的實(shí)例域,程序僅通過對象的方法同對象的數(shù)據(jù)進(jìn)行交互
對象變量和對象
Date deadline; //沒用引用任何對象
deadline = new Date(); //使用新構(gòu)造的對象初始化變量
Date birthday = deadline; //引用一個(gè)已經(jīng)存在的變量

- 一個(gè)對象變量并沒有實(shí)際包含一個(gè)對象,而僅僅引用一個(gè)對象
- 所有的Java對象都存儲(chǔ)在 堆 中
更改器方法和訪問器方法
- 更改器方法:
調(diào)用該方法后,對象的狀態(tài)會(huì)改變 - 訪問器方法:
只訪問對象而不修改對象的方法(如toUpperCase)
隱式參數(shù)與顯式參數(shù)
public void raiseSalary(double byPercent) {
double raise = this.salary * byPercent / 100;
this.salary += raise;
}
函數(shù)的參數(shù)為 顯式參數(shù),this 為 隱式參數(shù)
final實(shí)例域
final 修飾符大都應(yīng)用于基本類型域,或不可變類的域(類中的每個(gè)方法都不會(huì)改變其對象,這種類就是不可變的類,如String),對于可變的類,所傳達(dá)的意思為該變量不會(huì)再引用其他對象,但這個(gè)對象仍然可變(如StringBuilder)
方法參數(shù)
- 一個(gè)方法不能修改一個(gè)基本數(shù)據(jù)類型的參數(shù)(即數(shù)值型或布爾型)
- 一個(gè)方法可以改變一個(gè)對象參數(shù)的狀態(tài)
- 一個(gè)方法 不能讓對象參數(shù)引用一個(gè)新的對象
- 對象引用實(shí)際上是按值傳遞的
繼承
- 子類繼承父類的成員變量
當(dāng)子類繼承了某個(gè)類之后,便可以使用父類中的成員變量,但并不是完全繼承父類的成員變量
- 能夠繼承父類的public和protected成員變量;不能夠繼承父類的private成員變量;
- 對于父類的包訪問權(quán)限成員變量,如果子類和父類在同一個(gè)包下,則子類能夠繼承;否則,子類不能夠繼承;
- 對于子類可以繼承的父類成員變量,如果在子類中出現(xiàn)了同名稱的成員變量,則會(huì)發(fā)生隱藏現(xiàn)象,即子類的成員變量會(huì)屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關(guān)鍵字來進(jìn)行引用。
- 子類繼承父類的方法
同樣的,子類也不是完全繼承父類的所有方法
- 能夠繼承父類的public和protected成員方法;不能夠繼承父類的private成員方法;
- 對于父類的包訪問權(quán)限成員方法,如果子類和父類在同一個(gè)包下,則子類能夠繼承;否則,子類不能夠繼承;
- 對于子類可以繼承的父類成員方法,如果在子類中出現(xiàn)了同名稱的成員方法,則稱為覆蓋,即子類的成員方法會(huì)覆蓋掉父類的同名成員方法。如果要在子類中訪問父類中同名成員方法,需要使用super關(guān)鍵字來進(jìn)行引用。
注意:隱藏和覆蓋是不同的。隱藏是針對成員變量和靜態(tài)方法的,而覆蓋是針對普通方法的。
引用自http://www.cnblogs.com/dolphin0520/p/3803432.html
重載
- 多個(gè)方法有相同的名字,不同的參數(shù)(與域修飾符,返回值無關(guān))
- Java允許重載任何方法
- 要完整的描述一個(gè)方法,需要指出方法名以及參數(shù)類型,這叫做方法的簽名,返回類型不是方法簽名的一部分(這意味不能有兩個(gè)名字,參數(shù)相同但是返回值不同的方法)
無參構(gòu)造器
只有當(dāng)一個(gè)類沒有任何構(gòu)造器時(shí),系統(tǒng)才會(huì)給一個(gè)默認(rèn)的無參構(gòu)造器,該構(gòu)造器將實(shí)例域設(shè)置為默認(rèn)值(null,false,0)
包
如果在源文件中沒有 package 語句,這個(gè)源文件中的類將被放置在一個(gè)默認(rèn)包中,默認(rèn)包是一個(gè)沒有名字的包
this和super
- this有兩個(gè)用途:
- 引用隱式參數(shù)
- 調(diào)用該類其他的構(gòu)造器(調(diào)用其他構(gòu)造器的語句應(yīng)作為該構(gòu)造器的第一條語句出現(xiàn))
- super有兩個(gè)用途
- 調(diào)用超類方法(為了區(qū)分本類方法和超類方法)
- 調(diào)用超類的構(gòu)造器
什么是多態(tài)
一個(gè)對象變量可以被指示為多種實(shí)際類型的現(xiàn)象被稱為 多態(tài)。
class Base{
int count=2;
public void display() {
System.out.println(this.count);
}
}
public class Derived extends Base{
int count=20;
@Override
public void display() {
System.out.println(this.count);
}
public static void main(String[] args) {
Base base = new Derived();
System.out.println(base.count); //2
base.display(); //20
}
}
要弄清楚這個(gè)過程,首先需要知道什么叫做綁定
將一個(gè)方法調(diào)用和一個(gè)方法主體關(guān)聯(lián)起來叫做 綁定,程序執(zhí)行前進(jìn)行綁定,叫做前期綁定(C語言只有一個(gè)方法調(diào)用,就是前期綁定),上述程序之所以讓人迷惑,就是因?yàn)榍捌诮壎?,為了解決這種沖突,引出了后期綁定。
后期綁定的含義就是運(yùn)行時(shí)根據(jù)對象的類型進(jìn)行綁定,后期綁定也叫做動(dòng)態(tài)綁定,如果一種語言想實(shí)現(xiàn)動(dòng)態(tài)綁定,那么就必須有某種機(jī)制。以便在運(yùn)行時(shí)判斷對象的類型。
Java的做法是除了 構(gòu)造方法,static,final,private(編譯時(shí)被編譯為final),其他所有的方法全部都是動(dòng)態(tài)綁定。
如你所見,base變量在運(yùn)行期間是Derived類的行為,但是訪問base域時(shí)卻是Base的域,這是因?yàn)閯?dòng)態(tài)綁定的存在,使得原本Base類的普通方法(非構(gòu)造方法,static,final,private)被覆蓋掉,所以表現(xiàn)出來的行為就是Derived類的行為。
什么是動(dòng)態(tài)綁定
見上
在覆蓋一個(gè)方法時(shí),子類方法不能低于父類方法的可見性
抽象類和抽象方法
- 包含一個(gè)或多個(gè)抽象方法的類必須聲明為抽象類,但是抽象類不一定需要包含抽象方法
- 抽象類可以包含具體的數(shù)據(jù)和方法
- 抽象方法充當(dāng)著 占位的角色,他們的具體實(shí)現(xiàn)在子類中,子類在繼承抽象類是面臨兩個(gè)選擇:
- 子類仍然標(biāo)記為抽象類
- 子類不被標(biāo)記為抽象類,但是需要 定義全部的抽象方法
- 不能構(gòu)造抽象類的對象,但是可以聲明抽象類的變量
在Java中,只有基本類型不是對象,所有的數(shù)組類型(包括基本類型數(shù)組)都擴(kuò)展了Object類
hashcode
- 散列碼(hash code)是由對象導(dǎo)出的一個(gè)整型值
- 字符串的散列碼由內(nèi)容導(dǎo)出,如果兩字符串內(nèi)容相同,那么其導(dǎo)出的散列碼也相同
- Object類默認(rèn)hashcode()方法導(dǎo)出對象的存儲(chǔ)地址
包裝器對象

需要注意各種包裝器中valueOf()方法的實(shí)現(xiàn),其中Integer、Short、Byte、Character、Long這幾個(gè)類的valueOf方法的實(shí)現(xiàn)是類似的,Double、Float的valueOf()方法的實(shí)現(xiàn)是類似的。
Integer、Short、Byte、Character、Long這幾個(gè)類的valueOf方法實(shí)現(xiàn)如下,該種實(shí)現(xiàn)會(huì)使數(shù)值在[-128,127]之間的對象指向同一塊內(nèi)存區(qū)域。
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
Double、Float的valueOf()方法的實(shí)現(xiàn)如下,每次都會(huì)返回一個(gè)新對象。
public static Double valueOf(double d) {
return new Double(d);
}
那么布爾類型的valueOf()實(shí)現(xiàn)是怎樣的呢?
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
這就意味著下面這段代碼輸出為true,true。
public class Main {
public static void main(String[] args) {
Boolean i1 = false;
Boolean i2 = false;
Boolean i3 = true;
Boolean i4 = true;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
獲取Class對象
1. Random generator = new Random();
Class cl = generator.getClass();
2. String className = "java.util.Random";
Class cl = Class.forName(className);
3. Class cl = Random.class;
獲取對象的實(shí)例
Object m = Class.forName(s).newInstance();
垃圾回收
- 使用 finalize() 方法釋放"特殊的內(nèi)存區(qū)域",通常該區(qū)域?yàn)槠渌Z言申請得來的內(nèi)存。
- 通過 new 操作符 創(chuàng)建出來的對象Java會(huì)自動(dòng)回收。
接口中的自動(dòng)聲明
- 接口中的所有方法自動(dòng)屬于 public,不必顯示聲明,但在實(shí)現(xiàn)接口提供的方法時(shí),必須把方法顯示的聲明為 public
- 接口中的域?qū)⒈蛔詣?dòng)設(shè)為 public static final
每個(gè)類只能有一個(gè)超類,但是卻可以實(shí)現(xiàn)多個(gè)接口
接口的默認(rèn)實(shí)現(xiàn)
public interface Comparable<T> {
default int compareTo(T other) {
return 0;
}
}
解決接口沖突
情景一: A接口和B接口中都有一個(gè)fun()方法,但返回值不同,那么C類就不可能同時(shí)實(shí)現(xiàn)A接口和B接口,因?yàn)榻涌诘脑O(shè)計(jì)本身就存在問題
情景二: A接口和B接口中都有一個(gè)fun()方法,返回值和方法參數(shù)都相同,那么C類就可以同時(shí)實(shí)現(xiàn)A接口和B接口,即使可以實(shí)現(xiàn),但是接口的設(shè)計(jì)還是存在問題
情景三: A接口中有fun()方法,超類F中也有fun()方法,那么C類同時(shí)繼承F類并實(shí)現(xiàn)A接口時(shí),會(huì)覆蓋超類中的fun()方法而不會(huì)去實(shí)現(xiàn)A接口中的fun()方法(類優(yōu)先的原則)
實(shí)現(xiàn)Comparator接口來進(jìn)行排序
Comparator接口中比較器聲明如下:
public interface Comparator<T> {
int compare(T first,T second);
}
實(shí)現(xiàn)按長度比較字符串,可以定義一個(gè)Comparator<String>類
class LengthComparator implments Comparator<String> {
public int compare(String s1,String s2) {
return s1.length() - s2.length();
}
}
實(shí)際調(diào)用:
//1.普通調(diào)用
Comparator<String> comp = new LengthComparator();
if(comp.compare(word[i],word[j]) > 0) {
...
}
//2.比較器調(diào)用
Arrays.sort(arr,new LengthComparator());
使用lambda表達(dá)式
上述例子可以修改如下:
Arrays.sort(arr,(s1,s2) -> s1.length() - s2.length());
lambda表達(dá)式的作用域
lambda表達(dá)式有三個(gè)組成部分:
- 一個(gè)代碼塊
- 參數(shù)
- 自由變量的值,這里指非參數(shù)而且不在代碼中定義的變量(主要討論它)
- 要確保該值只能被引用,而不會(huì)被改變
- 該值在lambda外部必須是最終變量
- lambda表達(dá)式的體與嵌套塊有相同的作用域,要避免命名沖突
//該例子存在命名沖突
Path first = Path.get("/usr/bin");
Comparator<String> comp = (first,second) -> first.length() - second.length();
- 在lambda表達(dá)式中使用this關(guān)鍵字時(shí),this所指與平常無異(即this為創(chuàng)建lambda表達(dá)式方法的對象)
什么是函數(shù)式接口
對于只有一個(gè)抽象方法的接口,需要這種接口對象時(shí),就可以提供一個(gè)lambda表達(dá)式,這種接口成為 函數(shù)式接口
Java基礎(chǔ)知識(shí)干貨2傳送門->http://www.itdecent.cn/p/9bb6827a768c