Java基礎(chǔ)八股文(背誦版)
秋招也進行了快兩個月了,大家上岸了嗎?
二哥整理了一份 Java 基礎(chǔ)篇的八股文,大家在面試前可以背一遍,一定能“吊打”面試官。

Java 語言具有哪些特點?
Java 為純面向?qū)ο蟮恼Z言。它能夠直接反應現(xiàn)實生活中的對象。 具有平臺無關(guān)性。Java 利用 Java 虛擬機運行字節(jié)碼,無論是在 Windows、Linux 還是 MacOS 等其它平臺對 Java 程序進行編譯,編譯后的程序可在其它平臺運行。 Java 為解釋型語言,編譯器把 Java 代碼編譯成平臺無關(guān)的中間代碼,然后在 JVM 上解釋運行,具有很好的可移植性。 Java 提供了很多內(nèi)置類庫。如對多線程支持,對網(wǎng)絡通信支持,最重要的一點是提供了垃圾回收器。 Java 具有較好的安全性和健壯性。Java 提供了異常處理和垃圾回收機制,去除了 C++中難以理解的指針特性。
JDK 與 JRE 有什么區(qū)別?
JDK:Java 開發(fā)工具包(Java Development Kit),提供了 Java 的開發(fā)環(huán)境和運行環(huán)境。 JRE:Java 運行環(huán)境(Java Runtime Environment),提供了 Java 運行所需的環(huán)境。 JDK 包含了 JRE。如果只運行 Java 程序,安裝 JRE 即可。要編寫 Java 程序需安裝 JDK.
簡述 Java 基本數(shù)據(jù)類型
byte: 占用 1 個字節(jié),取值范圍-128 ~ 127 short: 占用 2 個字節(jié),取值范圍-2^15^ ~ 2^15^-1 int:占用 4 個字節(jié),取值范圍-2^31^ ~ 2^31^-1 long:占用 8 個字節(jié) float:占用 4 個字節(jié) double:占用 8 個字節(jié) char: 占用 2 個字節(jié) boolean:占用大小根據(jù)實現(xiàn)虛擬機不同有所差異
簡述自動裝箱拆箱
對于 Java 基本數(shù)據(jù)類型,均對應一個包裝類。
裝箱就是自動將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝器類型,如 int->Integer
拆箱就是自動將包裝器類型轉(zhuǎn)換為基本數(shù)據(jù)類型,如 Integer->int
簡述 Java 訪問修飾符
default: 默認訪問修飾符,在同一包內(nèi)可見 private: 在同一類內(nèi)可見,不能修飾類 protected : 對同一包內(nèi)的類和所有子類可見,不能修飾類 public: 對所有類可見
構(gòu)造方法、成員變量初始化以及靜態(tài)成員變量三者的初始化順序?
先后順序:靜態(tài)成員變量、成員變量、構(gòu)造方法。
詳細的先后順序:父類靜態(tài)變量、父類靜態(tài)代碼塊、子類靜態(tài)變量、子類靜態(tài)代碼塊、父類非靜態(tài)變量、父類非靜態(tài)代碼塊、父類構(gòu)造函數(shù)、子類非靜態(tài)變量、子類非靜態(tài)代碼塊、子類構(gòu)造函數(shù)。
Java 代碼塊執(zhí)行順序
父類靜態(tài)代碼塊(只執(zhí)行一次) 子類靜態(tài)代碼塊(只執(zhí)行一次) 父類構(gòu)造代碼塊 父類構(gòu)造函數(shù) 子類構(gòu)造代碼塊 子類構(gòu)造函數(shù) 普通代碼塊
面向?qū)ο蟮娜筇匦裕?span style="display: none;">
繼承:對象的一個新類可以從現(xiàn)有的類中派生,派生類可以從它的基類那繼承方法和實例變量,且派生類可以修改或新增新的方法使之更適合特殊的需求。
封裝:將客觀事物抽象成類,每個類可以把自身數(shù)據(jù)和方法只讓可信的類或?qū)ο蟛僮鳎瑢Σ豢尚诺倪M行信息隱藏。
多態(tài):允許不同類的對象對同一消息作出響應。不同對象調(diào)用相同方法即使參數(shù)也相同,最終表現(xiàn)行為是不一樣的。
為什么 Java 語言不支持多重繼承?
為了程序的結(jié)構(gòu)能夠更加清晰從而便于維護。假設(shè) Java 語言支持多重繼承,類 C 繼承自類 A 和類 B,如果類 A 和 B 都有自定義的成員方法 f(),那么當代碼中調(diào)用類 C 的 f() 會產(chǎn)生二義性。
Java 語言通過實現(xiàn)多個接口間接支持多重繼承,接口由于只包含方法定義,不能有方法的實現(xiàn),類 C 繼承接口 A 與接口 B 時即使它們都有方法f(),也不能直接調(diào)用方法,需實現(xiàn)具體的f()方法才能調(diào)用,不會產(chǎn)生二義性。
多重繼承會使類型轉(zhuǎn)換、構(gòu)造方法的調(diào)用順序變得復雜,會影響到性能。
簡述 Java 的多態(tài)
Java 多態(tài)可以分為編譯時多態(tài)和運行時多態(tài)。
編譯時多態(tài)主要指方法的重載,即通過參數(shù)列表的不同來區(qū)分不同的方法。
運行時多態(tài)主要指繼承父類和實現(xiàn)接口時,可使用父類引用指向子類對象。
運行時多態(tài)的實現(xiàn):主要依靠方法表,方法表中最先存放的是 Object 類的方法,接下來是該類的父類的方法,最后是該類本身的方法。如果子類改寫了父類的方法,那么子類和父類的那些同名方法共享一個方法表項,都被認作是父類的方法。因此可以實現(xiàn)運行時多態(tài)。
Java 提供的多態(tài)機制?
Java 提供了兩種用于多態(tài)的機制,分別是重載與覆蓋。
重載:重載是指同一個類中有多個同名的方法,但這些方法有不同的參數(shù),在編譯期間就可以確定調(diào)用哪個方法。
覆蓋:覆蓋是指派生類重寫基類的方法,使用基類指向其子類的實例對象,或接口的引用變量指向其實現(xiàn)類的實例對象,在程序調(diào)用的運行期根據(jù)引用變量所指的具體實例對象調(diào)用正在運行的那個對象的方法,即需要到運行期才能確定調(diào)用哪個方法。
重載與覆蓋的區(qū)別?
覆蓋是父類與子類之間的關(guān)系,是垂直關(guān)系;重載是同一類中方法之間的關(guān)系,是水平關(guān)系。 覆蓋只能由一個方法或一對方法產(chǎn)生關(guān)系;重載是多個方法之間的關(guān)系。 覆蓋要求參數(shù)列表相同;重載要求參數(shù)列表不同。 覆蓋中,調(diào)用方法體是根據(jù)對象的類型來決定的,而重載是根據(jù)調(diào)用時實參表與形參表來對應選擇方法體。 重載方法可以改變返回值的類型,覆蓋方法不能改變返回值的類型。
接口和抽象類的相同點和不同點?
相同點:
都不能被實例化。 接口的實現(xiàn)類或抽象類的子類需實現(xiàn)接口或抽象類中相應的方法才能被實例化。
不同點:
接口只能有方法定義,不能有方法的實現(xiàn),而抽象類可以有方法的定義與實現(xiàn)。
實現(xiàn)接口的關(guān)鍵字為 implements,繼承抽象類的關(guān)鍵字為 extends。一個類可以實現(xiàn)多個接口,只能繼承一個抽象類。
當子類和父類之間存在邏輯上的層次結(jié)構(gòu),推薦使用抽象類,有利于功能的累積。當功能不需要,希望支持差別較大的兩個或更多對象間的特定交互行為,推薦使用接口。使用接口能降低軟件系統(tǒng)的耦合度,便于日后維護或添加刪除方法。
簡述抽象類與接口的區(qū)別
抽象類:體現(xiàn)的是 is-a 的關(guān)系,如對于 man is a person,就可以將 person 定義為抽象類。
接口:體現(xiàn)的是 can 的關(guān)系。是作為模板實現(xiàn)的。如設(shè)置接口 fly,plane 類和 bird 類均可實現(xiàn)該接口。
一個類只能繼承一個抽象類,但可以實現(xiàn)多個接口。
簡述內(nèi)部類及其作用
成員內(nèi)部類:作為成員對象的內(nèi)部類。可以訪問 private 及以上外部類的屬性和方法。外部類想要訪問內(nèi)部類屬性或方法時,必須要創(chuàng)建一個內(nèi)部類對象,然后通過該對象訪問內(nèi)部類的屬性或方法。外部類也可訪問 private 修飾的內(nèi)部類屬性。 局部內(nèi)部類:存在于方法中的內(nèi)部類。訪問權(quán)限類似局部變量,只能訪問外部類的 final 變量。 匿名內(nèi)部類:只能使用一次,沒有類名,只能訪問外部類的 final 變量。 靜態(tài)內(nèi)部類:類似類的靜態(tài)成員變量。
Java 語言中關(guān)鍵字 static 的作用是什么?
static 的主要作用有兩個:
為某種特定數(shù)據(jù)類型或?qū)ο蠓峙渑c創(chuàng)建對象個數(shù)無關(guān)的單一的存儲空間。 使得某個方法或?qū)傩耘c類而不是對象關(guān)聯(lián)在一起,即在不創(chuàng)建對象的情況下可通過類直接調(diào)用方法或使用類的屬性。
具體而言 static 又可分為 4 種使用方式:
修飾成員變量。用 static 關(guān)鍵字修飾的靜態(tài)變量在內(nèi)存中只有一個副本。只要靜態(tài)變量所在的類被加載,這個靜態(tài)變量就會被分配空間,可以使用“類.靜態(tài)變量”和“對象.靜態(tài)變量”的方法使用。 修飾成員方法。static 修飾的方法無需創(chuàng)建對象就可以被調(diào)用。static 方法中不能使用 this 和 super 關(guān)鍵字,不能調(diào)用非 static 方法,只能訪問所屬類的靜態(tài)成員變量和靜態(tài)成員方法。 修飾代碼塊。JVM 在加載類的時候會執(zhí)行 static 代碼塊。static 代碼塊常用于初始化靜態(tài)變量。static 代碼塊只會被執(zhí)行一次。 修飾內(nèi)部類。static 內(nèi)部類可以不依賴外部類實例對象而被實例化。靜態(tài)內(nèi)部類不能與外部類有相同的名字,不能訪問普通成員變量,只能訪問外部類中的靜態(tài)成員和靜態(tài)成員方法。
為什么要把 String 設(shè)計為不可變?
節(jié)省空間:字符串常量存儲在 JVM 的字符串池中可以被用戶共享。 提高效率:String 可以被不同線程共享,是線程安全的。在涉及多線程操作中不需要同步操作。 安全:String 常被用于用戶名、密碼、文件名等使用,由于其不可變,可避免黑客行為對其惡意修改。
簡述 String/StringBuffer 與 StringBuilder
String 類采用利用 final 修飾的字符數(shù)組進行字符串保存,因此不可變。如果對 String 類型對象修改,需要新建對象,將老字符和新增加的字符一并存進去。
StringBuilder,采用無 final 修飾的字符數(shù)組進行保存,因此可變。但線程不安全。
StringBuffer,采用無 final 修飾的字符數(shù)組進行保存,可理解為實現(xiàn)線程安全的 StringBuilder。
判等運算符==與 equals 的區(qū)別?
== 比較的是引用,equals 比較的是內(nèi)容。
如果變量是基礎(chǔ)數(shù)據(jù)類型,== 用于比較其對應值是否相等。如果變量指向的是對象,== 用于比較兩個對象是否指向同一塊存儲空間。
equals 是 Object 類提供的方法之一,每個 Java 類都繼承自 Object 類,所以每個對象都具有 equals 這個方法。Object 類中定義的 equals 方法內(nèi)部是直接調(diào)用 == 比較對象的。但通過覆蓋的方法可以讓它不是比較引用而是比較數(shù)據(jù)內(nèi)容。
簡述 Object 類常用方法
hashCode:通過對象計算出的散列碼。用于 map 型或 equals 方法。需要保證同一個對象多次調(diào)用該方法,總返回相同的整型值。 equals:判斷兩個對象是否一致。需保證 equals 方法相同對應的對象 hashCode 也相同。 toString: 用字符串表示該對象 clone:深拷貝一個對象
Java 中一維數(shù)組和二維數(shù)組的聲明方式?
一維數(shù)組的聲明方式:
type arrayName[]
type[] arrayName
二維數(shù)組的聲明方式:
type arrayName[][]
type[][] arrayName
type[] arrayName[]
其中 type 為基本數(shù)據(jù)類型或類,arrayName 為數(shù)組名字
簡述 Java 異常的分類
Java 異常分為 Error(程序無法處理的錯誤),和 Exception(程序本身可以處理的異常)。這兩個類均繼承 Throwable。
Error 常見的有 StackOverFlowError、OutOfMemoryError 等等。
Exception 可分為運行時異常和非運行時異常。對于運行時異常,可以利用 try catch 的方式進行處理,也可以不處理。對于非運行時異常,必須處理,不處理的話程序無法通過編譯。
簡述 throw 與 throws 的區(qū)別
throw 一般是用在方法體的內(nèi)部,由開發(fā)者定義當程序語句出現(xiàn)問題后主動拋出一個異常。
throws 一般用于方法聲明上,代表該方法可能會拋出的異常列表。
出現(xiàn)在 Java 程序中的 finally 代碼塊是否一定會執(zhí)行?
當遇到下面情況不會執(zhí)行。
當程序在進入 try 語句塊之前就出現(xiàn)異常時會直接結(jié)束。 當程序在 try 塊中強制退出時,如使用 System.exit(0),也不會執(zhí)行 finally 塊中的代碼。
其它情況下,在 try/catch/finally 語句執(zhí)行的時候,try 塊先執(zhí)行,當有異常發(fā)生,catch 和 finally 進行處理后程序就結(jié)束了,當沒有異常發(fā)生,在執(zhí)行完 finally 中的代碼后,后面代碼會繼續(xù)執(zhí)行。值得注意的是,當 try/catch 語句塊中有 return 時,finally 語句塊中的代碼會在 return 之前執(zhí)行。如果 try/catch/finally 塊中都有 return 語句,finally 塊中的 return 語句會覆蓋 try/catch 模塊中的 return 語句。
final、finally 和 finalize 的區(qū)別是什么?
final 用于聲明屬性、方法和類,分別表示屬性不可變、方法不可覆蓋、類不可繼承。 finally 作為異常處理的一部分,只能在 try/catch 語句中使用,finally 附帶一個語句塊用來表示這個語句最終一定被執(zhí)行,經(jīng)常被用在需要釋放資源的情況下。 finalize 是 Object 類的一個方法,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的 finalize()方法。當垃圾回收器準備好釋放對象占用空間時,首先會調(diào)用 finalize()方法,并在下一次垃圾回收動作發(fā)生時真正回收對象占用的內(nèi)存。
簡述泛型
泛型,即“參數(shù)化類型”,解決不確定對象具體類型的問題。在編譯階段有效。在泛型使用過程中,操作的數(shù)據(jù)類型被指定為一個參數(shù),這種參數(shù)類型在類中稱為泛型類、接口中稱為泛型接口和方法中稱為泛型方法。
簡述泛型擦除
Java 編譯器生成的字節(jié)碼是不包涵泛型信息的,泛型類型信息將在編譯處理是被擦除,這個過程被稱為泛型擦除。
簡述注解
Java 注解用于為 Java 代碼提供元數(shù)據(jù)。作為元數(shù)據(jù),注解不直接影響你的代碼執(zhí)行,但也有一些類型的注解實際上可以用于這一目的。
其可以用于提供信息給編譯器,在編譯階段時給軟件提供信息進行相關(guān)的處理,在運行時處理寫相應代碼,做對應操作。
簡述元注解
元注解可以理解為注解的注解,即在注解中使用,實現(xiàn)想要的功能。其具體分為:
@Retention: 表示注解存在階段是保留在源碼,還是在字節(jié)碼(類加載)或者運行期(JVM 中運行)。 @Target:表示注解作用的范圍。 @Documented:將注解中的元素包含到 Javadoc 中去。 @Inherited:一個被@Inherited 注解了的注解修飾了一個父類,如果他的子類沒有被其他注解修飾,則它的子類也繼承了父類的注解。 @Repeatable:被這個元注解修飾的注解可以同時作用一個對象多次,但是每次作用注解又可以代表不同的含義。
簡述 Java 中 Class 對象
java 中對象可以分為實例對象和 Class 對象,每一個類都有一個 Class 對象,其包含了與該類有關(guān)的信息。
獲取 Class 對象的方法:
Class.forName(“類的全限定名”)
實例對象.getClass()
類名.class
Java 反射機制是什么?
Java 反射機制是指在程序的運行過程中可以構(gòu)造任意一個類的對象、獲取任意一個類的成員變量和成員方法、獲取任意一個對象所屬的類信息、調(diào)用任意一個對象的屬性和方法。反射機制使得 Java 具有動態(tài)獲取程序信息和動態(tài)調(diào)用對象方法的能力。可以通過以下類調(diào)用反射 API。
Class 類:可獲得類屬性方法 Field 類:獲得類的成員變量 Method 類:獲取類的方法信息 Construct 類:獲取類的構(gòu)造方法等信息
序列化是什么?
序列化是一種將對象轉(zhuǎn)換成字節(jié)序列的過程,用于解決在對對象流進行讀寫操作時所引發(fā)的問題。序列化可以將對象的狀態(tài)寫在流里進行網(wǎng)絡傳輸,或者保存到文件、數(shù)據(jù)庫等系統(tǒng)里,并在需要的時候把該流讀取出來重新構(gòu)造成一個相同的對象。
簡述 Java 序列化與反序列化的實現(xiàn)
序列化:將 java 對象轉(zhuǎn)化為字節(jié)序列,由此可以通過網(wǎng)絡對象進行傳輸。
反序列化:將字節(jié)序列轉(zhuǎn)化為 java 對象。
具體實現(xiàn):實現(xiàn) Serializable 接口,或?qū)崿F(xiàn) Externalizable 接口中的 writeExternal()與 readExternal()方法。
簡述 Java 的 List
List 是一個有序隊列,在 Java 中有兩種實現(xiàn)方式:
ArrayList 使用數(shù)組實現(xiàn),是容量可變的非線程安全列表,隨機訪問快,集合擴容時會創(chuàng)建更大的數(shù)組,把原有數(shù)組復制到新數(shù)組。
LinkedList 本質(zhì)是雙向鏈表,與 ArrayList 相比插入和刪除速度更快,但隨機訪問元素很慢。
Java 中線程安全的基本數(shù)據(jù)結(jié)構(gòu)有哪些
HashTable: 哈希表的線程安全版,效率低 ConcurrentHashMap:哈希表的線程安全版,效率高,用于替代 HashTable Vector:線程安全版 Arraylist Stack:線程安全版棧 BlockingQueue 及其子類:線程安全版隊列
簡述 Java 的 Set
Set 即集合,該數(shù)據(jù)結(jié)構(gòu)不允許元素重復且無序。Java 對 Set 有三種實現(xiàn)方式:
HashSet 通過 HashMap 實現(xiàn),HashMap 的 Key 即 HashSet 存儲的元素,Value 系統(tǒng)自定義一個名為 PRESENT 的 Object 類型常量。判斷元素是否相同時,先比較 hashCode,相同后再利用 equals 比較,查詢 O(1)
LinkedHashSet 繼承自 HashSet,通過 LinkedHashMap 實現(xiàn),使用雙向鏈表維護元素插入順序。
TreeSet 通過 TreeMap 實現(xiàn)的,底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹,添加元素到集合時按照比較規(guī)則將其插入合適的位置,保證插入后的集合仍然有序。查詢 O(logn)
簡述 Java 的 HashMap
JDK8 之前底層實現(xiàn)是數(shù)組 + 鏈表,JDK8 改為數(shù)組 + 鏈表/紅黑樹。主要成員變量包括存儲數(shù)據(jù)的 table 數(shù)組、元素數(shù)量 size、加載因子 loadFactor。HashMap 中數(shù)據(jù)以鍵值對的形式存在,鍵對應的 hash 值用來計算數(shù)組下標,如果兩個元素 key 的 hash 值一樣,就會發(fā)生哈希沖突,被放到同一個鏈表上。
table 數(shù)組記錄 HashMap 的數(shù)據(jù),每個下標對應一條鏈表,所有哈希沖突的數(shù)據(jù)都會被存放到同一條鏈表,Node/Entry 節(jié)點包含四個成員變量:key、value、next 指針和 hash 值。在 JDK8 后鏈表超過 8 會轉(zhuǎn)化為紅黑樹。
若當前數(shù)據(jù)/總數(shù)據(jù)容量>負載因子,Hashmap 將執(zhí)行擴容操作。默認初始化容量為 16,擴容容量必須是 2 的冪次方、最大容量為 1<< 30 、默認加載因子為 0.75。
為何 HashMap 線程不安全
在 JDK1.7 中,HashMap 采用頭插法插入元素,因此并發(fā)情況下會導致環(huán)形鏈表,產(chǎn)生死循環(huán)。
雖然 JDK1.8 采用了尾插法解決了這個問題,但是并發(fā)下的 put 操作也會使前一個 key 被后一個 key 覆蓋。
由于 HashMap 有擴容機制存在,也存在 A 線程進行擴容后,B 線程執(zhí)行 get 方法出現(xiàn)失誤的情況。
簡述 Java 的 TreeMap
TreeMap 是底層利用紅黑樹實現(xiàn)的 Map 結(jié)構(gòu),底層實現(xiàn)是一棵平衡的排序二叉樹,由于紅黑樹的插入、刪除、遍歷時間復雜度都為 O(logN),所以性能上低于哈希表。但是哈希表無法提供鍵值對的有序輸出,紅黑樹可以按照鍵的值的大小有序輸出。
ArrayList、Vector 和 LinkedList 有什么共同點與區(qū)別?
ArrayList、Vector 和 LinkedList 都是可伸縮的數(shù)組,即可以動態(tài)改變長度的數(shù)組。 ArrayList 和 Vector 都是基于存儲元素的 Object[] array 來實現(xiàn)的,它們會在內(nèi)存中開辟一塊連續(xù)的空間來存儲,支持下標、索引訪問。但在涉及插入元素時可能需要移動容器中的元素,插入效率較低。當存儲元素超過容器的初始化容量大小,ArrayList 與 Vector 均會進行擴容。 Vector 是線程安全的,其大部分方法是直接或間接同步的。ArrayList 不是線程安全的,其方法不具有同步性質(zhì)。LinkedList 也不是線程安全的。 LinkedList 采用雙向列表實現(xiàn),對數(shù)據(jù)索引需要從頭開始遍歷,因此隨機訪問效率較低,但在插入元素的時候不需要對數(shù)據(jù)進行移動,插入效率較高。
HashMap 和 Hashtable 有什么區(qū)別?
HashMap 是 Hashtable 的輕量級實現(xiàn),HashMap 允許 key 和 value 為 null,但最多允許一條記錄的 key 為 null.而 HashTable 不允許。 HashTable 中的方法是線程安全的,而 HashMap 不是。在多線程訪問 HashMap 需要提供額外的同步機制。 Hashtable 使用 Enumeration 進行遍歷,HashMap 使用 Iterator 進行遍歷。
如何決定使用 HashMap 還是 TreeMap?
如果對 Map 進行插入、刪除或定位一個元素的操作更頻繁,HashMap 是更好的選擇。如果需要對 key 集合進行有序的遍歷,TreeMap 是更好的選擇。
HashSet 中,equals 與 hashCode 之間的關(guān)系?
equals 和 hashCode 這兩個方法都是從 object 類中繼承過來的,equals 主要用于判斷對象的內(nèi)存地址引用是否是同一個地址;hashCode 根據(jù)定義的哈希規(guī)則將對象的內(nèi)存地址轉(zhuǎn)換為一個哈希碼。HashSet 中存儲的元素是不能重復的,主要通過 hashCode 與 equals 兩個方法來判斷存儲的對象是否相同:
如果兩個對象的 hashCode 值不同,說明兩個對象不相同。 如果兩個對象的 hashCode 值相同,接著會調(diào)用對象的 equals 方法,如果 equlas 方法的返回結(jié)果為 true,那么說明兩個對象相同,否則不相同。
fail-fast 和 fail-safe 迭代器的區(qū)別是什么?
fail-fast 直接在容器上進行,在遍歷過程中,一旦發(fā)現(xiàn)容器中的數(shù)據(jù)被修改,就會立刻拋出 ConcurrentModificationException 異常從而導致遍歷失敗。常見的使用 fail-fast 方式的容器有 HashMap 和 ArrayList 等。 fail-safe 這種遍歷基于容器的一個克隆。因此對容器中的內(nèi)容修改不影響遍歷。常見的使用 fail-safe 方式遍歷的容器有 ConcurrentHashMap 和 CopyOnWriteArrayList。
Collection 和 Collections 有什么區(qū)別?
Collection 是一個集合接口,它提供了對集合對象進行基本操作的通用接口方法,所有集合都是它的子類,比如 List、Set 等。 Collections 是一個包裝類,包含了很多靜態(tài)方法、不能被實例化,而是作為工具類使用,比如提供的排序方法:Collections.sort(list);提供的反轉(zhuǎn)方法:Collections.reverse(list)。
我是二哥呀,希望能幫助大家闖面成功,秋招成功上岸。點贊 + 在看只要來一個,我這張帥臉就泛起了笑容。
送大家一句我最喜歡的短詩:沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟。
推薦閱讀:
