瘋狂Java講義 讀書筆記(一),java講義讀書筆記

來源:互聯網
上載者:User

瘋狂Java講義 讀書筆記(一),java講義讀書筆記

李剛老師的《瘋狂Java講義》(第三版)是我的啟蒙作品,前前後後一共看了3遍,每次都有新的認識。

接下來的一段時間就將一些經典的知識記錄下來。

1.電腦進階語言的執行方式分為編譯型和解釋型,前者運行高效但不能跨平台(C,C++,Object-C),後台可以跨平台但效率不高(Ruby,Python)。Java比較特殊,先編譯產生.class,再在JVM中解釋。

2.記憶體回收機制:依靠記憶體回收演算法,何時回收對Java程式員而言具有透明性,因此要養成良好的習慣——對於不需要的對象,不要引用他們。(在堆中進行回收)

3.Java是強型別語言:所有類變數必須先聲明後使用,指定類型的變數只能接受與類型相匹配的值。

4.Java支援兩種類型:1、基本類型:布爾類型、數實值型別 2.參考型別:類、介面、數組。

5.強制類型轉化:造成溢出時,之前一直覺得19.745會變成19(實在汗顏),其實是轉換成二進位後再進行截取。

6.常量池:在編譯期被確定,並已被儲存在.class檔案中的一些資料。包括類、方法、介面中的常量,也包括字串常量。

7.switch語句:控製表達式的資料類型只能是byte,short,char,int,枚舉,String.

8.break和continue可以通過標籤跳到指定的迴圈層

public class BreakTest2{    public static void main(String[] args)    {        outer:        for (int i = 0 ; i < 5 ; i++ )        {            for (int j = 0; j < 3 ; j++ )            {                System.out.println("i的值為:" + i + "  j的值為:" + j);                if (j == 1)                {                    break outer;                }            }        }    }}

9.棧和堆:1、當一個方法執行時,每個方法都會建立自己的記憶體棧,在這個方法內定義的變數將會逐個放入這塊棧記憶體裡,隨著方法的執行結束,這個方法的記憶體棧也將自動銷毀。因此,所有在方法中定義的局部變數都是放在棧記憶體中;2、當我們在程式中建立一個對象是,這個對象將被儲存到運行是資料區中,以便反覆利用,這個運行是資料區就是堆記憶體。堆記憶體中的對象不會因方法結束而銷毀,就算方法結束後,這個對象還可能被另一個變數所引用,則這個對象不會銷毀,只有當一個變數沒有任何引用變數引用它,那麼系統的記憶體回收行程才會在合適的時候回收它;

10.Arrays:Java8增加的工具類,在java.util包下,支援並發編程

        // 定義一個a數組        int[] a = new int[]{3, 4 , 5, 6};        // 定義一個a2數組        int[] a2 = new int[]{3, 4 , 5, 6};        // a數組和a2數組的長度相等,每個元素依次相等,將輸出true        System.out.println("a數組和a2數組是否相等:"            + Arrays.equals(a , a2));        // 通過複製a數組,產生一個新的b數組        int[] b = Arrays.copyOf(a, 6);        System.out.println("a數組和b數組是否相等:"            + Arrays.equals(a , b));        // 輸出b數組的元素,將輸出[3, 4, 5, 6, 0, 0]        System.out.println("b數組的元素為:"            + Arrays.toString(b));        // 將b數組的第3個元素(包括)到第5個元素(不包括)賦為1        Arrays.fill(b , 2, 4 , 1);        // 輸出b數組的元素,將輸出[3, 4, 1, 1, 0, 0]        System.out.println("b數組的元素為:"            + Arrays.toString(b));        // 對b數組進行排序        Arrays.sort(b);        // 輸出b數組的元素,將輸出[0, 0, 1, 1, 3, 4]        System.out.println("b數組的元素為:"            + Arrays.toString(b));    }

11.Java語言通過new關鍵字調用構造器。

