面試官常問的 Java 基礎題(四)

31.String s = new String(“xyz”);創建了幾個 String 對象? 二者之間有什麼區別?

分兩種情況: 1、如果String常量池中,已經創建"xyz",則不會繼續創建,此時只創建了一個對象new String(“xyz”),此時爲一個對象; 2、如果String常量池中,沒有創建"xyz",則會創建兩個對象,一個對象的值是"xyz",一個對象new String(“xyz”),此時爲兩個對象;

這裏需要了解幾個概念:

  • 棧:由JVM分配區域,用於保存線程執行的動作和數據引用。

  • 堆:由JVM分配的,用於存儲對象等數據的區域。

  • 常量池constant pool :在堆中分配出來的一塊存儲區域,用於存儲顯式 的String,float或者integer.這是一個特殊的共享區域,可以在內存中共享的不經常改變的東西,都可以放在這裏。

32.String 和 StringBuffer 的區別

String :值不可變,有equals方法。 StringBuffer :值可變,沒有equals方法。

JAVA 平臺提供了兩個類:
String 和 StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。這個 String 類提供了 數值不可改變的字符串。 而這個StringBuffer類提供的字符串進行修改。
當你知道字符數據要改變的時候你就可以使用StringBuffer,可以使用StringBuffers來動態構造字符數據。
另外, String實現了equals方法, newString(“abc” ).equals(newString(“abc” ) 的結果爲 true,而 StringBuffer 沒有實現 equals 方法,所以, newStringBuffer(“abc” ).equals(newStringBuffer(“abc” )的結果爲 false。

33.如何把一段逗號分割的字符串轉換成一個數組?

用正則表達式

代碼爲:

		String orgStr="a,b,c,d,e,f";  
        String [] result = orgStr.split(",");

34.數組有沒有 length() 方法? String 有沒有 length() 方法?

數組沒有 length() 方法,String 有 length() 方法。

數組沒有 length()這個方法,有 length 的屬性。String 有 length()這個方法。

35.try{}裏有一個 return 語句,那麼緊跟在這個 try 後的 finally{}裏的 code 會不會被執行,什麼時候被執行,在 return 前還是後?

finally{}裏的 code 會被執行 ,在return中間執行。

try 中的 return 語句調用的函數先於 finally 中調用的函數執行,也就是說 return 語句先執行,finally 語句後執行,但 return 並不是讓函數馬上返回,而是 return 語句執行後,將把返回結果放置進函數棧中,此時函數並不是馬上返回,它要執行 finally 語句後才真正開始返回!但此時會出現兩種情況:

①、如果finally中也有return,則會直接返回並終止程序,函數棧中的return不會被完成!;

②、如果finally中沒有return,則在執行完finally中的代碼之後,會將函數棧中的try中的return的內容返回並終止程序;

catch同try;
在這裏插入圖片描述

36.下面的程序代碼輸出的結果是多少?

在這裏插入圖片描述

返回的結果是 2。
我可以通過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中可以發現,try 中的 return 語句調用的函數先於 finally 中調用的函數執行,也就是說 return 語句先執行,finally 語句後執行,所以,返回的結果是 2。
Return 並不是讓函數馬上返回,而是 return 語句執行後,將把返回結果放置進函數棧中,此時函數並不是馬上返回,它要執行 finally 語句後才真正開始返回。
在講解答案時可以用下面的程序來幫助分析:
在這裏插入圖片描述
結論:finally 中的代碼比 return 和 break 語句後執行

37.final, finally, finalize 的區別。

final 用於聲明屬性、方法和類,分別表示屬性不可變(屬性一旦被分配內存空間就必須初始化並且以後不可變)、方法不可覆蓋(方法一旦定義必須有實現代碼並且子類裏不可被覆蓋)和類不可被繼承(不能再派生出新的子類);
finally 是異常處理的一部分,只能在try/catch語句中,並且附帶一個語句塊表示這段語句最終一定被執行;
finalize 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM 不保證此方法總被調用。

final屬性:
被final修飾的變量不可變。不可變有兩重含義:一是引用不可變,二是對象不可變。
final指的是引用不可變,即它只能指向初始時指向的那個對象。所以,被final修飾的變量必須被初始化。

final屬性初始化可以通過以下幾種方式:

  1. 在定義的時候初始化。

     	public class Test{
     	    public final int a=0;
     	    private Test(){}
     	}
    
  2. final成員變量可以在初始化塊中初始化,但不可在靜態初始化塊中初始化。

     	public class Test {
     	    public final String color;
        	{ color = "red"; }
     	}
    

    初始化塊會先於構造方法執行。

  3. 靜態final成員變量可以在靜態初始化塊中初始化,但不可在初始化塊中初始化。

     	public class Test{
     	    public static final int a;
     	    static{
     	        a=0;
     	    }
     	}
    
  4. 在類的構造器中初始化,但靜態final成員變量不可以在構造函數中初始化。

     	public class Test{
     	    public final int a;
     	    private Test(){
     	        a=0;
     	    }
     	}
    

    當a這個屬性被修飾爲final,而非static的時候,它屬於類的實例對象的資源,當類被加載進內存的時候這個屬性並沒有給其分配內存空間,而只是定義了一個變量a,只有當類被實例化的時候這個屬性才被分配內存空間,而實例化的時候同時執行了構造函數,所以屬性被初始化了,也就符合了當它被分配內存空間的時候就需要初始化。

final方法: 當一個方法聲明爲final時,該方法不允許任何子類重寫這個方法,但子類仍然可以使用這個方法。

final參數: 用來表示這個參數在這個函數內部不允許被修改

		public void testBaseType(final int i){
		    int n = i;
		    i = 9; //編譯報錯
		    System.out.println("i = "+i);
		    System.out.println("n = "+n);
		}

final 類當一個類被聲明爲final時,此類不能被繼承,所有方法都不能被重寫。但這並不表示final類的成員變量也是不可改變的,要想做到final類的成員變量不可改變,必須給成員變量怎加final修飾。

一個類不能既被聲明爲abstract,又被聲明爲final !!!

finally 作爲異常處理語句結構的一部分,它只能在try/catch語句中,並且附帶一個語句塊表示這段語句最終一定被執行,經常被用在需要釋放資源的情況下。

		Connection conn=null;
		Statement stmt=null;
		try{
		  conn=DriverManager.getConnection(url,uName,pwd);
		  stmt=conn.creatStatement();
		  stmt=executeUpdate(update);
		}catch(Exception e)finally{
		  if((stmt!=NULL)
		    stmt.close();
		  if(conn!=NULL)
		    conn.close();
		}

不管程序運行是否出現異常,finally中的代碼一定會執行,這樣能保證在任何情況下數據庫的連接資源都能夠被釋放。

finalize : finalize 是 Object 類的一個方法,在垃圾回收器執行時會調用被回收對象的finalize()方法,可以覆蓋此方法來實現對其他資源的回收。
一旦垃圾回收器準備好釋放對象佔用的空間,將首先調用其finalize()方法,並且在下一次垃圾回收動作發生時,纔會真正回收對象佔用的內存。

38.運行時異常與一般異常有何異同?

異常表示程序運行過程中可能出現的非正常狀態,
運行異常 表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。
一般異常 java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。

運行時異常,我們可以不處理。當出現這樣的異常時,總是由虛擬機接管。
比如:我們從來沒有人去處理過 NullPointerException 異常,它就是運行時異常,並且,這種異常還是最常見的異常之一。RuntimeException 體系包括錯誤的類型轉換、數組越界訪問和試圖訪問空指針等等。處理 RuntimeException 的原則是:假如出現 RuntimeException,那麼一定是程序員的錯誤,例如,可以通過檢查數組小標和數組邊界來避免越界訪問異常。

一般異常:定義方法時必須聲明所有可能會拋出的checked exception;
在調用這個方法時,必須捕獲它的checked exception,不然就得把它的exception傳遞下去;
checked exception是從java.lang.Exception類衍生出來的。
異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。
java 編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。
在這裏插入圖片描述

39.error 和 exception 有什麼區別?

error 表示恢復不是不可能但很困難的情況下的一種嚴重問題,比如說內存溢出,不可能指望程序能處理這樣的情況。
exception 表示 一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。

40.Java 中的異常處理機制的簡單原理和應用。

當 JAVA程序違反了 JAVA 的語義規則時,JAVA 虛擬機就會將發生的錯誤表示爲一個異常。
違反語義規則包括 2 種情況:
① JAVA 類 庫內置的語義檢查。
例如數組下標越界,會引發 IndexOutOfBoundsException;訪問 null 的對象時會引發 NullPointerException。
② JAVA允許程序員擴展這種語義檢查,程序員可以創建自己的異常,並自由選擇在何時用 throw 關鍵字引發異常。
所有的異常都是 java.lang.Thowable 的子類。

異常是指java程序運行時(非編譯)所發生的非正常情況或錯誤。
 
 與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等信息,可以用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。

Java對異常進行了分類,不同類型的異常分別用不同的Java類來表示,
  所有異常的根類爲 java.lang.Throwable,Throwable,下面又派生了兩個子類:Error和Exception,
  Error 表示應用程序本身無法克服和恢復的一種嚴重問題,程序只有死的份了,例如,說內存溢出和線程死鎖等系統問題。
  Exception 表示程序表示程序還能夠克服和恢復的一種嚴重問題,其中又分爲系統異常和普通異常,系統異常是軟件本身缺陷所導致的問題,也就是軟件開發人員考慮不周所導致的問題,軟件使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException)、空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是用戶能夠克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常後,程序不應該死掉。

java爲系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try···catch處理或用throws聲明繼續拋給上層調用方法處理,所以 普通異常也稱爲 checked異常 ,而系統異常可以處理也可以不處理,所以,編譯器不強制用try…catch處理或用throws聲明,所以系統異常也稱爲unchecked異常。
  在這裏插入圖片描述

異常 說明
ArithmeticException 由於除數爲0引起的異常
StackOverflowError 堆棧溢出異常
ArrayStoreException 由於數組存儲空間不夠引起的異常
ClassCastException 當把一個對象歸爲某個類,但實際上此對象並不是由這個類創建的,也不是其子類創建的,則會引起異常
IllegalMonitorStateException 監控器狀態出錯引起的異常
NegativeArraySizeException 數組長度是負數,則產生異常
NullPointerException 程序試圖訪問一個空的數組中的元素或訪問空的對象中的方法或變量時產生異常
OutofMemoryException 用new語句創建對象時,如系統無法爲其分配內存空 間則產生異常
SecurityException 由於訪問了不應訪問的指針,使安全性出問題而引起異常
IndexOutOfBoundsExcention 由於數組下標越界或字符串訪問越界引起異常
IOException 由於文件未找到、未打開或者I/O操作不能進行而引起異常
ClassNotFoundException 未找到指定名字的類或接口引起異常
CloneNotSupportedException 程序中的一個對象引用Object類的clone方法,但 此對象並沒有連接Cloneable接口,從而引起異常
InterruptedException 當一個線程處於等待狀態時,另一個線程中斷此線程,從而引起異常
NoSuchMethodException 所調用的方法未找到,引起異常
Illega1AccessExcePtion 試圖訪問一個非public方法
StringIndexOutOfBoundsException 訪問字符串序號越界,引起異常
ArrayIdexOutOfBoundsException 訪問數組元素下標越界,引起異常
NumberFormatException 字符的UTF代碼數據格式有錯引起異常
IllegalThreadException 線程調用某個方法而所處狀態不適當,引起異常
FileNotFoundException 未找到指定文件引起異常
EOFException 未完成輸入操作即遇文件結束引起異常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章