Pros and cons of JEP 286

Pros and cons of JEP 286

A couple of weeks ago a new JDK Enhancement Proposal (JEP) has been published: JEP 286

It proposes ‘var’ and possible also ‘val’ as a way to declare local variables. This means that for local variables you don’t need to specify the type of your variable when it can be safely infered.

Some examples:

    // Before:
    int ten = 10;
    List<String> list = new ArrayList<>();

    // After
    var ten = 10;    // infers int
    var list = new ArrayList<String>();  // infers ArrayList<String>

Personally I’m not convinced this is a good idea for Java, but OTOH some of my colleagues and co-workers are very happy with the proposal.

Let’s look at some of the pros and cons of this proposal.

Pro: Less typing!

There is one obvious pro: Less typing.

‘var’ is just three characters, while most other local variables type names are much longer.

Instead of typing int, List, Person or SpringObjectFactoryManagerTemplateProxyDelagate you just have var.

    // Instead of:
    List<Integer> myList = someMethod();

    // You can now have:
    var myList = someMethod();

    // We saved 10 keystrokes! (<- probably less if you know shortcuts in your IDE)

Con: Readability

The biggest advantage of Java over other languages is the readability. The language Java is a bit verbose, but this is actually a good thing when it comes to reading the code.

Code is read more than it is written

Consider the following:

    var myVariable = dependency.calculateSomething();

What is the type of myVariable? When you are writing the code, you probably have a good idea why you called dependency and what you receive as return value.

But when you are reading the code, there is no way of knowing what myVariable is… you probably need your IDE to tell you, or look at the code of the dependency.

I personally think this is a con regarding the JEP. I’d rather have a verbose language where the IDE helps me with autocomplete and hide things… than having a language that needs an IDE to help me makes sense of the code.

Pro: Adding var doesn’t break anything

Some peope think (and argue) that adding this feature breaks backwards compatibility (because of the new keyword).

But this is not true!

When ‘var’ gets added it won’t be a keyword, it’ll be a ‘reserved type name’. This means that the following code for example would be working just fine:

    // this compiles just fine:
    var var = "var";

Con: RHS versus LHS

This JEP focusses on the LHS (left-hand side) declaration by removing the need to specify a type. But recently, in Java 7, Java has introduced the diamond operator to eliminate verbosity in the RHS (right-hand side) declaration. With JEP 286, these two collide:

    // Before Java 7 'diamond operator':
    List<Integer> numbers = new ArrayList<Integer>();

    // With Java 7 'diamond operator', removing generic type on RHS:
    List<Integer> numbers = new ArrayList<>();

    // With JEP 286, we need to add the generic type again at the RHS...
    var numbers = new ArrayList<Integer>();

    // Java, make up your mind!

Pro and con: Refactoring

Some people have argued that, after JEP 286, refactoring can become easier. Look at the following, silly, example:

    public boolean hasClosed() {
        var list = getSomeList();
        for(var item : list) {
        	if(item.isClosed()) {
        		return true;
        	}
        }
        return false;
    }

No matter what getSomeList() returns, it should work as long as it has the method isClosed. I think this is a weird example, because normally you would define an interface with isClosed and every class that implements this interface can be replaced/refactored as well.

There is a counter argument that can be made, refactoring can also be dangerous with JEP 286, look at this (crafted) example:

    var answer = SomeCode.generate();
    System.out.println(answer + 42);

As long as the method generate returns a number the code works fine. But when someone changes the method to return an object or a String, it stops working without failing compilation. This argument however seems valid, but it would also break it you would have inlined the call to ‘System.out.println(SomeCode.generate() + 2);’.

This might make the problem a bit harder and more widespread. I believe there are more cases this can go wrong.

Try it out for yourself

The best way to get a feel for JEP 286 is just to try it out yourself!

There is a pre-compiled version of JDK-9 with JEP availabe for download at the website: iteratrlearning.

Conclusion

After looking at a lot of examples I’m still not convinced that JEP 286 is good nor bad. It can go either way. There are some good pros but also quite a lot of cons.

When discussing this JEP with co-workers and colleagues I often get the following reply:

The arguments you’re using have been used when C# adopted var/val, stop complaining, they did it.

But did you know most coding guidelines for C# warn you for using ‘var’?

Just read these guidelines from Microsoft:

  • Do not use var when the type is not apparent from the right side of the assignment.
  • Do not rely on the variable name to specify the type of the variable. It might not be correct.
  • Avoid the use of var in place of dynamic.
  • Use implicit typing to determine the type of the loop variable in for and foreach loops.

This, combined with readability, makes me lean towards a no for JEP 286 right now.

How about you? Leave a comment!