【筆記】Java核心技術卷一讀書筆記

第三章

  1. Java是一種強類型語言。
    https://blog.csdn.net/qq_3619...
  2. 在Java中,整型的範圍與機器無關。
    int 4字節
    short 2字節
    long 8字節
    byte 1字節
  3. 子串:Substring
    拼接:String.join
    String類對象是不可變字符,可經過substring+」」 改變字符串變量
    不能用==來比較字符串,應該用equals。一個常量和一個變量比較,推薦把常量寫在前面
  4. 任何一個Java對象均可以轉換成字符串
  5. 輸入輸出
    首先要構造一個Scanner對象。
    Scanner類有各類方法,nextLine()讀取一行,next()讀取一個單詞,nextInt()讀取一個整數,nextDouble()讀取一個浮點數。
  6. Java提供了一種帶標籤的break語句。只能跳出語句塊,而不能跳入語句塊。
  7. 大數值BigInteger類
  8. for each循環(加強for)html

    for(int element:a)
        System.out.println(element);
        public class Main {
        public static void main(String[] args) {
            System.out.println("Hello World");
        }
    }
  9. 底層使用的是迭代器,因此在遍歷的過程當中,不能對集合中的元素進行增刪。目標只能是Collection或者是數組。
  10. Arrays.copyOf能夠拷貝數組,若是直接b=a,拷貝的是數組地址值,改變b會改變a

第四章、對象和類

  1. 類之間最多見的關係有
    依賴(uses-a):一個類的方法操縱另外一個類的對象。儘量的將相互依賴的類減至最小。
    聚合(has-a):覺得着類A的對象包含類B的對象
    繼承(is-a):
  2. 構造器(構造方法)用來構造並初始化對象。經過new關鍵字構造一個新對象。構造器與其餘方法有一個重要的不一樣,構造器老是伴隨new操做符的執行被調用,而不能對一個已經存在的對象調用構造器來打到從新設置實例域的目的。構造器沒有返回值
  3. 一個對象變量並無實際包含一個對象,而僅僅引用一個對象,如:java

    Date deadline = new Date();

    有兩個部分。New Date()構造了一個Date類型的對象,它的值是新建立的對象的引用。這個引用儲存在deadline中。segmentfault

  4. 靜態域、靜態方法(用static修飾)伴隨着類一直存在。靜態方法經過類名調用。調用靜態方法不須要建立實例(這也是main是靜態方法的緣由)。
    https://www.cnblogs.com/LZL-s...

    靜態方法只能訪問靜態域。數組

  5. 在下面兩種狀況下使用靜態方法:
    一個方法不須要訪問對象狀態,其所需參數都是經過顯示參數提供(如:Math.pow)
    一個方法只須要訪問類的靜態域
  6. Java中方法參數的總結(Java中都是值傳遞,而不是引用傳遞):
    https://segmentfault.com/a/11...
    一個方法不能修改一個基本數據類型的參數(數值型或布爾型)
    一個方法能夠改變一個對象參數的狀態
    一個方法不能讓對象參數引用一個新的對象(Java中值傳遞的體現)
  7. 當且僅當類沒有提供任何構造器時,系統纔會提供一個默認的構造器。
  8. 類設計技巧:P144

