Answer to your question:
What happens when the class I instantiate and assign to the variable declared with var, is the implementation of the interface? which type is it going to be inferred, Interface or the implementation?
Inferred type of the variable will be exactly the class, reference to the instance of which you're assigning to the variable declared with var
.
Regarding "interface" point: if it (class of the object, reference to which you assign to variable declared with "var") is an implementation of some interface, what do you think will happen if that class implements two or more interfaces? how, do you think, Java should decide on which super-type (i.e. interface) to infer for the variable? this is impossible even by basing our judgement purely on a logic (without any relation to Java) - there will be no "source of truth", by which, Java would be able to decide on this.
Motivation for var keyword:
Remember, that the only stated purpose of using var
, according to the language designers (since JDK 10+), has been the point to beautify the code and make it more readable (which, I personally think, is a non-sense as having "var" in Java, is worse than having explicit types, and in many ways so).
For example, this code:
URL url = new URL("http://www.oracle.com/");
URLConnection conn = url.openConnection();
Reader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
is (according to official JEP document) less clear to read than:
var url = new URL("http://www.oracle.com/");
var conn = url.openConnection();
var reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Implementation details:
var
was introduced with the purpose of serve the cleaner/better readability and NOT to amend the Type System of the Java language. That's why, you can't use it in the class level (for static or instance) fields, because fields might be used with polymorphism (might receive different implementation types, might be injected by IoC, or etc.) and at the bytecode, it's not possible to dynamically change the field type for each different case.
Update:
Why I think "var" is bad and why I try to avoid it?
Well, for several reasons:
- code gets actually harder to read, and not only in a sense of merely reading it, but also in a sense, that you may have hard times when trying to understand what is the actual type you are getting the reference to. Imagine if the actual object creation expression is some long builder pattern code.. or factory pattern call.. or etc. you basically have to go and open/decompile the source and see what you get. So, it's harder to read and harder to understand;
- this will often lead (especially a bit less experienced in Java) engineers to confusion whether typing becomes dynamic or keeps static;
- polymorphic calls are not supported and polymorphism, in general, is not possible, because compiler cannot infer different types with the same code;
- code actually gets inconsistent, as you'll be having explicit types for fields and "var"s for local variables. This will also (but not only) confuse newcomers to Java;
- maybe not that important.. but this can be important as well: "var" will also break backwards compatibility, as you won't be able to downgrade to the Java version below 10.