12.this關鍵字:1、讓類中的一個方法,訪問該類裡的另一個方法或者執行個體變數。2、this所代表的對象是不確定的,但他的類是確定的。3、在構造器中,this代表該構造器正在初始化的對象。4、如果在某個方法中把this作為傳回值,則可以多次連續調用同一個方法。

public class ReturnThis{    public int age;    public ReturnThis grow()    {        age++;        // return this返回調用該方法的對象        return this;    }    public static void main(String[] args)    {        ReturnThis rt = new ReturnThis();        // 可以連續調用同一個方法        rt.grow()            .grow()            .grow();        System.out.println("rt的age成員變數值是:" + rt.age);    }}

13.static:不要使用對象去調用static修飾的成員變數,要使用類去調用。

14.值傳遞:將實際參數的副本傳入方法內,參數本身不會受到任何影響。

15.形參可變的方法:定義方法時,在最後一個形參的類型後增加三個點(...)。多個參數值被當成數組傳入。與傳入數組相比,形參可變更加簡潔,但一個方法只能有一個可變形參。

public class Varargs{    // 定義了形參個數可變的方法    public static void test(int a , String... books)    {        // books被當成數組處理        for (String tmp : books)        {            System.out.println(tmp);        }        // 輸出整數變數a的值        System.out.println(a);    }    public static void main(String[] args)    {        // 調用test方法        test(5 , "瘋狂Java講義" , "輕量級Java EE公司專屬應用程式實戰");    }}

16.遞迴演算法:一個方法調用自身,一定要向已知方向遞迴。

17.局部變數:形參(方法簽名中定義的變數),方法局部變數(在方法內定義),代碼塊局部變數(在代碼塊內定義),局部變數不屬於任何類或者執行個體,它總是儲存在其所在方法的棧記憶體中。

18.封裝:類的成員變數不直接暴露,而是通過方法實現操作和訪問,以便於在方法中添加一些限制條件

19.高內聚:儘可能把模組的內部資料、功能實現細節隱藏在模組內部獨立完成,不允許外部直接幹預;低耦合:僅暴露少量的方法給外部使用。

20.靜態匯入:JDK1.5增加的導包方法,用於匯入包內的靜態成員 import static package...

21.構造器:1、構造器是建立Java對象的重要途徑,但這個對象並不是完全由構造器負責建立的。2、子類的構造器必定會調用其父類的構造器(沒有super和this時預設調用無參的構造器)。

22.方法重寫(覆蓋)原則:1、兩同:方法名、參數列表相同 2、兩小:子類方法傳回值<=父類方法傳回值 3、一大:子類方法存取權限>=父類方法存取權限

23.當程式建立一個子類對象時,系統不僅會為該類中定義的執行個體變數分配記憶體,也會為它從父類繼承得到的所有執行個體變數分配記憶體。

24.引用變數類型:1、編譯時間類型:由聲明該變數時使用的類型決定 2、運行時類型:由實際賦給該變數的對象決定 3、編譯時間類型和運行時類型不同時,就出現了所謂的多態 4、引用變數在編譯階段只能調用其編譯時間類型所具有的方法,但運行時則執行它運行時類型所具有的方法(可用強制類型轉換解決問題)。

25.向上轉型:把一個子類對象直接賦值給父類引用變數;強制類型轉換:把一個父類對象賦給子類引用變數

26多態:1、相同類型的變數,調用同一個方法時呈現出多種不同的行為特徵叫做多態 2、成員變數不存在多態,總是調用父類的值

27.instanceof:判斷前面的對象是否是後面的類,或者其子類、實作類別的執行個體

String str="str";//trueSystem.out.println(str instanceof Object);Object obj=new Object();//falseSystem.out.println(obj instanceof String);

28.繼承與組合:1繼承代表"is a",組合代表"has a" 2.建立子類對象,系統會為其父類所定義的執行個體變數分配記憶體空間,因此繼承和組合在系統開銷上沒有太大的區別

29.初始化塊:1.初始化塊在構造器之前執行(編譯後初始化塊的內容會還原到構造器中) 2.靜態初始化塊在普通初始化塊之前執行

30.封裝類:封裝類的執行個體可以與數實值型別直接比較

31.toString:自訂類時,盡量重寫類的toString方法,便於輸出執行個體的值

32.==與equals:1.對於參考型別,只有二者指向同一個對象,==才會等於true  2.String類型情況如下,編譯時間確定的資料在常量池中,運行時產生的資料在堆記憶體中

