Java答疑解惑

TerDandridg 8年前發布 | 11K 次閱讀 Java 面向對象編程 Java開發

前言

記錄一些Java中讓人疑惑的知識點,幫助我們更好的理解代碼。

正文

  1. Java程序的入口——main方法

    public static void main(String[] args) {
         // TODO Auto-generated method stub
     }

    main方法為java程序的入口,public static 表示這是一個公開的靜態方法,方法中代碼存儲在靜態存儲區。main()方法中的public、static沒有先后順序,也可以把main()方法定義為final。只有與.java文件同名且用public修飾的類中的main()方法才能作為整個程序的入口方法。

  2. java程序初始化的順序

    依次滿足:

    • 靜態先于非靜態
    • 父類先于子類
    • 變量先于代碼塊,代碼塊先于構造方法
  3. 修飾符的作用域

    java修飾符作用域.png

  4. java創建對象的方式
    四種:
    • new 出一個對象;
    • 通過反射機制創建對象;
    • clone()方法創建;
    • 反序列化方法創建。
  5. 構造函數
    • 構造函數必須與類的名字相同,不能有返回值(void也是返回值)
    • 每個類都可以有多個構造函數,可提供不同參數(個數、類型、順序)的構造函數
    • 構造函數總是伴隨著new操作一起調用(只能由系統調用,且只調用一次。)
    • 構造函數不能被繼承,所以它不能被覆蓋,但是可以被重載,即定義多個構造函數。
    • 子類可以通過super關鍵字來顯式調用父類的構造函數。當父類沒有提供無參構造函數時,子類的構造函數中必須顯式地調用父類構造函數。當有父類時,在實例化對象時會先執行父類的構造函數,再執行子類的構造函數。
    • 默認構造器的修飾符只跟當前類的修飾符有關(一致)。
  6. 淺復制與深復制
    淺復制:僅復制所考慮的對象
    深復制:把復制的對象所引用的對象都復制了一遍。
  7. 多態
    多態表示當同一個操作作用在不同對象時,會有不同的語義,從而會產生不同的結果。
    java提供了兩種用于多態的機制,分別為通過方法的重載實現的編譯時多態;通過方法的覆蓋實現的運行時多態。
  8. 重載和覆蓋

    重載是在一個類中多態性的一種表現,是指在一個類中定義了多個同名的方法,它們或有不同的參數個數或有不同的參數類型。

    • 重載是通過不同的方法參數來區分的(個數、類型、順序)
    • 不能通過方法的訪問權限、返回值類型和拋出的異常類型進行重載
    • 對于繼承來說,如果基類的方法訪問權限為private,那么就不能在派生類對其重載。

    覆蓋是指派生類函數覆蓋基類函數,覆蓋一個方法并對其重寫,以達到不同的作用。

    • 派生類中的覆蓋方法必須要和基類中被覆蓋的方法有相同的函數名和參數
    • 派生類中的覆蓋方法的返回值必須和基類中被覆蓋的方法的返回值相同
    • 派生類中的覆蓋方法所拋出的異常必須和基類(或是其子類)中被覆蓋的方法所拋出的異常一致。
    • 基類中被覆蓋的方法不能定義為private,否則其子類只是定義了一個方法,并沒有對其覆蓋。
  9. 重載和覆蓋的區別

    • 覆蓋是子類和父類之間的關系,是垂直關系;重載是同一個類中方法之間的關系,是水平關系。
    • 覆蓋只能由一個方法或只能由一對方法產生關系;重載是多個方法之間的關系。
    • 覆蓋要求參數列表相同;重載要求參數列表不同方。
    • 覆蓋關系中,調用方法體是根據對象的類型(對象對應存儲空間類型)來決定;而重載關系是根據用時的實參表與形參表來選擇方法體的。
  10. 抽象類與接口

    如果一個類中包含抽象方法,那么這個類就是抽象類。

    接口就是指一個方法的集合,接口中的所有方法都沒有方法體。

    interface MyInterface{
    public int myMethod(int a ,int b);
    }

    接口與抽象類的相同點

    1. 都不能被實例化;
    2. 接口的實現類或抽象類的子類都只有實現了接口或抽象類中的方法后才能被實例化。

    接口與抽象類的不同點

    1. 接口只有定義,其方法不能在接口中實現,只有實現接口的類才能實現接口中定義的方法,而抽象類可以有定義與實現,即其方法可以在抽象類中被實現。
    2. 接口需要實現,但抽象類只能被繼承,使用接口可以間接達到多重繼承的目的。
    3. 接口強調特定功能的實現,其設計理念是“has - a”關系;而抽象類強調所屬關系其設計理念為“is - a”關系。
    4. 接口中定義的成員變量默認為public static final ,只能夠由靜態的不能被修改的數據成員,而且必須給其賦初值,其所有成員方法都是public 、abstract的,而且只能被這兩個關鍵字修飾。而抽象類可以有自己的數據成員變量,也可以有非抽象的成員方法,而抽象類中的成員變量默認為default,這些成員變量在子類中可以重新定義也可以重新賦值,抽象類中的抽象方法不能用private、static、synchronized、native等修飾符修飾,同時方法必須以分號結尾,并且不帶花括號。所以,當功能需要累積時,用抽象類;不需要累積時,用接口。
    5. 接口被運用于實現比較常用的功能,便于日后維護或者添加刪除方法;而抽象類更傾向于充當公共類的角色,不適用于日后重新對里面的代碼進行修改。
      簡單地說,接口是一種特殊形式的抽象類,使用接口完全有可能實現于抽象類相同的操作,但一般而言,抽象類多用于在同類事物中具有無法描述的方法場景,所以當子類和父類存在有邏輯上的層次結構時,推薦使用抽象類;而接口多用于不同類之間,定義不同類之間的通信規則,所以當希望支持差別較大的兩個或者更多對象之間的特定交互行為時,應該使用接口。
      此外,接口可以繼承接口,抽象類可以實現接口,抽象類也可以繼承具體類。抽象類也可以有靜態的main方法。
    </li>
  11. 內部類

    靜態內部類是指被聲明為static的內部類,它可以不依賴于外部類的實例而被實例化,而通常的內部類需要在外部類實例化后才能實例化。靜態內部類不能與外部類有相同的名字,不能訪問外部類的普通成員變量,只能訪問外部類中的靜態成員和靜態方法(包括私有類型)。

    非靜態內部類中不能定義靜態成員,靜態內部類不能訪問外部類的非靜態成員。

  12. break、continue、return

    • break用于直接強行跳出當前循環,不再執行剩余代碼
    • continue用于停止當次循環,回到循環起始處,進入下一次循環操作。
    • return語句是一個跳轉語句,用來表示從一個方法返回(返回一個值或者其他復雜類型),可以使程序控制返回到調用該方法的地方。
    • 帶標識的break語句,用于跳出多重循環。
    • </ul> </li>
    • final、finally、finalize

      • final用于聲明屬性、方法和類,分別表示屬性不可變、方法不可覆蓋和類不可被繼承。
      • finally作為異常處理的一部分,表示這段語句最終一定被執行,經常被用在需要釋放資源的情況下。
      • finalize是Object類的一個方法,在垃圾回收器執行時會調用被回收對象的finalize()方法,可以覆蓋此方法來實現對其他資源的回收,如關閉文件等。
      • </ul> </li>
      • assert
        assert即斷言,是一種軟件調試的方法,提供了一種在代碼中進行正確性檢查的機制。
      • volatile關鍵字
        volatile是一個類型修飾符,用來修飾被不同線程訪問和修改的變量。被volatile類型定義的變量,系統每次用到它時都是直接從對應的內存當中提取,而不會利用緩存。所有線程在任何時候所看到的volatile修飾的變量都是相同的。
      • strictfp
        strictfp是strict float point 的縮寫,指精確浮點,它用來確保浮點數運算的準確性。
      • 基本數據類型

        java一共提供了8種原始的數據類型(boolean,byte,short,int,long,float,double,char),這些數據類型不是對象,而是java語言中不同于類的特殊類型,這些基本類型的數據變量在聲明后就會立刻在棧上被分配內存空間。注意:String 不是基本數據類型。除了這8種數據類型外,其他類型都是引用類型。

        java基本數據類型.png

      • java運算符優先級

        運算符優先級.png

      • Java IO

        在java語言中,輸入和輸出都被稱為抽象的流,流可以被看作一組有序的字節集合,即數據在兩設備之間傳輸。

        流的本質是數據傳輸,根據處理數據類型的不同,流可以分為兩大類:字節流和字符流。字節流和字符流最主要的區別為:字節流在處理輸入輸出時不會用到緩存,而字符流用到了緩存。

        字節流繼承于InputStream與OutputStream,字符流繼承于Reader與Writer。

      • Java Socket
        網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個雙向鏈路的一端稱為一個Socket。Socket也稱為套接字,可以用來實現不同虛擬機或不同計算機之間的通信。
        Socket分為兩種類型:面向連接的Socket通信協議(TCP,傳輸控制協議)、面向無連接的Socket通信協議(UDP,用戶數據報協議)。
      • Java加載class文件的原理機制

        class加載方式分為隱式加載與顯式加載兩種。隱式加載指的是程序在使用new等方式創建對象時,會隱式的調用類的加載器把對應的類加載到JVM中。顯式加載指的是通過直接調用class.forName()方法來把所需的類加載到JVM中。

      • Java中容易引起內存泄露的地方

        • 靜態集合類。
        • 各種連接,如數據庫、網絡、IO等等。
        • 監聽器
        • 變量不合理的作用域。
        • 單例模式可能會造成內存泄露。(靜態的單例對象持有引用)
        • </ul> </li>
        • Java中的堆和棧

          • 棧內存主要是用來存放基本數據類型與引用變量。
          • 堆內存用來存放運行時創建的對象。一般來講,通過new 關鍵字創建出來的對象都存放在堆內存中。
          • </ul> </li>
          • 集合框架

            • Set 表示數學意義上的集合概念。最主要的特點就是集合中的元素不能重復,該接口有兩個實現類:HashSet、TreeSet。其中TreeSet實現了SortSet接口,因此TreeSet容器中的元素是有序的。
            • List又稱為有序的Collection。它按對象進入的順序保存對象,所以它能對列表中的每個元素的插入和刪除位置進行精確地控制。同時,它可以保存重復的對象。該接口的實現類有:LinkedKist,ArrayList和Vector。
            • Map提供了一個從鍵映射到值的數據結構。鍵唯一,值可以重復。實現該接口的類有:HashMap,TreeMap,LinkedHashMap,WeakHashMap,IdentityHashMap。
            • </ul> </li>
            • 迭代器

              迭代器(Iterator)是一個對象,它的工作是遍歷并選擇序列中的對象,它提供了一種訪問一個容器對象中的各個元素,而又不必暴露該對象內部細節的方法。

              import Java.util.*;
              public class IteratorTest{
              public static void main(String[] args){
                  List<String> ll = new LinkedList<String>();
                  ll.add("first");
                  ll.add("second");
                  ll.add("third");
                  ll.add("fourth");
                  ll.add("fifth");

              for(Iterator<String> iter = ll.iterator;iter.hasNext();){
                  String str = (String)itr.next;
                  System.out.println(str);
              }
              

              } }</code></pre> </li>

            • Collection和Collections
              Collection是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。實現該接口的類主要又List和Set,該接口的設計目標是為各種具體的集合提供最大化的統一操作方式。
              Collections是針對集合類的一個包裝類,它提供一系列靜態方法以實現對各種集合的搜索、排序、線程安全化等操作,其中大多數方法都是用來處理線性表。Collection.sort(list)。
            • 線程,進程,多線程

              線程是指程序在執行過程中,能夠執行程序代碼的一個執行單元。

              進程是指一段正在執行的程序,一個進程可以擁有多個線程,各個線程之間共享程序的內存空間(代碼段、數據段和堆空間)及一些進程級的資源(例如打開的文件),但是各個線程擁有自己的棧空間。

              進程與線程的對比關系.png

              多線程的便利:

              • 減少程序的響應時間;
              • 線程的創建與切換開銷更小;
              • 提高CPU的利用率;
              • 簡化程序的結構,便于理解與維護。
              • </ul>

                Java多線程的實現方法:

                • 繼承Thread類,重寫run()方法。
                • 實現Runnable接口,并實現該接口的run()方法。
                • 實現Callable接口,重寫call()方法。

                只有調用線程的start()方法才能真正達到多線程的目的,run()方法只是當作普通函數來調用。

                多線程同步的實現方法:

                • 使用synchronized關鍵字。
                • wait()方法與notify()方法。
                  在synchronized代碼被執行期間,線程可以調用對象的wait方法,釋放對象鎖,進入等待狀態,并且可以調用notify()方法或notifyAll()方法通知正在等待的其他線程。notify()方法僅喚醒一個線程(等待隊列中的第一個線程),notifyAll()方法喚醒所有等待這個對象的線程,讓他們去競爭,獲得鎖。
                • Lock,以阻塞的方式獲取鎖。
                </li> </ol>

                參考資料

                《java核心技術》

                《java編程思想》

                《java程序員面試筆試寶典》

                 

                來自:http://www.jianshu.com/p/fadc96a90daf

                 

 本文由用戶 TerDandridg 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!