我之前曾在Java Collections類的實用程序上進行過博客撰寫,并且特別地在使用Usings Collections Methods上的博客emptyList(),emptyMap()和emptySet()上進行了博客撰寫。 在本文中,我研究了使用Collections
類的相關字段訪問空集合與使用Collections
類的相關方法訪問空集合之間有時細微但重要的區別。
以下代碼演示了直接訪問Collections
的字段以指定空集合。
將集合的字段用于空集合
/*** Instantiate my collections with empty versions using Collections fields.* This will result in javac compiler warnings stating 'warning: [unchecked]* unchecked conversion'.*/public void instantiateWithEmptyCollectionsFieldsAssigment(){this.stringsList = Collections.EMPTY_LIST;this.stringsSet = Collections.EMPTY_SET;this.stringsMap = Collections.EMPTY_MAP; }
上面的代碼使用javac進行編譯 ,但是導致出現警告消息(在這種情況下,該消息由NetBeans和Ant生成):
-do-compile:[javac] Compiling 1 source file to C:\java\examples\typesafeEmptyCollections\build\classes[javac] Note: C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java uses unchecked or unsafe operations.[javac] Note: Recompile with -Xlint:unchecked for details.
將-Xlint:unchecked指定為 javac
的參數(在這種情況下,通過NetBeans project.properties
文件中的javac.compilerargs=-Xlint:unchecked
)有助于獲取更具體的警告消息,用于前面列出的代碼:
[javac] Compiling 1 source file to C:\java\examples\typesafeEmptyCollections\build\classes[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:27: warning: [unchecked] unchecked conversion[javac] this.stringsList = Collections.EMPTY_LIST;[javac] ^[javac] required: List<String>[javac] found: List[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:28: warning: [unchecked] unchecked conversion[javac] this.stringsSet = Collections.EMPTY_SET;[javac] ^[javac] required: Set<String>[javac] found: Set[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:29: warning: [unchecked] unchecked conversion[javac] this.stringsMap = Collections.EMPTY_MAP; [javac] ^[javac] required: Map<String,String>[javac] found: Map
如果在其選項中選中了適當的提示框,則NetBeans還將顯示這些警告。 接下來的三個圖像演示如何確保設置適當的提示以查看NetBeans中的這些警告,并提供一個示例,說明NetBeans如何將上面顯示的代碼與警告一起呈現。
幸運的是,很容易利用Collections
類的實用程序并以類型安全的方式訪問空集合,而不會導致這些javac
警告和相應的NetBeans提示。 這種方法是使用Collections
的方法而不是其字段 。 下一個簡單的代碼清單對此進行了演示。
對空集合使用集合的方法
/*** Instantiate my collections with empty versions using Collections methods.* This will avoid the javac compiler warnings alluding to 'unchecked conversion'.*/public void instantiateWithEmptyCollectionsMethodsTypeInferred(){this.stringsList = Collections.emptyList();this.stringsSet = Collections.emptySet();this.stringsMap = Collections.emptyMap();}
上面的代碼將編譯而不會發出警告,并且也不會顯示任何NetBeans提示。 Collections
類的每個字段的Javadoc文檔都沒有解決為什么這些字段會出現這些警告的問題,但是每個類似方法的文檔都對此進行了討論。 具體來說,有關Collections.emptyList() , Collections.emptySet()和Collections.emptyMap()的文檔每個狀態為“((不同于此方法,該字段不提供類型安全性。)”
對最后一個代碼清單中顯示的空集合使用Collections
方法可提供類型安全性,而無需顯式指定存儲在該集合中的類型,因為類型是通過在顯式分配給已知和已經聲明的實例屬性時使用Collections
方法來推斷的指定的元素類型。 如果無法推斷類型,則使用沒有顯式指定類型的Collections
方法時將導致編譯器錯誤 。 下一個嘗試在NetBeans中執行此操作的屏幕快照中顯示了這一點。
具體的編譯器錯誤消息是:
[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:62: error: method populateList in class Main cannot be applied to given types;[javac] populateList(Collections.emptyList());[javac] ^[javac] required: List<String>[javac] found: List<Object>[javac] reason: actual argument List<Object> cannot be converted to List<String> by method invocation conversion[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:63: error: method populateSet in class Main cannot be applied to given types;[javac] populateSet(Collections.emptySet());[javac] ^[javac] required: Set<String>[javac] found: Set<Object>[javac] reason: actual argument Set<Object> cannot be converted to Set<String> by method invocation conversion[javac] C:\java\examples\typesafeEmptyCollections\src\dustin\examples\Main.java:64: error: method populateMap in class Main cannot be applied to given types;[javac] populateMap(Collections.emptyMap());[javac] ^[javac] required: Map<String,String>[javac] found: Map<Object,Object>[javac] reason: actual argument Map<Object,Object> cannot be converted to Map<String,String> by method invocation conversion[javac] 3 errors
通過在代碼中顯式指定集合元素的類型,可以避免這些編譯器錯誤并實現類型安全。 這顯示在下一個代碼清單中。
使用Collections的Empty方法顯式指定元素類型
/*** Pass empty collections to another method for processing and specify those* empty methods using Collections methods. This will result in javac compiler* ERRORS unless the type is explicitly specified.*/public void instantiateWithEmptyCollectionsMethodsTypeSpecified(){populateList(Collections.<String>emptyList());populateSet(Collections.<String>emptySet());populateMap(Collections.<String, String>emptyMap());}
出于相同的目的,使用Collections
類的用于獲取空集合的方法比使用Collections
的類似命名的字段更可取,因為這些方法提供了類型安全性。 這樣可以更好地利用Java的靜態類型系統,這是諸如Effective Java這類書籍的關鍵主題。 一個不錯的副作用是消除了混亂的警告和標記的NetBeans提示,但是更重要的結果是更好,更安全的代碼。
參考: JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客中提供的Java類型安全的空集合 。
翻譯自: https://www.javacodegeeks.com/2012/11/type-safe-empty-collections-in-java.html