Yesterday we ran a live webinar on Java 10 features and how to use them, particularly in IntelliJ IDEA (of course). The recording is now available for you to view.
During this webinar we look at:
- The major changes in Java 10
- Local Variable Type Inference (the use of
var
) - The changes in Oracle’s support roadmap (TL;DR: Java 9 is already end of life, use Java 8 or Java 10)
- IntelliJ IDEA’s inspections for migrating to use
var
The key points are covered in the first ten minutes of the video, but if you want a deeper view of good and bad places to use var
, carry on watching – we cover most of the points mentioned in the LVTI style guide, and then spend plenty of time answering your questions.
About 45 minutes in, we also show, very briefly, a couple of the nice new API additions in Java 10, specifically List.copyOf
and Collectors.toUnmodifiableList()
.
There were some questions that could not be answered during the recording, and some that benefit from either a deeper dive or that work better in a blog post (for example because we can include links or code). Here they are:
Are there any performance implications of using var?
During the webinar we suggested “probably not”. This blog post by Nicolai Parlog not only does a good job of covering the feature, but also shows that var is only at the compiler level, and that decompiling a class that contained var will give you all the original types as you expect.
So short answer: no.
So var is broadly comparable to C++ auto?
Yes, pretty much.
Can you use instanceof or perform explicit casting with var?
Yes, this works the way you’d expect. Check out the following examples run via the REPL (JShell):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
jshell> var list = List.of("one") list ==> [one] jshell> System.out.println(list instanceof ArrayList); false jshell> System.out.println(list instanceof List); true jshell> var arrayList = ((ArrayList) list) | java.lang.ClassCastException thrown: java.base/java.util.ImmutableCollections$List1 cannot be cast to java.base/java.util.ArrayList | at (#9:1) jshell> var arrayList = ((AbstractList) list) arrayList ==> [one] |
Can you declare var without initializing it?
No.
For example:
1 2 3 4 5 6 |
jshell> var x; | Error: | cannot infer type for local variable x | (cannot use 'var' on variable without initializer) | var x; | ^----^ |
Does var keyword work with primitives also?
Yes, but there’s not much point, mostly because you don’t save yourself a lot of boilerplate (int vs var, for example). Also see guideline 7, this shows some cases where you might get unexpected results from using var with literals.
Why only var and not var/val?
The community was asked, and the short version is that while more people liked var/val or var/let over just var, more people also hated var/val or var/let more than just var (see more info here). It was the pragmatic choice.
Does anyone know the fate of JAX-B with Java 10 and beyond?
The Java EE modules were deprecated in Java 9, this includes JAXB. The current plan is to remove them in Java 11. This means that if you’re dependent upon JAXB, you need to make sure you’re including a dependency on an external version (e.g. from Maven Central), not the versions that come bundled as part of Java SE. Ideally make this move before you adopt Java 11 so the transition is easier.
What’s coming in Java 11?
The roadmap may not be complete yet, but you can see it on the OpenJDK site.
The code that is used in the presentation, is it available for the general public?
Yep, it’s here, specifically Java10Inspections.
In summary, the most useful links are:
- Style Guidelines for Local Variable Type Inference in Java
- Local Variable Type Inference Frequently Asked Questions (link updated 2018/10/16 to most recent version)
- Code is available here.

The video mentions not having suggestions when using diamond operators, e.g. “C v = new C()” – since that would give you a type specialized for Object instead of T.
Why not have a suggestion that turns the above into “var v = new C()”, though? That seems intuitively to be what one would want?
Yes, that would be nice. I guess you mean, for example, turn:
List words = new ArrayList();
into:
var words = new ArrayList();
or maybe:
List strLst = new ArrayList();
into:
var strLst = new ArrayList();
omg it doesn’t accept the ‘<'s
I meant:
List” strLst = new ArrayList();
into:
var strLst = new ArrayList(”);
Hmm, yes we are having some trouble rendering code!
I’m assuming the question is: can we automatically turn
List<String> words = new ArrayList<>();
into
var words = new ArrayList<String>();
It does seem like a sensible suggestion, and indeed there is a request for this feature:
https://youtrack.jetbrains.com/issue/IDEA-188771
Feel free to comment or upvote.
I quit 😛
Oh, now I understand why the original question lacked the angle brackets
A jetbrains blog should accept code I guess. 😉
I am getting an error when trying to add JDK 10:
“the selected directory is not a valid home jdk”
Windows 7 professional
jdk-10.0.1
Intellij 2017.2.1
Please help
IDEA 2017.2 was release before java 10 and doesn’t support it. Please use 2017.3 or 2018.1 releases. Thanks
That solves it, thank you for the tip !!!
Could not determine Java version using executable /usr/lib/jvm/java-10-oracle/bin/java
IntelliJ Community 2018.3
Ubuntu 18.04
Java 10.01
Please help
Hi Piyush, please could you raise a ticket at https://youtrack.jetbrains.com/issues/idea, and then someone can help you out. Thanks!