第五章、繼承

  1. this的兩個主要用途:一是引用隱式參數,二是調用該類其餘的構造器;
    super的兩個主要用途:一是調用超類的方法,二是調用超類的構造器。
    調用構造器時,二者很類似,調用構造器的語句只能做爲另外一個構造器的第一條語句出現。
  2. Java不支持多繼承。Java中多繼承可經過接口實現。
  3. 多態、向上轉型和向下轉型:
    https://www.cnblogs.com/bette...
  4. 父子類構造方法:子類構造方法必須調用父類構造方法。不寫則有一個默認super()自動調用父類無參構造方法,若是父類沒有無參構造方法,會報錯,這時需在子類重載父類已有的有參數的構造方法便可。並且super重載必須是子類構造方法的第一句。
  5. 子類重寫方法的返回值範圍必須【小於等於】父類方法的返回值。例如父類返回值是void,子類是int,報錯;父類返回值是Object,子類是String,不報錯。
    子類方法的權限必須【大於等於】父類方法的權限修飾符
  6. 關於靜態綁定和動態綁定:
    https://www.cnblogs.com/bette...
  7. final:一個方法被聲明爲final,子類不能覆蓋重寫這個方法。一個域被聲明爲final,構造對象以後不能改變值。一個類聲明爲final,只是其中的方法自動成爲final,不包括類中的域。
  8. 內聯:若是一個方法沒有被覆蓋而且很短,編譯器就可以對它進行優化處理,這個過程稱爲內聯。(挖個坑,之後學到JVM時來填)
  9. 抽象方法必須在抽象類中
  10. 抽象類除了抽象方法,還能夠包含具體數據和具體方法。例如Person類能夠保存姓名和一個返回姓名的具體方法ide

    public abstract class Person
    {
        private String name;
        public Person(String name)
        {
            this.name = name;
        }
    
        public abstract String getDescription();
    
        public String getNmame();
        {
            return name;
        }
    }

    儘可能將通用的域和方法(不論是否是抽象的)放在超類(不論是否是抽象類)中。工具

  11. 類即便不含抽象方法,也能夠將類聲明爲抽象類。
    抽象類不能被實例化,若是將一個類聲明爲abstract,就不能建立這個類的對象
    注意:能夠定義一個抽象類的對象變量,可是它只能引用非抽象子類的對象。例如優化

    Person p = new Student("Vince Vu", "Economics");
    //p是一個抽象類Person的變量,Person引用了一個非抽象子類Student的實例

    能夠理解爲多態/向上轉型this

  12. 只有基本類型不是對象,例如:數值、字符、布爾類型的值。
  13. Object中的equals方法,若是是基本類型比較的是值,若是是對象比較的是地址值。String重寫了equals方法,比較的是兩字符串的內容是否相等。
    https://www.cnblogs.com/dolph...

    數組可使用靜態的Arrays.equals檢測相應的數組元素是否相等。重寫equals來比較兩個對象的建議:P169。IDEA直接能夠自動生成重寫的equals和toString方法。。。
    重寫equals,記得參數列表爲(Object other)。(重寫:在繼承中,方法的名稱同樣,參數列表也同樣;重載:方法名稱同樣,參數列表不同)
    getClass()是使用反射技術來判斷對象所屬的類。.net

  14. 不一樣的兩個對象可能會有相同的散列碼,因此重寫equals就必須重寫hashCode方法。P170。
    https://www.cnblogs.com/dolph...
  15. toString是一種很好的調試工具。數組可經過Arrays.toString。建議每個類都添加toString方法
  16. ArrayList:
    https://www.cnblogs.com/bette...
  17. 自動裝箱和拆箱:
    有一個頗有用的特性,便於添加int的元素到ArrayList<Integer>:設計

    list.add(3);

    將自動變換成

    list.add(Integer.valueOf(3));

    這種變化稱爲自動裝箱(autoboxing)(基本類型的數據->包裝類)

    相反地,當一個Integer對象賦給一個int值時,將會自動的拆箱(包裝類->基本類型的數據),包裝類沒法直接參與運算

    int n = list.get(i);

    自動變成

    int n = list.get(i).intValue();

    在算數表達式中也可以自動的裝箱和拆箱

    Integer n = 3;
    n++;

    編譯器將自動地插入一條對象拆箱的指令,而後進行自增計算,最後再將結果裝箱。
    比較兩個包裝器對象時要調用equals,若是用==可能會出錯。

  18. 包裝器中包含了一些基本方法,如一個整數字符串轉換成數值

    int x = Integer.parseInt(s);

    這裏與Integer對象沒有任何關係,parseInt是一個靜態方法,Interger類只是放置這個方法的地方。
    Integer.toString()能夠把一個整數轉換成字符串

  19. Integer對象是不可變的:包含在包裝器中的內容不會改變。因此

    public static void triple(Integer x) // won't work
    {
        ...
    }

    不會改變參數值。
    org.omg.CORBA包中定義持有者(holder)類型,能夠訪問儲存在其中的值,進而改變參數值。

  20. 參數數量可變的方法

    // 一個方法只能有一個可變參數;
    // 若是方法的參數有多個,那麼可變參數要寫在參數的末尾
    public static int max(int... values){
        int lagest=0;
        for (int i = 0; i < values.length ; i++) {
            if(values[i]>lagest)
                lagest=values[i];
        }
        return lagest;
    }
    //可變參數的特殊(終極)寫法
    public static void method(Object...obj){
    }
  21. 枚舉類型其實是一個類,例如

    public enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE };

    這個聲明定義的類型是一個類,它恰好有4個實例。
    比較兩個枚舉類型的值,永遠不要用equals,用==。
    枚舉類型中能夠添加一些構造器、方法和域。

  22. 反射(以後再回來看)
  23. Class類:Object中的getClass()方法能夠返回一個Class類型的實例。
  24. 繼承的設計技巧:P208

