Java基礎知識點(一)


前言:本篇隨筆,主要記錄Java的基礎知識點,不管是用於項目或者面試中,筆者認為都非常有用,所以將持續更新......


1.Java的訪問權限

Java中有四種訪問權限:默認訪問權限、public、private、protected

這四種訪問權限中,只有默認訪問權限和public才能修飾類(這里所說的類為外部類,對於內部類,四種權限都可以進行修飾),對於字段和方法,四種權限都可以進行修飾。

默認訪問權限(字段或類前不加任何修飾符):用默認訪問權限進行修飾,只能在同包中進行訪問。

public:任何地方都可見(方法、字段、包)。

private:用private修飾的方法或字段只能在本類中進行訪問。

protected:用protected修飾類的方法或字段,在同包中可以被訪問,對於不同的包,只能通過繼承對其方法或字段進行訪問。

具體細節參考:http://www.cnblogs.com/dolphin0520/p/3734915.html,這篇博文中有詳細解釋。

2.Java中"=="與equals()方法的區別

1)對於8種基礎數據類型,"=="比較值是否相等。

     如果作用於引用類型的變量,則比較的是所指向對象的地址。

注:equals方法是不能作用與基礎類型數據的,只能作用與引用類型數據。

2)對於equals方法:

     如果equals方法未被重寫,則比較的是引用類型變量所指向的對象地址。

     對於String、Integer、Date等復寫了equals方法的對象,則比較的是對象內容。

注:重寫了equals方法的對象:String、8種基礎類型的包裝類、Date等,這里並未列舉完。

具體參考:

https://www.cnblogs.com/wangjiangwu/p/5770634.html

http://www.cnblogs.com/dolphin0520/p/3592500.html

3.在重寫equals方法,為什么有必要同時重寫hashCode方法

具體參考:http://www.cnblogs.com/happyPawpaw/p/3744971.html

重寫hashCode方法,主要是為了維護hashCode方法的協定,該協定規定,相等的對象必須有相同的哈希碼。

4.String、StringBuffer和StringBuilder

這三個對象在平時使用和面試中出現的頻次非常的高。

要點:

String是不可變對象。這點可以從String的源碼中看到。String源碼分析傳送門:String源碼分析

StringBuffer是線程安全的。從源碼中可以看到函數上使用了synchronized進行修飾。

StringBuilder是非線程安全的。

特別指出String中的intern()方法,該方法從源代碼中可以看出為本地方法(並且與jdk的版本有關系,以jdk1.6為分界點),並且在面試題中極其容易出現,具體區別為:

在jdk1.6以前:

調用intern方法時,首先會去常量池中查找是否存在與當前String值相同的值,

如果存在的話,則直接返回常量池中這個String值的引用;如果不存在的話,則會將原先堆中的該字符串拷貝一份到常量池中,並返回該字符串在常量池中的引用

jdk1.7:

調用intern方法時,首先會去常量池中查找是否存在與當前String值相同的值,

如果存在的話,則直接返回常量池中這個String值的引用;如果不存在的話,則只會將原先堆中該字符串的引用放置在常量池中注意:不會拷貝這個字符串到常量池中

注意:由於jdk1.7對字符串常量池做出了調整,從PermGen區中調整到了堆中,所以在使用intern方法時,並不會進行字符串的拷貝。

下面給出相應例子,更清楚的說明intern方法。

1 String str1 = "abcd";
2 String str2 = new String("ab") + new String("cd");
3 System.out.println(str2.intern() == str1);
4 System.out.println(str2 == str1);

jdk1.6中輸出:

false

false

jdk1.7中輸出:

true

false

解釋:

在jdk1.6中字符串常量池和堆區被完全區分開,所以會返回兩個false。

在jdk1.7中

在執行第1行String str1=“abcd”時,會將“abcd”直接存儲到常量池中。

在執行第2行String str2=new String("ab")+new String("cd")時,在類加載的時候,會在常量池中存儲"ab"和"cd"。

