Java基礎(chǔ)知識(shí)干貨

這個(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í)際上是按值傳遞的

繼承

  1. 子類繼承父類的成員變量
    當(dāng)子類繼承了某個(gè)類之后,便可以使用父類中的成員變量,但并不是完全繼承父類的成員變量
  • 能夠繼承父類的public和protected成員變量;不能夠繼承父類的private成員變量;
  • 對于父類的包訪問權(quán)限成員變量,如果子類和父類在同一個(gè)包下,則子類能夠繼承;否則,子類不能夠繼承;
  • 對于子類可以繼承的父類成員變量,如果在子類中出現(xiàn)了同名稱的成員變量,則會(huì)發(fā)生隱藏現(xiàn)象,即子類的成員變量會(huì)屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關(guān)鍵字來進(jìn)行引用。
  1. 子類繼承父類的方法
    同樣的,子類也不是完全繼承父類的所有方法
  • 能夠繼承父類的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

  1. this有兩個(gè)用途:
  • 引用隱式參數(shù)
  • 調(diào)用該類其他的構(gòu)造器(調(diào)用其他構(gòu)造器的語句應(yīng)作為該構(gòu)造器的第一條語句出現(xiàn))
  1. 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è)選擇:
  1. 子類仍然標(biāo)記為抽象類
  2. 子類不被標(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ǔ)地址

包裝器對象

==和equals

需要注意各種包裝器中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ù)而且不在代碼中定義的變量(主要討論它)
  1. 要確保該值只能被引用,而不會(huì)被改變
  2. 該值在lambda外部必須是最終變量
  3. lambda表達(dá)式的體與嵌套塊有相同的作用域,要避免命名沖突
//該例子存在命名沖突
Path first = Path.get("/usr/bin");
Comparator<String> comp = (first,second) -> first.length() - second.length();
  1. 在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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運(yùn)行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,813評(píng)論 0 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,727評(píng)論 18 399
  • 1、一個(gè)".java"源文件中是否可以包括多個(gè)類(不是內(nèi)部類)?有什么限制?答:可以有多個(gè)類,但只能有一個(gè)publ...
    岳小川閱讀 1,023評(píng)論 0 2
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,265評(píng)論 0 62
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,272評(píng)論 0 5

友情鏈接更多精彩內(nèi)容