Type-safe Empty Collections in Java

I have blogged before on the utility of the Java Collections class and have specifically blogged on Using Collections Methods emptyList(), emptyMap(), and emptySet(). In this post, I look at the sometimes subtle but significant differences between using the relevant fields of the Collections class for accessing an empty collection versus using the relevant methods of the Collections class for accessing an empty collection.

The following code demonstrates accessing Collections‘s fields directly to specify empty collections.

Using Collections’s Fields for Empty 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;      

The code above compiles with javac, but leads to the warning message (generated by NetBeans and Ant in this case):

    [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.

Specifying -Xlint:unchecked as an argument to javac (in this case via the javac.compilerargs=-Xlint:unchecked in the NetBeans project.properties file) helps get more specific warning messages for the earlier listed code:

    [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 will also show these warnings if the appropriate hint box is checked in its options. The next three images demonstrate ensuring that the appropriate hint is set to see these warnings in NetBeans and provides an example of how NetBeans presents the code shown above with warnings.

Fortunately, it is easy to take advantage of the utility of the Collections class and access empty collections in a typesafe manner that won’t lead to these javac warnings and corresponding NetBeans hints. That approach is to use Collections‘s methods rather than its fields. This is demonstrated in the next simple code listing.

Using Collections’s Methods for Empty 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();

The above code will compile without warning and no NetBeans hints will be shown either. The Javadoc documentation for each field of the Collections class does not address why these warnings occur for the fields, but the documentation for each of the like-named methods does discuss this. Specifically, the documentation for Collections.emptyList(), Collections.emptySet(), and Collections.emptyMap() each state, ‘(Unlike this method, the field does not provide type safety.)’

Use of the Collections methods for empty collections shown in the last code listing provided type safety without the need to explicitly specify the types stored within that collection because type was inferred by use of the Collections methods in assignments to known and already declared instance attributes with explicitly specified element types. When type cannot be inferred, compiler errors will result when using the Collections methods without an explicitly specified type. This is shown in the next screen snapshot of attempting to do this in NetBeans.

The specific compiler error message is:

    [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

These compiler errors are avoided and type safety is achieved by explicitly specifying the types of the collections’ elements in the code. This is shown in the next code listing.

Explicitly Specifying Element Types with Collections’s Empty Methods

    * 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()
      populateMap(Collections.<String, String>emptyMap());

The Collections class’s methods for obtaining empty collections are preferable to use of Collections‘s similarly named fields for that same purpose because of the type safety the methods provide. This allows greater leveraging of Java’s static type system, a key theme of books such as Effective Java. A nice side effect is the removal of cluttering warnings and marked NetBeans hints, but the more important result is better, safer code.

Reference: Type-safe Empty Collections in Java from our JCG partner Dustin Marx at the Inspired by Actual Events blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

One Response to "Type-safe Empty Collections in Java"

  1. Amit Phaltankar says:

    Thanks for such a cool post.

    Really nice !!

Leave a Reply

7 × = seven

Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below: