A Hands-on Overview of the New Java Local Variable Type Inference Language Feature

var and val are coming to Java

A new JDK Enhancement Proposal (JEP) is making waves in the Java community: JEP 286. The proposal suggests to introduce Local Variable Type Inference in future versions of Java, in order to simplify the writing of Java applications.

In the following post we will explain what it means and how it will affect your code.

The var Proposal

The new language feature suggests adding some syntactic sugar to Java – simplifying it and improving developer experience. The new syntax will reduce the ceremony associated with writing Java, while maintaining the commitment to static type safety.

In other words, you’ll be able to declare variables without having to specify the associated type. Oracle stated that this new feature will allow, for example, declarations such as:

var list = new ArrayList<String>();
val stream = getStream();

That will replace the current syntax:

List<String> list = new ArrayList<String>();
final Stream<String> stream = getStream();

As you can see, the Local Variable Type Inference will allow using the var keyword instead of specifying the type of the variable.

Java is known to be a bit verbose, which is good when it comes to reading and understanding what you or another developer had in mind when a function was written. For those of you who always thought it was a bit tedious, the proposal marks a significant change.

This proposal is not relevant for Java 9, which is already in the making and will also change the way you code.

To JEP or Not to JEP?

A few weeks ago Brian Goetz, Java Language Architect at Oracle, published the survey results for this new proposal. The main question was: “What do you think of the proposed Local Variable Type Inference feature overall?”. 2,453 developers replied, and the result we’re mostly positive:

What do you think of the proposed Local Variable Type Inference feature overall?
What do you think of the proposed Local Variable Type Inference feature overall?

The second part of the survey focused on the future syntax, suggesting 5 options to choose from based on similar use in other languages, such as C#, Scala, Swift, C++ or use let. Most users chose the var/val option:

Possible syntax options
Possible syntax options

Even though most users approve of this new option, reading through the comments section shows developers who approve of this change, asking Oracle to “get with the times”, pointing out this change should apply only to val and even asking for more changes, such as multi-line strings.

The developers who are against this proposal claim that it might be difficult for those who are taking their first steps in Java, or point out that the existing syntax is the “right mix of verbosity and legibility” and that “the diamond operator was a good move”, unlike the current proposal.

Where is This Change Coming From?

One of the most common complaints about Java is the amount of boilerplate coding required to write it. A few lines of Java code can be written with a single line in other languages, such as C++, C#, Scala and Go.

While Type Inference is not a new concept in Java, it is a new concept for local variables.

It was partly introduced in Java 7 (as part of Project Coin) with the diamond operator (<>), which allows initializing lists without a type bound ArrayList<>, and in Java 8 with Lambda Formals. For example, using the diamond operator allowed writing the following code:

List<String> list = new LinkedList<String>();

And of course, on the JEP 286 summary page you’ll be able to find the following justification from Oracle for adding the new feature:

“Java is nearly the only popular statically typed language that has not embraced local-variable type inference; at this point, this should no longer be a controversial feature”

How Will This Affect Your Code?

Oracle knows that the community might take time to adapt and accept this new proposal. While it’s still not clear if and when JEP 286 will become a reality in future versions of Java, it’s enough to make a few developers in the community speak out.

If you’re one of those developers, you’d be happy to learn that this treatment is restricted to:

  • Local variables with initializers
  • Indexes in the enhanced for-loop
  • Locals declared in a traditional for-loop

Oracle states that It will not be available for:

  • Method parameters
  • Constructor parameters
  • Method return types
  • Fields
  • Catch formals (or any other kind of variable declaration)

Due to Java’s commitment to support previous versions of Java, we can assume it won’t break backwards compatibility.

Do Try This at Home

We at OverOps always love to try new things before they hit the market, and JEP 286 is exactly that. If you didn’t form an opinion about JEP 286, you can check it out for yourself right now.

As part of the Adopt OpenJDK program, Richard Warburton and Raoul-Gabriel Urma has publicly posted unofficial builds of the Open JDK with JEP 286 support. That way, you’ll be able to experiment with the new features, get to know what JEP 286 is all about and get a taste of it in action.

Final Thoughts

This new proposal is stirring things up in the Java community, getting a lot of attention. The fact that you can test drive the new feature right now will help developers realize what the future of Java might have in hold.

It is important to remember that this is an early proposal and it’s still not clear whether Oracle will implement it. That’s why we encourage you to participate in future surveys and be an active part of this JEP, and other future Java related features.

I write about Java, Scala and everything in between. Lover of gadgets, apps, technology and tea.
  • mquinsland

    JVM without verbosity? Maybe Java 9 will be spelled S-C-A-L-A

    • ehud lev

      Exactly !!!! I wonder when they add macros 🙂

      • HaakonKL

        Lombok already implements a lot of compiler macros.

    • Jason LeCount

      Exactly it. It feels like you could get this improvement plus twenty others by just switching to scala rather than improving java piecemeal…

      I personally feel like somebody has made me type one-handed when having to go back to writing java.

  • Yonatan Graber

    Lombok provides the val functionality for a while: https://projectlombok.org/features/val.html Generally speaking, Lombok reduces significant amount of verbosity, and probably should always be used.

    • Henn Idan

      Hi Yonatan, cool, thanks for pointing it out!

    • http://trydent.io TryIO

      please don’t! it’s a good choice when you need to create prototypes, but then you’re gonna regret it…

      • HaakonKL

        But that’s wrong. Lombok is tasty. It’s not exactly magic either. It does exactly what it says on the tin, and you can override any getter and setter that needs to do extra stuff.

  • davidriss

    I’ve been writing code using Java for 15 years or more, and one thing I can’t understand is why they keep insisting in not putting a better way to generate getters and setters, which still being the heart of many design patterns in Java. I hate to open a VO java source and see 10 times more lines than it would be needed. I know Java committee would bring a nice explanation on why they keep things that way, but the fact is: more lines of code cause more bugs and requires more effort to understand. Java is loosing field to other languages like Scala or even others because they are too stubborn to accept some changes. Just for the records, I generally use Project Lombok to get rid of getters and setters generation, but I miss an official solution to it.

    • paul

      The problem with giving java first class properties (i.e. an implicit getter and setter for fields) is that fields and methods are treated differently for inheritance: having myobj.name call an implicit ‘getName’ method would theoretically break existing code which relied on the fact that field access in java does not go through the override dynamic dispatch mechanism (where as a call to an implicit getter would). To be honest it was a bit of a facepalm design decision not to dispatch field access the same as method access but were stuck with it if we want to maintain backwards compatibility.

      • davidriss

        I know, and I wouldn’t expect a real property, but at least an annotation or a property keyword to get rid of tedious and error prone pattern :
        public void setValue(T value) {
        this.value = value;
        public T getValue() {
        return this.value;
        I can’t believe that I’m still being obliged to do that in 2016!

        • http://trydent.io TryIO

          The «property» proposal was given for Java7, but it was denied. The reason was due that Java can survive without them, since generally speaking (but this is a huge topic as well) properties used as getter/setter is a bad practice. With JEE8 for instance the evaluation of the JavaBean state won’t rely on getters/setters by default (nowadays – that is JEE6/7 – it is), but on inner-fields, since as you said getter/setter methods are an error prone pattern (and they are able to invalid the state of an object).

          In my opinion data classes (that is all such classes with a list of never-ending properties) are a bad practice too: in Scala you have case-classes, in Kotlin you have data-classes and other langs propose something similar (in Groovy is even worse, since you just need to define the sequence of inner-fields and under-the-hood they are going to be all getter/setter methods by default).

          • Oleksandr Alesinskyy

            Yes, but the same “can survive them” logic is completely applicable to the var/val proposal. Likely, to even greater extent as the “property” proposal does not decrease code readability, and “var/val” does decrease (not critically, but decrease).

          • http://trydent.io TryIO

            I think the problem is not readability but designability 😉 if we want to keep defining huge objects with ton of backing fields, Property can increase readability but not design in my opinion.

            var/val is just a shortcut to define local fields in the end and if you’re code doesn’t break law of Demeter and the compiler cares about method returning type (as it has been suggested in the proposal) you’re able to write readable code anyway. This strongly depends on what kind of developer reads others’ code and who wrote that code, but this is a never-ending debate which not depends on var/val.

          • Oleksandr Alesinskyy

            Yes, and the problem is that a developer and the compiler may be of different opinions of a type of such variables.

            Mainly, it breaks (to some extent) on of the main principles formulated when Java was conceived – Java is for readers and not for writers.

          • http://trydent.io TryIO

            I didn’t follow you on «different opinions» about compiler, what do you mean?

          • Oleksandr Alesinskyy

            A developer may make incorrect judgement about what a compiler will infer.

          • HaakonKL

            In Java you have Lombok.

    • HaakonKL

      Project Lombok! Project Lombok!
      It gives you:
      val and var types, just like JEP286 would!
      Automatic getters and setters!

      That’s right, you can now make a bean like so:

      public class InventoryBean {
      private int sku;
      private String stockName;
      private int unitsInStock;
      private LocalDateTime fetchTime;
      private long price;

      And you’ll get your class, with getters, setters, hashCode, equals, toString and a free hug. Boolean getters will be called isVariableName, and everything else is getVariableName, just like the standard wants. Since it’s a bean you get a no-args constructor.

      Now you might say that such a JPA-ish view from a database should look a bit different, and should probably be a value object and have an all args constructor. Everything private final, and so on. Well, in order to do that you get:

      public class InventoryBean {
      int sku;
      String stockName;
      int unitsInStock;
      LocalDateTime fetchTime;
      long price;

      And now everything will be private final, you’ll have getters (no setters), and you’ll get an all-args constructor.
      You also get to do things like this:

      var someVariable = foo.frobnicate().toBar().bazzing(quux);
      val yupItWorks = someVariable.quuinx("GNU Placeholder Variable Names are weird");

      Just give it a look-see. It Makes Java Great Again. :3

  • Mario Pimenta dos Reis

    Java can be more useful and do things in few less lines as other languages can do, Getters and Setters can be smallers. the developers of the new JDK would made Java a new language for better purposes. Lambda was a great addiction i hope they revise Java to make it more modern.

  • TheMeerkat

    I personally don’t se a problem with verbosity. Most of the time we spend on reading code, not writing and in many cases verbosity actually helps to understand the code.
    I had a bit of experience with Kotlin and I found that I was missing been able to find the types of the variables easily).
    I have the same problem with functional style – when you see a long multi-line statement with a lot of functional calls, it is more difficult to understand if you not familiar with the code and the types of what is return by functions are not clear.

    • HaakonKL

      You have similar things in Lisp, which is dynamically typed and there you just ask the compiler what type something is. A modern Java-IDE should be able to do the same for you.

  • Emil

    The problem is that var and val are already valid identifiers. Remember that const is reserved and unused.