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):

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

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()
   {
      populateList(Collections.<String>emptyList());
      populateSet(Collections.<String>emptySet());
      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.

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

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

  1. Amit Phaltankar says:

    Thanks for such a cool post.

    Really nice !!

Leave a Reply


nine − 8 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books