當執行str2.intern()方法時,發現常量池中存在"abcd"(第一行代碼的結果),所以返回此時"abcd"字符串的引用,即str1所以str2.intern()==str1為true,兩處的引用相同的。

第四行,str2==str1,兩個引用的地址明顯不同,str2指向堆,str1指向字符串常量池中,所以為false。

將上述代碼進行變形,形式如下:

1 String str2 = new String("ab") + new String("cd");
2 str2.intern();
3 String str1="abcd";
4 System.out.println(str2 == str1);

在jdk1.6中,同樣輸出false。

但是在jdk1.7中輸出true

解釋:

在執行第1行String str2=new String("ab")+new String("cd")時,在類加載的時候,會在常量池中存儲"ab"和"cd"。注意:這時常量池中是沒有"abcd"的。

在執行第2行str2.intern()方法時,發現常量池中沒有"abcd",於是將str2的引用放入常量池中,並不會進行拷貝

在執行第3行時,發現常量池中已經存在"abcd"的引用了,直接賦值給str1,所以最后的結果為true。

將上述代碼再次變形,將第2行與第3行互換位置。形式如下:

1 String str2 = new String("ab") + new String("cd");
2 String str1 = "abcd";
3 str2.intern();
4 System.out.println(str2 == str1);

在jdk1.6與jdk1.7中都是輸出false。

這個原理比較簡單了,str2與str1,明顯是兩個不同的引用,str2指向堆,str1指向字符串常量池,所以為false。

具體參考:

http://www.cnblogs.com/dolphin0520/p/3778589.html

http://blog.csdn.net/seu_calvin/article/details/52291082

http://blog.csdn.net/bigtree_3721/article/details/74907670

http://blog.csdn.net/hzw19920329/article/details/51262925

5.關於集合類

具體細節參考這篇博文:https://www.cnblogs.com/leeplogs/p/5891861.html,總結得非常詳細。

重點歸納:

List有序集合,可以包含重復元素。

Set無序(TreeSet有序,二叉樹排序),不能包含重復元素。

Map不能包含重復的鍵值,因為鍵值對,重復鍵會被覆蓋。

注:參考博文中說,所有集合類都實現了Iterator接口,但是Map集合是沒有實現該接口的

下面對常見集合的主要特點進行總結:

HashMap:

#1.非同步的,也就說是線程不安全,與Hashtable相反。

#2.無序,允許null鍵和null值(HashTable不允許鍵或值為null),不能包含重復的鍵,出現重復的鍵值時,在put操作時會進行覆蓋。

#3.在HashMap中擴容時,是非常耗性能的;HashMap默認數據容量大小為16,loadFactor(擴容因子默認值為0.75),當元素個數大於16*0.75=12時,就會進行擴容,擴大一倍:2*16=32。

#5.HashMap線程不安全體現傳送門:HashMap線程不安全的體現

#6.HashMap源碼分析傳送門:HashMap源碼分析——基於jdk1.7

Hashtable:

#1.Hashtable是線程安全的。

#2.無序,不允許null鍵或null值。

#3.繼承Dictionary接口,也實現了Map接口。

#4.Hashtable擴容時,擴大的容量為:2n*+1,擴大一倍並加1。Hashtable默認數據容量為11

#5.Hashtable源碼分析傳送門:Hashtable源碼分析

ConcurrentHashMap的實現原理,參考:

https://my.oschina.net/hosee/blog/639352

https://www.cnblogs.com/chengxiao/p/6842045.html

https://my.oschina.net/hosee/blog/675884

ConcurrentHashMap:

1)線程安全的,主要使用鎖分離技術(分段鎖)。

2)初始容量大小為16,默認並發度也為16。

3)由於使用分段鎖技術,只有對於同一段數據操作,才會考慮線程同步。

4)無序,不允許null鍵或null值。(源碼put函數可以得出該結論)


by Shawn Chen,2018.3.19日,下午。


相關內容

Java基礎知識點(二) 

Java基礎知識點(三)

Java基礎知識點(四)


免責聲明!

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



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