1.4. Reference Types and Assignment Values

Consider the following reference type variable declaration:

SomeType varName;

Here, we use SomeType as a placeholder for any reference type (class, array, or interface).

Remember: the values that can be assigned to varName are null and any reference to an object whose type is compatible with SomeType. In Java, a reference to an object of a particular type is always compatible with a variable of the same type. Here are some examples:

Listing 1.1 Valid declarations / initializations
Scanner scan = new Scanner(System.in); // same types
String str = "Hello";                  // same types

The memory diagram below illustrates how compatible reference assignments work in memory. Variable str stores a reference referring to a String object on the heap, the value of variable other is null, which means other does not refer to an object, and variable alias receives a copy of the reference in str, referring to that same object:

Code visualization diagram for java/variables/reference-types-and-assignment:31 (end of main)

Final captured memory state. [download] [open]

Values that are not compatible with the type of the variable cannot be assigned. For example, the following examples will not compile:

Listing 1.2 Invalid declarations / initializations - won't compile
Scanner input = 7.0;                   // Can't assign a double value to a Scanner variable
String str = new Scanner(System.in);   // Can't assign Scanner to String
int x = "Hello";                       // Can't assign String to int

When you invoke a constructor using new SomeClassName() (or similar), the type of the reference produced by the expression is the same as the class name. For example:

Listing 1.3 produces a reference of type Scanner
new Scanner(System.in);

The class instance creation expression above produces a reference value of type Scanner. We can assign that value to a variable of type Scanner:

Listing 1.4 valid because the type of the reference and the type of the variable are compatible
Scanner input = new Scanner(System.in);
Foreshadowing

Object references are also compatible with a variable when the variable's type is a superclass of the reference's type or an interface that the reference's type implements. We will discuss this in more detail later in the semester once interfaces and inheritance are introduced.

References can be assigned to any compatible variable, and a method can return with a reference whose type is compatible with the method's return type. In other words, the types don't have to match - they just have to be compatible. We will define this term formally in the upcoming chapters.