After reading and talking about Java 10s new reserved type name var
(JEP 286: Local-Variable Type Inference), one question arose in the discussion.
When using it with literals like:
var number = 42;
is number
now an int
or an Integer
? If you just use it with comparison operators or as a parameter it usually doesn't matter thanks to autoboxing and -unboxing.
But due to Integer
s member functions it could matter.
So which type is created by var
, a primitive int
or class Integer
?
A literal is the source code representation of a a fixed value that can be of a primitive type without requiring a computation. Java literals are suffixes and prefixes that represent Boolean, character, numeric, string data, and other primitive types.
Each primitive type has a corresponding wrapper: byte, short, int, long, float, double, boolean, char. Byte, Short, Integer, Long, Float, Double, Boolean, Character.
The valueOf method returns the wrapper classes from primitive types.
Wrapper class creates an object and primitive does not create object. Wrapper classes are used with Collections to represent type. Wrappers have methods and can hold memory address/null and primitives hold default values. Primitives are fast compare to wrapper classes as there is no overhead of methods or object.
var
asks the compiler to infer the type of the variable from the type of the initializer, and the natural type of 42
is int
. So number
will be an int
. That is what the JLS example says:
var a = 1; // a has type 'int'
And I would be surprised if it worked any other way, when I write something like this, I definitely expect a primitive.
If you need a var
as boxed primitive, you could do:
var x = (Integer) 10; // x is now an Integer
According to the proposed specification changes in 14.4.1 Local Variable Declarators and Types:
If LocalVariableType is
var
, then let T be the type of the initializer expression when treated as if it did not appear in an assignment context, and were thus a standalone expression (15.2). The type of the local variable is the upward projection of T with respect to all synthetic type variables mentioned by T (4.10.5).
In other words, the inferred type for the local variable is the type that the initializer expression would have if it were used as a standalone expression. 42
as a standalone expression has type int
, ergo, the variable number
is of type int
.
Upward projection is a term defined in the spec changes that doesn't apply to simple cases like this.
Let's test it. With jshell:
jshell> Integer boxed1 = 42000;
boxed1 ==> 42000
jshell> Integer boxed2 = 42000;
boxed2 ==> 42000
jshell> System.out.println(boxed1 == boxed2);
false
jshell> var infered1 = 42000;
infered1 ==> 42000
jshell> var infered2 = 42000;
infered2 ==> 42000
jshell> System.out.println(infered1 == infered2);
true
In the first comparison, the two variables are not the same; they're different instances. The second comparison is however true, hence an int must've been infered here.
Note: To try it at home, use values outside <-128, 128). Integer instances in that range are cached.
The compiler treats var number = 42;
similarly to int number = 42;
public void method(Integer i) {
System.out.print("Integer method");
}
public void method(int i) {
System.out.print("int method");
}
var n = 42; // n has type 'int'
method(n); // => "int method"
And auto-boxing when:
public void method(Integer i) {
System.out.print("Integer method");
}
var n = 42; // a has type 'int'
method(n); // => "Integer method"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With