Java 9's other new enhancements, Part 2: Milling Project Coin

JEP 213 builds on Java 7's Project Coin with small language improvements and additions for your Java programs

Page 2 of 2

Although you can still use two or more underscores to name identifiers, you should avoid this practice because it makes source code hard to read and greatly increases the chance for introducing bugs into the source code. By the way, can you use multiple underscores to denote unnamed lambda parameters in Java 8 and/or Java 9?

Supporting private methods in interfaces

Java 8 made it possible to declare default and static methods with implementations in interfaces. However, you couldn't declare these methods private, preventing them from being called from beyond the interface. A private method could serve as a helper method whose common code is executed by multiple non-private default or static methods.

Java 9 corrects the Java 8 deficiency by supporting private methods. A private method is a static method or a non-default instance method that's declared with the private keyword. You cannot declare a default method to also be private because default methods are intended to be callable from the classes that implement their declaring interfaces.

Consider the following examples:

private static void a() {}

private void b() {}

private default void c() {} // error: cannot be private and default

private abstract void d(); // error: an abstract method cannot also be private

Although these examples illustrate the declaration of private static and non-default methods, they don't give a sense of their usefulness. Therefore, I've created a sort-oriented example that reveals this usefulness while also demonstrating SafeVarargs in a private-method context. Listing 4 presents the example's Sortable interface.

Listing 4. Sortable.java

public interface Sortable
{
   @SafeVarargs
   public static <E extends Comparable<E>> void sortAZ(E... elements)
   {
      sort("AZ", elements);
   }

   @SafeVarargs
   public static <E extends Comparable<E>> void sortZA(E... elements)
   {
      sort("ZA", elements);
   }

   @SafeVarargs
   private static <E extends Comparable<E>> void sort(String order, 
                                                      E... elements)
   {
      if (order == "AZ")
      {
         for (int pass = 0; pass < elements.length - 1; pass++)
            for (int i = elements.length - 1; i > pass; i--)
               if (elements[i].compareTo(elements[pass]) < 0)
               {
                  E temp = elements[i];
                  elements[i] = elements[pass];
                  elements[pass] = temp;
               }
      }
      else
      {
         for (int pass = 0; pass < elements.length - 1; pass++)
            for (int i = elements.length - 1; i > pass; i--)
               if (elements[i].compareTo(elements[pass]) > 0)
               {
                  E temp = elements[i];
                  elements[i] = elements[pass];
                  elements[pass] = temp;
               }
      }
   }
}

Sortable declares three static methods, where the first two public methods invoke the third private method. Because this is a utility-oriented interface, you don't need to implement it in any class that uses it, such as Listing 5's SortableDemo class.

Listing 5. SortableDemo.java

public class SortableDemo
{
   static String[] directions = { "North", "South", "East", "West" };

   static class Employee implements Comparable<Employee>
   {
      private String name;

      Employee(String name)
      { 
         this.name = name;
      }

      @Override 
      public int compareTo(Employee e)
      {
         return name.compareTo(e.name);
      }

      @Override
      public String toString()
      {
         return name;
      }
   }

   static Employee[] employees = 
   { 
      new Employee("C"),
      new Employee("A"),
      new Employee("B")
   };

   public static void main(String[] args)
   {
      Sortable.sortAZ(directions);
      for (String direction: directions)
         System.out.println(direction);
      System.out.println();

      Sortable.sortZA(directions);
      for (String direction: directions)
         System.out.println(direction);
      System.out.println();

      Sortable.sortZA(employees);
      for (Employee employee: employees)
         System.out.println(employee);
   }
}

SortableDemo declares a couple of comparable arrays along with a nested class and a main() method to drive this application. This method invokes Sortable's sortAZ() and sortZA() methods on these arrays to perform the sort operations; the sorted contents are subsequently output.

Compile Listings 4 and 5 as follows:

javac *.java

Run the resulting application as follows:

java SortableDemo

You should observe the following output:

East
North
South
West

West
South
North
East

C
B
A

Conclusion

JEP 213 identifies three small Project Coin enhancements and two Coin-like enhancements: reserving a single underscore character for future use and supporting private methods in interfaces. Although they're not spectacular like lambdas, you'll probably find most of these tiny improvements to be helpful once you've familiarized yourself with them.

download
Get the source code for this post's applications. Created by Jeff Friesen for JavaWorld

The following software was used to develop the post's code:

  • 64-bit JDK 9ea+154

The post's code was tested on the following platform(s):

  • JVM on 64-bit Windows 8.1
| 1 2 Page 2