    // s1直接引用常量池中的"瘋狂Java"        String s1 = "瘋狂Java";        String s2 = "瘋狂";        String s3 = "Java";        // s4後面的字串值可以在編譯時間就確定下來        // s4直接引用常量池中的"瘋狂Java"        String s4 = "瘋狂" + "Java";        // s5後面的字串值可以在編譯時間就確定下來        // s5直接引用常量池中的"瘋狂Java"        String s5 = "瘋" + "狂" + "Java";        // s6後面的字串值不能在編譯時間就確定下來,        // 不能引用常量池中的字串        String s6 = s2 + s3;        // 使用new調用構造器將會建立一個新的String對象,        // s7引用堆記憶體中新建立的String對象        String s7 = new String("瘋狂Java");        System.out.println(s1 == s4); // 輸出true        System.out.println(s1 == s5); // 輸出true        System.out.println(s1 == s6); // 輸出false        System.out.println(s1 == s7); // 輸出false

33.重寫equals的條件:1.自反性:x.equals(x)=true 2.對稱性:若x.equals(y)=true,則y.equals(x)=true 3.傳遞性:若x.equals(y)=true,y.equals(z)=true,則x.equals(z)=true 4.一致性:只要x.equals(y)=true且x,y不變,無論調用多少次結果都不變 5.對任何不適Null的x,x.equals(null)=false 6.equals相同,則hashcode相同

34.null類型的執行個體可以訪問類的靜態方法和靜態變數,在底層是通過該執行個體的類去訪問的

35.final:1.final變數不是不能被賦值,而是不能被改變 2.final變數必須由程式員顯示的指定初始值 3.final修飾引用變數時,引用地址不可以改變,對象可以改變 4.final修飾的方式不能被重寫,但是可以被重載

36.宏變數:定義final變數時就為該變數指定了初始值,而且可以在編譯時間就確定下來,編譯器會把程式中所有用到改變數的地方直接替換成該變數的值(進入常量池)

37.不可變類:1.private final修飾所有成員變數 2.只有getter沒有setter

38.緩衝池:先進先出緩衝執行個體,重寫了equals和hsahcode

class CacheImmutale{    private static int MAX_SIZE = 10;    // 使用數組來緩衝已有的執行個體    private static CacheImmutale[] cache        = new CacheImmutale[MAX_SIZE];    // 記錄緩衝執行個體在緩衝中的位置,cache[pos-1]是最新緩衝的執行個體    private static int pos = 0;    private final String name;    private CacheImmutale(String name)    {        this.name = name;    }    public String getName()    {        return name;    }    public static CacheImmutale valueOf(String name)    {        // 遍曆已緩衝的對象,        for (int i = 0 ; i < MAX_SIZE; i++)        {            // 如果已有相同執行個體,直接返回該緩衝的執行個體            if (cache[i] != null                && cache[i].getName().equals(name))            {                return cache[i];            }        }        // 如果緩衝池已滿        if (pos == MAX_SIZE)        {            // 把緩衝的第一個對象覆蓋,即把剛剛產生的對象放在緩衝池的最開始位置。            cache[0] = new CacheImmutale(name);            // 把pos設為1            pos = 1;        }        else        {            // 把新建立的對象緩衝起來,pos加1            cache[pos++] = new CacheImmutale(name);        }        return cache[pos - 1];    }    public boolean equals(Object obj)    {        if(this == obj)        {            return true;        }        if (obj != null && obj.getClass() == CacheImmutale.class)        {            CacheImmutale ci = (CacheImmutale)obj;            return name.equals(ci.getName());        }        return false;    }    public int hashCode()    {        return name.hashCode();    }}public class CacheImmutaleTest{    public static void main(String[] args)    {        CacheImmutale c1 = CacheImmutale.valueOf("hello");        CacheImmutale c2 = CacheImmutale.valueOf("hello");        // 下面代碼將輸出true        System.out.println(c1 == c2);    }}

39.預設方法:1.JDK1.8後新增的方法,在介面中一共有三種方法,抽象方法(abstract),類方法(static),預設方法(default),後兩者必須有方法實現 2.使用介面的執行個體來調用預設方法

40.抽象類別:抽象類別作為多個子類的抽象父類,可以被當成系統實現過程的中間產品,這個中間產品已經實現了系統的部分功能,但這個產品依然不能當成最終產品,必須由進一步的完善,

41.內部類:1.提供更好的封裝 2.內部類成員可以直接存取外部類的私人資料 3.匿名內部類適用於建立只需要一次使用的類 4.局部內部類和匿名內部類不是類成員 5.包含內部類的類被稱為外部類

42.非靜態內部類:1.非靜態內部類對象裡儲存了一個外部類的引用 2.外部類對象訪問非靜態內部類成員時,可能非靜態普通內部類對象根本不存在 3.不允許在非靜態內部類定義靜態成員

43.靜態內部類:1.靜態內部類可以包含靜態成員和非靜態成員 2.靜態內部類是外部類的類相關,靜態內部類對象寄生在外部類的類本身中,只持有外部類的類引用,沒有外部類的對象引用

44.內部類的使用: 1.盡量使用靜態內部類(調用簡單)2.局部內部類沒有什麼卵用  3.非靜態內部類的構造器必須由其外部類的對象來調用

public class SubClass extends Out.In{    //顯示定義SubClass的構造器    public SubClass(Out out)    {        //通過傳入的Out對象顯式調用In的構造器        out.super("hello");    }}

45.匿名內部類:1.必須繼承一個父類或者實現一個介面 2.不能是抽象類別 3.不能定義構造器 4.JDK1.8以前被匿名內部類訪問的局部變數必須使用final修飾,1.8以後會自動加上final修飾

46.枚舉類:可以使用枚舉類來替代靜態final常量

public class Enum {public enum Season{    spring,summer,fall,winter;}public static void main(String[] args) {    Season season=Season.spring;    System.out.println(season);    switch (season){    case spring:        System.out.println("spring");        break;    case summer:        System.out.println("summer");        break;    case fall:        System.out.println("fall");        break;    case winter:        System.out.println("winter");        break;    }    }

47.記憶體回收:1.只負責回收對象,不負責實體資源 2.程式無法精確控制記憶體回收的運行 3.在回收對象前,會調用對象的finalize方法嘗試讓其獲得新的引用以複活 4.finalize方法何時被調用具有不確定性

public class FinalizeTest{    private static FinalizeTest ft = null;    public void info()    {        System.out.println("測試資源清理的finalize方法");    }    public static void main(String[] args) throws Exception    {        // 建立FinalizeTest對象立即進入可恢複狀態        new FinalizeTest();        // 通知系統進行資源回收//        System.gc();  //①        // 強制記憶體回收機制調用可恢複對象的finalize()方法//        Runtime.getRuntime().runFinalization();   //②        System.runFinalization();   //③        ft.info();    }    public void finalize()    {        // 讓tf引用到試圖回收的可恢複對象,即可恢複對象重新變成可達        ft = this;    }}

48.參考型別:1.強引用(最常見的引用) 2.軟引用(當系統記憶體空間不夠時會被回收) 3.弱引用(比軟引用層級更低,當系統記憶體回收機制運行時,無論記憶體夠不夠都會被回收) 4.虛引用(沒什麼用)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.