PrimitiveVariablesDynamicallyTyped
DRAFT

Misconception:

The type of a primitive variable x depends on the value that was assigned to it. For example, if we initialize x=44100, then the type of x is int.

Incorrect

The type of a primitive variable depends on its value

Correct

Correction
Here is what's right.

Java supports two kinds of types: primitive types and reference types. In Java, a variable uses only a few bits of memory (e.g., an int uses 32 bits, a double uses 64 bits, and a reference uses 64 bits on a modern machine). A variable of a primitive type directly holds its value in its own few bits of memory. A variable of a reference type holds a reference to an object on the heap. The object is not stored in the variable itself (it’s most probably too big to fit in the few bits of memory a variable represents). The variable stores a reference (which in most virtual machines is simply the address on the heap at which the object is stored).

For variables of primitive types, the static and dynamic types are identical. The static type is the declared type of the variable (e.g., double x would declare x to have type double). The dynamic type is the type of the value sitting in the variable. For primitive variables, the value assigned to a variable is converted to the variable’s type (because the value is directly stored in the bits of memory the variable represents). When you then load the value from the variable, you get a value with the exact same type as the variable.

Take the following code:

double x = 44000;

The variable x has type double. We initialize it with the value of the expression on the right-hand side of the equals sign. That expression, which just consists of an int literal, has type int. However, variable x has type double. According to the Java language specification, we can assign an int to a double variable. This is ok, because the int value will (implicitly) be converted into a double value, and only then stored in x. If we later try to access the value of x, we get back the double value stored in that variable:

System.out.println(x); // will print 44100.0
int y = x; // will not compile (x has type double)
int z = 2*x; // will not compile (2 has type int, x has type double, 2*x has type double)

Note: Implicit type conversions for reference types look similar to the above implicit type conversions for primitive types. However, they are different: a variable of a reference type does not store the object, but only a reference to the object. The object itself sits on the heap. The object has a type, and it is never “coerced” into (reshaped into the representation of) some other type. If we assign a value of type String to a variable of type Object (Object is a supertype of String), then we can do that. The static type of the variable will be Object. However, the dynamic type of the variable—type of the object pointed to by the variable—will still be String. The object does not get converted. Only the reference to the object gets “converted” (i.e., playing with that reference, stored in the variable of type Object, we won’t be able to access members introduced in class String).

int i = 44100;
double d = i; // implicit conversion from int to double

String s = "Hello";
Object o = s; // implicit conversion from String reference to Object reference
// o is of static type Object, but it still points to a String object

Stay up-to-date

Follow us on  twitter to hear about new misconceptions.