Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using var with a literal result in a primitive or a primitive wrapper class?

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 Integers member functions it could matter.

So which type is created by var, a primitive int or class Integer?

like image 717
sweisgerber.dev Avatar asked Mar 22 '18 09:03

sweisgerber.dev


People also ask

Is a literal a primitive data type?

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.

Which of the following are wrapper classes for 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.

Which methods return wrapper class objects from primitive values?

The valueOf method returns the wrapper classes from primitive types.

What is the difference between primitive and wrapper class?

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.


4 Answers

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
like image 52
Eugene Avatar answered Oct 14 '22 05:10

Eugene


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.

like image 20
Jörg W Mittag Avatar answered Oct 14 '22 05:10

Jörg W Mittag


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.

like image 35
david a. Avatar answered Oct 14 '22 06:10

david a.


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"
like image 1
tonyhoan Avatar answered Oct 14 '22 06:10

tonyhoan