
內部類和靜態內部類的區別
內部類:
1、內部類中的變量和方法不能聲明為靜態的。
2、內部類實例化:B是A的內部類,實例化B:A.B b = new A().new B()。
3、內部類可以引用外部類的靜態或者非靜態屬性及方法。
靜態內部類:
1、靜態內部類屬性和方法可以聲明為靜態的或者非靜態的。
2、實例化靜態內部類:B是A的靜態內部類,A.B b = new A.B()。
3、靜態內部類只能引用外部類的靜態的屬性及方法。
inner classes——內部類
static nested classes——靜態嵌套類
其實人家不叫靜態內部類,只是叫習慣了,從字面就很容易理解了。
內部類依靠外部類的存在為前提,而靜態嵌套類則可以完全獨立,明白了這點就很好理解了。
非靜態內部類中的變量和方法不能聲明為靜態的原因
靜態類型的屬性和方法,在類加載的時候就會存在于內存中。使用某個類的靜態屬性和方法,那么這個類必須要加載到虛擬機中。但是非靜態內部類并不隨外部類一起加載,只有在實例化外部類之后才會加載。
我們設想一個場景:在外部類并沒有實例化,內部類還沒有加載的時候如果調用內部類的靜態成員或方法,內部類還沒有加載,卻試圖在內存中創建該內部類的靜態成員,就會產生沖突。所以非靜態內部類不能有靜態成員變量或靜態方法。
String,StringBuilder,StringBuffer的區別
- String 字符串常量
- StringBuffer 字符串變量(線程安全)
- StringBuilder 字符串變量(非線程安全)
性能上通常StringBuilder > StringBuffer > String。
String是不可變對象,每次對String類型進行改變的時候都等同于生成了一個新的String對象,然后將指針指向新的String對象,所以性能最差,對于要經常改變內容的字符串不用String。
StringBuffer是字符串變量,對它操作時,并不會生成新的對象,而是直接對該對象進行更改,所以性能較好。
StringBuilder和StringBuffer一樣,是字符串變量,但是他不帶有synchronized關鍵字,不保證線程安全,所以性能最好。在單線程的情況下,建議使用StringBuilder。
總體來說:
- String:適用于少量的字符串操作的情況。
- StringBuilder:適用于單線程下在字符緩沖區進行大量操作的情況。
- StringBuffer:適用多線程下在字符緩沖區進行大量操作的情況。
來一些問題:
下面這段代碼的輸出結果是什么?
String a = "helloworld";String b = "hello" + "world";System.out.println((a == b));
輸出結果為:True。
原因是String對字符串的直接相加,會在編譯期進行優化。即hello+world在編譯時期,被優化為helloworld,所以在運行時期,他們指向了同一個對象。我們也可以推理,對于直接字符串的相加,String不一定比其余兩個慢。
下面這段代碼的輸出結果是什么?
String a = "helloworld";String b = "hello"; String c = b + "world"; System.out.println((a == c));
輸出結果為:False。
原因是c并非兩個字符串直接相加,包含了一個字符串引用,這時不會做編譯期的優化。所以a、c最終生成了兩個對象,這時他的效率低。
集合和數組之間的相互轉換
數組變集合:
通常我們會回答的是以下代碼:
List list = Arrays.asList(array);
但這并不是很好的答案,此時組合成的list是Arrays里面的一個靜態內部類,該類并未實現add、remove方法,因此在使用時存在問題。
可以這樣:
String array[]= {"hello