第六章、接口、lambda表達式與內部類

  1. 接口中的全部方法自動地屬於public,聲明時可省略。可是在實現接口時,必須把方法生命爲public
  2. 接口中的變量實際上是常量,接口不容許有實例域(常量)
  3. 實現Arrays中的sort方法:https://blog.csdn.net/qq_3785...
  4. 接口中的方法自動被設置爲public,接口中的域自動設爲public static final。java語言規範建議不要書寫這些多餘的關鍵字。
  5. 引用接口,而不是隻用抽象類的緣由是一個類只能繼承一個類,可是能夠實現多個接口
  6. 接口的默認方法與靜態方法:https://www.cnblogs.com/dustc...
    接口的默認方法能夠經過接口實現類對象,直接調用
    接口的默認方法能夠被接口實現類覆蓋重寫
    默認方法的主要優點是拓展接口的方法,而不破壞現有代碼。
  7. 解決默認方法衝突:

    • 超類優先:若是繼承了一個類,實現了一個接口,那麼超類優先
    • 接口衝突:若是實現了兩個接口有想通的方法,必須經過覆蓋來解決衝突
  8. lambda
  9. 內部類包括成員內部類、局部內部類和匿名內部類
  10. 如何使用成員內部類:
    間接方式:
      在外部類的方法中,使用內部類,在外部類方法中建立內部類對象,經過內部類對象調用內部類方法,main只是調用外部類的方法。經過外部類的對象,調用外部類的方法,裏面間接再使用內部類

    public class Outer
    {
    
        public class Inner{
            public void show(){
                System.out.println("內部類的方法");
            }
        }
    
        public void method(){
            System.out.println("外部類的方法");
            Inner inner = new Inner();            //建立內部類對象
            inner.show();                                //經過內部類對象調用內部類方法
        }
    
    }
    //經過調用外部類對象,調用外部類的方法
    public class Main
    {
        public static void main(String[] args) {
            Outer outer = new Outer();
            outer.method();
        }
    }

    直接方式:

    //類名稱  對象名  =  new  類名稱();
    //【外部類名稱.內部類名稱  對象名  =  new  外部類名稱().new  內部類名稱();】
    public class Main
    {
        public static void main(String[] args) {
            Outer.Inner inner = new Outer().new Inner();
            inner.show();
        }
    }
  11. 內部類既能夠訪問自身的數據域,也能夠訪問建立它的外圍類對象的數據域。(內用外,隨意訪問;外用內,須要先創建內部類對象,經過內部類對象訪問)
    沒重名可直接調用外部類數據域,若是重名,經過【外部類名稱.this.外部類成員變量名】來調用。

    public class Outer
    {
    
        private int num = 100;
        public class Inner{
            final int num = 200;
            public void show(){
                int num = 300;
                System.out.println(num);//300
                System.out.println(this.num);//200
                System.out.println(Outer.this.num);//100
            }
    
        }
    }
  12. 局部內部類定義:若是一個類是定義在一個方法內部的,那麼這就是一個局部內部類。「局部」:只有當前所屬的方法才能使用它,除了這個方法外面就不能用了。
    訪問局部內部類,是經過調用外部類包含該內部類的方法

    public class Outer
    {
    
        public void methodOuter(){
            class Inner {
                int num = 10;
                public void methodInner() {
                    System.out.println(num);
                }
            }
    
            Inner inner = new Inner();
            inner.methodInner();
        }
    
        public static void main(String[] args) {
            Outer obj = new Outer();
            obj.methodOuter();
        }
    }
  13. 類的權限修飾符:
    public > protected > (default) >private
    定義一個類的時候,權限修飾符:

    • 外部類:public / (default)
    • 成員內部類:public / protected / (default) / private
    • 局部內部類:什麼都不能寫
  14. 局部內部類想訪問所在方法的局部變量,這個局部變量必須是【有效final的】,即final或者沒有更改過的

    class Outer
    {
        public void methodOuter(){
            final int num = 5;
    //        num = 9;   錯誤
            class Inner {
            
                public void methodInner() {
    
                    System.out.println(num);
                }
            }
     
        }
    }
  15. 匿名內部類:若是接口的實現類,(或者是父類的子類)只須要使用惟一的一次,那麼這種狀況下就能夠省略該類的定義,二改成使用【匿名內部類】。

    /*
    匿名內部類格式
    接口名稱  對象名  =  new  接口名稱(){
    //覆蓋重寫全部抽象方法
    };   //注意要有分號
    */
    public static void main(String[] args){
        //匿名內部類
        MyInterface obj = new MyInterface(){    //new表明建立對象的動做                                                              //接口名稱是匿名內部類須要實現的接口
            @Override                                            //大括號中的內容纔是匿名內部類的內容
            public void method(){
    
            }
        };
        obj.method();
    }
    /*
    注意:
    1.匿名內部類,在【建立對象】的時候,只能使用惟一一次。若是但願屢次建立對象,並且類的內容同樣的話,那麼就必須使用單獨定義的實現類了。
    2.匿名對象,在【調用方法】的時候,只能調用惟一一次。若是但願同一個對象,調用屢次方法,那麼必須給對象起一個名字。
    3.匿名內部類是省略了【實現類/子類名稱】,可是匿名對象是省略了【對象名稱】。匿名內部類和匿名對象不是一碼事!!

    匿名內部類做用:不用專門寫一個類來實現接口,直接使用匿名內部類調用接口。

    若是想重複使用,就不要用任何匿名的東西。不論是匿名內部類仍是匿名對象。

    //若是有兩個對象,要寫兩遍
    //使用匿名內部類
    MyInterface objA = new MyInterface(){
        @Override
        public void method(){
            System.out.println("匿名內部類實現了方法!");
        }
    };
    objA.method();
    
    MyInterface objB = new MyInterface(){
        @Override
        public void method(){
            System.out.println("匿名內部類實現了方法!");
        }
    };
    objB.method();

    匿名對象:

    //使用了匿名內部類,並且省略了對象名稱,也是匿名對象
    new MyInterface(){
        @Override
        public void method1(){
            System.out.println("匿名對象匿名內部類實現了方法1");
        }
    
        @Override
        public void method2(){
            System.out.println("匿名對象匿名內部類實現了方法2");
            }
    }.method1();
    //匿名對象只能調用一次方法
    //若是還想調用method2還要建立一個新的匿名對象
    new MyInterface(){
        @Override
        public void method1(){
            System.out.println("匿名對象匿名內部類實現了方法1");
        }
    
        @Override
        public void method2(){
            System.out.println("匿名對象匿名內部類實現了方法2");
            }
    }.method2();
    //若是想重複使用,就不要用任何匿名的東西
  16. 內部類是一種編譯器現象,與虛擬機無關
相關文章
相關標籤/搜索