JAVA高級語法1:基礎


  1. 實例化:

    1567925803682
    不實例化,就是一個空指針

    注意,即使只是聲明,也是會分配空間的:

來源:https://zhidao.baidu.com/question/519582801799420045.html?qbl=relate_question_3
我們要看你這句int a處於什么地方,如果是在方法內部中被執行到,也就是說是局部變量,就會在棧內存中分配內存,由於是int型,所以就是4字節,也就是32bit,long類型的才會是64bit。
而你說的表示地址我們稱為堆內存。創建的對象以及對象中的方法和數據是存儲在堆內存中的。JVM會在棧內存中建立對象的引用,然后當執行到new語句時,在堆內存中創建對象,這時就將這個對象的類型以及這塊區域的內存地址值賦給引用,然后進行對象中數據的初始化。也就是說,對象的引用存儲在棧內存中,存放的是類型以及hash值,如Integer@0xff67。而對象里的內容實際上是存儲在堆內存中的。
如果你這句int a只是在某個對象內作為成員變量,那么根本不會涉及到棧內存。a就存儲在它所在的那個對象的堆內存中。明白了么?

所以說,如果是成員變量的話,如果是基本類型,會在聲明時直接在棧上給該類似的大小的內存空間;如果是引用類型,會在棧上給一個指針的大小。

  1. 1567926063450
    對變量的分類

    實例變量只有實例化之后才能使用,而類變量直接用類名就可以使用

    成員變量在堆,局部變量在棧

  2. 1567926294291

  3. 匿名對象

    new Person().shout();

    使用場景:

    1. 對一個對象只需要一次方法調用
    2. 作為實參傳遞給方法
  4. 方法的重載

    參數的個數或者參數的數據類型必須不同

  5. 可變個數的形參

    1. (String[] args)//定義字符串數組
    2. (String... args)//JAVA特有的點點點的方式,這種參數在使用時與數組的使用方式相同

    兩種方法的區別:

    ? 第一種如果沒有參數,需要輸入null或者一個空數組;而第二種直接不填就好(...代表可以傳遞0到多個參數)

  6. 方法的參數傳遞

    JAVA只有一種參數傳遞方法:值傳遞。即將實際參數值復制到方法的形參中,而參數本身不受影響(當然這種方法比較慢,但是JAVA嗎23333)

    1567927252595
    注意,對於引用對象,值還是變化了的,因為傳進去的實際是地址。但是即使修改了函數里的指針指向(例如在函數中new了一個對象並將指針指向了該對象),外部的實際指向也不會受影響,相當於指向了兩個不同的對象而已

  7. this關鍵字

    使用this的幾個優點:

    1. 不需要給方法中的形參亂起名字了

      1567929662728
      如圖,使用this的話,形參的名稱可以和成員變量相同,賦值的時候借助this區分就好,這樣就不需要在函數的形參上亂起名字了

    2. 增強程序閱讀性

    3. this可以作為一個類中,構造器相互調用的特殊格式

      1567929844806
      用於構造器重載時,可以直接調用已有的構造器然后進行修改即可,使構造器的編寫更加方便

      注意,這種情況下,this()必須放在構造器的首行(顯然)

  8. JAVA Bean

    1567930523599

    也就是說,符合這三條的都可以叫做javaBean

    1567930478899
    右鍵-》source-》general getters and setters,自動生成get和set方法

  9. 繼承(extends)和多態

    JAVA只支持單繼承

    繼承讓類與類之間產生了關系,不要僅僅為了獲取其他類中的某個功能而去繼承-》繼承是要有邏輯關系在其中的

  10. 方法的重寫(@override)

    • 重寫只能重寫方法體,名稱、參數列表和返回值類型均不能改
    • 重寫方法不能使用比被重寫方法更加嚴格的訪問權限
    • 子類方法拋出的異常不能大於父類被重寫方法的異常

    題外話:ctrl+/:eclipse快速注釋代碼

    1567933293375
    如果子類和父類在同一個包下,那么對於父類的成員修飾符除了private之外,剩下的情況子類都可以使用父類的成員變量;如果不在一個包下,只有protected和public的成員變量可以使用

  11. super關鍵字

    super和this類似,但是是用於調用父類的成員變量和方法的。

    使用super,子類可以調用父類之上的所有父類層級

    this和super的區別:

    1567933691109
    在子類中,通過This或者super調用構造器,只能使用一個,因為都要占據第一行

  12. 類對象的實例化過程

    1567933853468
    有繼承時:

    1567933943287
    在方法區,先加載父類方法,再加載子類方法

    子類構造方法先入棧,父類再入棧,所以父類先執行

  13. instanceof操作符

    instance:實例

    1567934573311
    屬於子類也行

  14. Object類

    1567934698585 也叫基類
    形參定義為object類型,則可以接受任何類型的類(注意,必須是個類!)
    1567934831018

    • equal:比較引用對象:是否引用了同一個對象(也就是一個new出來的對象)

      Person e=new person();
      Person p=new person();//此時e和p指向的是堆中的兩個不同的對象,此時用equal方法檢測是false
      e=p;//此時e被重定向到p,此時再檢測就是true了
      
  15. 對象的類型轉換

    1567935304860
    能進行的是有繼承關系間的類型的轉換

    從子類到父類:

    ? 1567935647850
    由此可見,object對象可以接收任何類型的對象

    從父類到子類:

    ? 1567935689642
    示例代碼:

    1567936024337
    e可以接受父類為Person類的各種類的對象,然后檢查其是否是Student類或Student類的子類,如果是,就執行Student類中獨有的方法,否則執行其他方法。

  16. ==操作符和equals方法

    1567936263845
    只有指向同一個對象,==才為true,而比較的不是成員變量的值是否相等

    equals和==功能相同,除了下面說的幾個特殊情況:

    1567936393976

    注意String的比較要使用equals而不是==

  17. String對象的創建

    1567936600983
    可以看到,無論是哪一種方法,同樣的字符串也不會保留多個

    1567936738889
    --所以字面量創建更加省內存,所以其常用

    而“不重復”只全體現在常量池上,如果使用New的方式,堆中每次都會創建一個新的對象。最特別的是最后一種情況,常量池中添加的是拼接錢的串,而堆中創建的卻是拼接后的串

  18. 包裝類
    1567940987662
    將基本數據類型賦予了類的方法

    1567941056182

    • 自動拆箱、裝箱:和基本數據類型寫法可以保持一致(轉換更簡單,使用起來比基本數據類型更方便、功能更強大)

    • 包裝類的功能:

      借助包裝類的類方法,將字符串轉換為對應類型的數據(注意,只是借助其實現轉換,並沒有直接使用包裝類)

      1. 字符串轉其他基本數據類型

      int i=Integer.parseInt("123");

      boolean b=Boolean.parseBoolean("false");

      1. 其他基本數據類型轉字符串

      String istr=String.valueOf(i);

      String batr=String.valueOf(b);

      ->綜上,包裝類主要應用於字符串和其他基本數據類型的應用

  19. 重寫toString()

    toString方法是直接用System.out.printIn()打印時調用的方法。默認的toString()是類Object的方法,由於其是所有類的父類,所以其功能比較泛,該方法就是輸出內存地址(大多數情況下這是沒什么用的)。所以各個類可以重寫該方法以打印有意義的內容。

  20. static關鍵字

    static用來設置類屬性和類方法

    1567941969678
    static一般只用Public修飾

    類屬性被所有對象所共用,可以用來計數什么的

  21. 單例設計模式--設計模式之一

    • 什么是設計模式?

      1567942247272
      設計模式就是實際編程中逐漸總結出來的一些解決問題的套路

    • 單例

      只有一個實例(實例化對象)

      在整個軟件系統運行過程中,這個類只被實例化一次,以后不論在哪都只調用這一個實例

      1567942357483

    • 應用的場景:

      1. 該對象的創建要消耗大量的時間和資源
      2. 重復new對象沒有必要
    • 兩種實現方式:

      1. 1567942732316
        先構造后使用

        構造方法私有化,不能new

        實例化也是私有的,引用是私有的類變量

        利用公有的方法返回那個類變量

        這樣的話,程序中永遠只有一個實例化對象

      2. 1567943121140
        先不構造,用的話再構造,如果從來不用就算了,就這一點區別

        先判斷(s1==null)來判斷是否需要實例化

    1567943668335

  22. 理解main方法

    ? 1567943755648
    例如cmd,即可給main傳參

  23. 初始化代碼塊

    1567944332140
    作用:對JAVA對象進行初始化

    類的成員初始化過程:聲明成員變量默認值-》顯示初始化,執行代碼塊-》執行構造方法

    • 靜態代碼塊

      1567944805892
      靜態代碼塊用於初始化靜態屬性

      非靜態代碼塊每次new都要重新執行,而靜態代碼塊只執行一次。且靜態先於非靜態執行

    1567945131153
    在實際應用中,靜態代碼塊用的比較多,用於初始化靜態類屬性(尤其對於一些比較復雜的靜態類屬性,例如屬性是一個類的情況下),非靜態的作用不太大

  24. 匿名內部類

    對Person類的方法進行了重載,所以其其實是一個Person的子類,故稱為匿名內部類

    1567946613503
    匿名內部類中成員變量的初始化(如果要和父類的初始化有所不同的話)無法通過構造方法實現(因為沒有類名,無法創建構造方法),只能通過代碼塊的方式完成

  25. final關鍵字

    1567946843746
    概況一下,final修飾的內容初始化之后就不能再修改了,所以變量要均大寫,和常量保持一致(final修飾的變量是常量,常量必須顯式賦值

    1567947033873
    final static:全局常量

  26. 抽象類

    1567947138828
    含有抽象方法的類必須被聲明為抽象類

    注意,抽象類中不一定所有方法都是抽象的,如果都是抽象的就是接口了

    final和abstract是沖突的

    1567947265366
    1567947315639
    抽象類可以有構造方法

  27. 模板方法設計模式--設計模式之二

    • 1567947413784 * 1567947854872
  28. 接口

    1567947909883
    接口中只有定義,沒有實現

    interface定義,implements使用

    1567948569774
    類可以實現多個接口,多個接口之間用,分割

    1567948730475
    當有一個新的需求時:

    • 如果父類新增抽象方法,子類就必須實現,否則就需要定義為抽象類。

    • 解決方法就是不要在父類中新增抽象方法,而是新增一個接口,由子類去選擇是否實現這一接口

      父類需要穩定的抽象,不能總是在改

    需要描述一個交叉的關系時:

    1567948971562

    • 不能使用類的繼承解決這個問題:會污染類的繼承,使繼承關系沒有邏輯性
    • 實現接口就好(接口是一類方法(動作)的集合

    對抽象類和接口的總結:

    • 抽象類是對於一類事物的高度抽象,其中既有屬性也有方法
    • 接口是對方法的抽象,也就是對一系列動作的抽象
    • 當需要對一類事物抽象的時候,應該使用抽象類,好形成一個父類;當需要對一系列動作抽象時,就使用接口

    匿名內部類在接口中的應用

    看到了以下一段代碼:

    1568038108936
    這里的Runnable是接口,我們知道接口是不能實例化對象的,那這里是什么情況呢?

    其實這不是聲明了一個接口類型的對象,而是一種多態機制,專業名詞叫“匿名內部類”,實際上是創建了一個遵守了該接口的普通類(Object)對象。

    類似的使用還有下面,可以看到,類能聲明的接口幾乎都可以聲明

    interface  Shape {
        void  draw();
    }
    public class Main {
      // interface type as instance variable
      private Shape myShape;
    
      // interface type as parameter type for a constructor
      public Main(Shape s) {
        this.myShape = s;
      }
    
      // interface type as return type of a method
      public Shape getShape() {
        return this.myShape;
      }
    
      // interface type as parameter type for a method
      public void setShape(Shape s) {
        this.myShape = s;
      }
    
      public void letItSwim() {
        // interface type as a local variable
        Shape locaShape = null;
    
        locaShape = this.myShape;
    
        // interface variable can invoke methods
        // declared in the interface and the Object class
        locaShape.draw();
      }
    }
    

    這其實是一種變相的“用接口作為類型”,也是面向接口的編程的思想之一。

  29. 工廠模式——設計模式之三

    1567949332262
    1567949461353
    在真正的開發工作中,都是合作開發,每個開發人員寫一部分,集合到一起成為一個項目

    問題:一個開發人員要改代碼,例如改類名,會影響其他人的工作。因此降低了工作效率

    解決方法:寫一個產品接口類,一個工廠接口類,其他人用工廠類而不是直接用產品類。通過工廠將new對象隔離,通過產品的接口接受不同實際產品的實現類,實例的類名的改變不影響其他合作開發人員的編程。其他開發人員只需要關注工廠類的使用,而修改代碼只限於產品類的名稱和工廠類的代碼,不會影響工廠類的使用。(這種設計可能是架構師的任務(?ω?))

    無論是內部類還是其他,JAVA除了很早期的一些特征外,剩下的特征都是為了解決一些特點問題必不可少的,不是冗余的功能

  30. 內部類

    1567955489008
    內部類是外部類的成員

    注意外部類調用內部類時方法

    1567956213887
    內部類可以聲明private 或者protected

    內部類的聲明和外部類互相不影響,可以重名

    內部類的作用:

    • 內部類的最大作業是實現多重繼承(A想同時獲得類B和類C的方法並重寫)

    • 1567956778941


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM