Java 面試總結(一) —— 面試常問的關鍵字總結

關鍵字:html

  • final finalize finally
  • throws和throw
  • static關鍵字的做用
  • abstract 和 interface 
  • super 和 this
  • synchronize 和 volatile

1. final finalize finally對比

(1)性質不一樣面試

  • final爲關鍵字;
  • finalize()爲方法;
  • finally爲爲區塊標誌,用於try語句中;

(2)做用不一樣安全

  • final:用於標識常量的關鍵字,final標識的關鍵字存儲在常量池中(在這裏final常量的具體用法將在下面進行介紹);final定義的變量值不可變,方法不可覆寫,類不可繼承
    • 定義變量:一旦初始化(聲明處或構造函數中)便不可改變。對基本類型是其值不可變,對引用類型是引用不可變;(String天生就是final的)
    • 定義方法:1)使用final定義的方法,不容許覆寫,認爲其功能知足要求無需擴展時;2)容許編譯器將全部對此方法的調用轉化爲inline(行內機制),便可以將此方法直接複製在調用處,而不是進行例行的方法調用(保存斷點、壓棧),能夠提升效率。但若是過多的話,會形成代碼膨脹,反而會影響效率,慎用。
    • 定義類:沒法被繼承,這也就意味着此類在一個繼承樹中是一個葉子類;類成員是否是final均可以。多線程

  • finalize():方法在Object中進行了定義,用於在對象「消失」時,由JVM進行調用用於對對象進行垃圾回收,相似於C++中的析構函數;用戶自定義時,用於釋放對象佔用的資源(好比進行I/0操做);
  • finally{}:用於標識代碼塊,與try{}進行配合,是異常處理模型的補充,不論try中的代碼執行完或沒有執行完(這裏指有異常),該代碼塊之中的程序一定會進行;不可單獨使用,在一個try...catch...finally語句塊中最多隻有一個finally;通常用來維護對象的內部狀態,清理非內存資源。

 

2. throws和throw對比

(1)使用位置不一樣jvm

  • throw位於方法體內部,能夠做爲單獨語句使用;
  • throws位於方法頭部的參數列表後面,不能單獨使用;

(2)內容不一樣函數

  • throw拋出一個具體的異常對象,並且只能是一個;
  • throws聲明拋出的異常類,能夠同時聲明多個;

(3)做用不一樣post

  • throw用於在程序中拋出異常,一旦執行說明必定有異常拋出,由方法體內部語句處理異常;
  • throws用於聲明在該方法內可能拋出的異常類,若是拋出了異常,由該方法的調用者處理,層層上拋;

總結:函數調用時,若是須要向上層拋出異常,就必須在函數頭部顯式地聲明(throws Exception1, Exception2)異常類型;若是僅須要在方法體內部處理異常,方法體內部可自行處理該異常,thorw拋出具體的異常實例(catch(Exception1 e){...})性能

 

3. static關鍵字的做用

static關鍵字可用來修飾屬性、方法、代碼塊,目的是把對象相關的變成類相關的,即:不加static的成員是對象相關的,歸單個對象全部;加static修飾的成員是類成員,能夠經過類名直接調用,歸全部對象全部。優化

static修飾的成員變量和成員方法習慣上稱爲靜態變量和靜態方法,能夠直接經過類名來訪問,訪問語法爲:this

  • 類名.靜態方法名(參數列表…)
  • 類名.靜態變量名

(1)static修飾屬性(類變量、靜態變量)

  • 被static修飾的變量,叫靜態變量或類變量,可經過類名直接訪問;沒有被static修飾的變量,叫實例變量。
  • 靜態變量爲本類全部對象共享;實例變量只屬於單個對象。
  • 靜態變量在內存中只有一個拷貝,類加載時被建立和初始化,JVM只爲其分配一次內存(節省內存)。類加載過程只進行一次,所以靜態變量也只會被建立一次;實例變量在建立對象時被初始化,在內存中有多個拷貝,每建立一個對象就會爲其分配一次內存,各實例變量間互不影響(靈活)。

因此通常在須要實現如下兩個功能時使用靜態變量:

1).在對象之間共享值時;2).方便訪問變量時

(2)static修飾方法(靜態方法)

  • static修飾的方法,叫靜態方法,可經過類名直接訪問,爲本類全部對象共享;
  • 靜態方法不能訪問本類的非靜態成員(包括實例變量和方法,由於非靜態則和特定的對象關聯,就不能全類共享了),可是非靜態方法能夠訪問靜態成員(ofcourse,靜態成員全類共享);
  • 靜態方法中不能出現this和super關鍵字(由於this是指向當前對象,super().成員名調用父類成員);
  • 由於static方法獨立於任何實例,所以static方法必須被實現,而不能是抽象的abstract;
  • 子類覆蓋父類的靜態方法時,只能依然覆蓋爲靜態方法(一日static終生static),可是沒有多態。

Java中main方法必須爲static的緣由:

在類加載時沒法建立對象,而靜態方法能夠不經過對象調用,因此在類加載時能夠經過main方法入口運行程序。

 

(3)static修飾代碼塊(初始化塊、靜態代碼塊)

格式: static{...}

static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,能夠有多個,位置能夠隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,若是static代碼塊有多個,JVM將按照它們在類中出現的前後順序依次執行它們,每一個代碼塊只會被執行一次。

 

初始化總結(靜態變量->實例變量->按聲明初始化->執行構造方法)

1) 首次使用某個類時,JVM查找相應的類文件加載(Java只有在必要時纔會逐步載入相應的類文件)

首先爲全部的靜態變量分配存儲空間並初始化爲默認值(全局變量),而後按照聲明靜態變量時指定的初始化動做的順序,以及靜態初始化塊中的語句在類定義中出現的順序依次執行。這些靜態的初始化動做只會在其所屬類的類文件加載時執行一次。

2)類文件加載完畢後,若是須要建立類的對象,則進行以下初始化動做

JVM爲全部的實例變量分配足夠的存儲空間並初始化爲默認值(局部變量);而後按聲明實例變量時指定初值的初始化動做和實例初始化塊中的語句在類中出現的順序依次執行,以後再調用相應的構造方法。

 

4. abstract 和 interface 對比

stract class和interface是支持抽象類定義的兩種機制。正是因爲這兩種機制的存在,才賦予了Java強大的面向對象能力。abstract class和interface之間在對於抽象類定義的支持方面具備很大的類似性,區別:

  Abstract class Interface
實例化 不能    不能
抽象類通常只能做爲其餘類的基類。一個類只能有一重繼承關係。 一個類能夠實現多個interface
數據成員 可有私有的,默認是friendly 型,其值能夠在子類中從新定義,也能夠從新賦值,能夠非abstract 不可有私有的,默認是public static final 型,且必須賦初值,實現類中不能從新定義,不能改變其值。
方法成員 能夠私有的,能夠有非abstract方法,必須實現 不可有私有的,默認是public,abstract 類型
設計理念 表示的是「is-a」關係 表示的是「like-a」關係
實現 須要繼承,要用extends 須要實現,用implements

抽象類(Abstract Class):

(1)只能做爲其餘類的基類,不能被實例化(new);

(2)抽象類中的成員是否是abstract無所謂,並非必須的。(能夠有抽象成員,也能夠沒有任何抽象成員)

(3)抽象類不能同時是final的。抽象的老是但願被繼承,而final類不可被繼承。final和abstract不可同時存在。

(4)非抽象類繼承抽象類,必須覆蓋其全部的抽象成員。抽象類繼承抽象類,能夠不覆蓋全部的抽象成員。

(5)抽象類容許被聲明

 

接口(interface):

接口的本質是一種特殊的抽象類,用來描述系統對外提供的全部服務。

(1)接口中,全部方法都是公開、抽象的:public abstract。(都必須被繼承)

(2)接口中,全部屬性都是公開、靜態、常量:public static final,且必須賦初值。(全部實現類共享且不可改變)

接口老是但願被實現被訪問的,所以全部成員都必須是公開的(public),確保外界能夠訪問。接口僅僅描述系統能夠作什麼,但不指明如何去作,具體操做由實現類完成,所以方法都是abstract的,都必須被繼承;接口不涉及任何的實現細節,所以無構造方法,接口不能被實例化;無變量,只有靜態常量(static final),由於要被全部的實現類共享;類的繼承只能單繼承,可是接口能夠一次實現多個,用「,」隔開。

 

5. super 和 this對比

super:

super能夠理解爲是指向本身父類對象的一個指針,指的是離本身最近的一個父類

用法:

  • super.成員名(變量名或者方法名()):顯式調用父類的同名成員,固然成員不能是private的(不容許子類訪問)。由於當子類和父類存在同名成員時,由於子類成員優先級更高,此時會隱藏父類的相應成員。
  • super(參數列表);:調用父類的構造函數,注意super語句必定要放在函數體的第一條 :

 

this:

this能夠理解爲指向當前對象自身的一個指針,即當前正在執行本方法的那個對象實例。位於函數體內部。

用法:

  • this.成員名:引用成員變量。由於函數參數或者函數中的局部變量和成員變量同名的話,成員變量被屏蔽,此時要訪問成員變量則須要使用「this.成員變量」的方式引用。
  • this(參數列表);:調用本類中參數表一致的另外一個構造函數,注意應做爲構造函數中的第一條語句。

引用構造函數時:

super(參數):調用 父類中的某一個構造函數(應該爲構造函數中的第一條語句)。
this(參數):調用 本類中另外一種形式的構造函數(應該爲構造函數中的第一條語句)。

this和super都無需聲明。

 

6. synchronize 和 volatile對比

(1)做用範圍:volatile僅能使用在變量級別;synchronized則可使用在變量、方法、和類級別;

(2)volatile本質是在告訴jvm當前變量在寄存器(工做內存)中的值是不肯定的,須要從主存中讀取;synchronized則是鎖定當前變量,只有當前線程能夠訪問該變量,其餘線程被阻塞住。

(3)volatile不會形成線程的阻塞;synchronized可能會形成線程的阻塞。

(4)volatile只能在線程內存和主內存之間同步一個變量的值,而synchronized則同步在線程內存和主內存之間的全部變量的值,經過鎖住和釋放監聽器來實現。

(5)volatile標記的變量不會被編譯器優化;synchronized標記的變量能夠被編譯器優化

(6)顯然,synchronized在性能上將比volatile更加有所消耗

(7)volatile僅能實現變量的修改可見性,不能保證原子性;而synchronized則能夠保證變量的修改可見性和原子性

 

詳細的 synchronize 和 volatile用法介紹請見博文:Java多線程(二) —— 線程安全、線程同步、線程間通訊(含面試題集) 第二節【2、線程同步】

相關文章
相關標籤/搜索