Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Java

Variables and types

What is a variable, and what does a type decide?

A variable is a name under which a value is stored. The single line int age = 20; has three parts. int is the type, which means that this variable holds only integers. age is the name. 20 is the value to store first. This line is called a declaration. When the compiler reads a declaration, it remembers that "age is an int variable," and before the program runs it checks that the lines after it fit what it remembered. In this lab you remove the type int, change the value that is stored, and store no value at all. Each time, the same code is compiled and run, so you can see what the compiler reports and what is printed.

Checked against real execution · Six combinations were compiled with javax.tools on JDK 21, run, and checked against the results

Concepts in this lab

Variable
A variable is a name for a storage location that holds a value. Every variable has a type that is already fixed at compile time, and the type decides what kind of value the variable can hold. For example, a variable declared as int age; can hold only integers, and int is a 32-bit integer from -2147483648 to 2147483647. A value is stored in a variable with =, and age = age + 1; means "store the value calculated on the right in the variable on the left." The stored value can change, but the name and the type of the variable do not change. Trying to store a value that does not fit the type is a compile-time error.
Declaration and initialization
A declaration is the line that creates a variable inside a method. It is called a local variable declaration, and it gives a type, a name, and optionally a first value after = (the initialization). int age; only declares, and int age = 20; declares and initializes at the same time. If you use a name that was not declared, the compiler cannot find the name and reports an error. A local variable, unlike a field, does not automatically get a default value such as 0, so a value must be stored in it before it is read, or else it is a compile-time error. A name written on the left of =, where a value is stored, does not count as reading.
Type
A type is a name that decides what kind of value a variable can hold. The types of Java are divided into primitive types and reference types, and the reference types are class types, interface types, type variables, and array types. When you write a class Card or interface Payable declaration, you can use Card and Payable as types. On every line that puts a value in a variable, the compiler checks that the type of the value is the same as the type of the variable or a subtype of it. An interface that a class names with implements is a supertype of that class. If you use a name that is not declared as a type, the compiler cannot find that type and reports an error.
Primitive types and reference types
These are the two kinds into which the types of Java are divided. There are eight primitive types, byte, short, int, long, float, double, char, and boolean, and a variable of one of them holds the value itself. Reference types are all the other types, such as classes, interfaces, and arrays, and a variable of one of them holds a reference to an object, not the object itself. So assigning a variable of a primitive type copies the value, and the two variables do not affect each other, but assigning a variable of a reference type copies the reference, and the two variables come to refer to the same object. A variable of a reference type can hold null, which means that it refers to no object, and a variable of a primitive type cannot hold null.

Try these

Running with the default settings

  1. The compiler reads main from the top. First it reads the line int age = 20;. This line has three parts. int is the type, which means that only integers are stored. age is the name. 20 is the value to store. The compiler remembers that "the name age is a variable of type int."
  2. The compiler checks the value to store. 20 is an integer, so it can be stored in the int variable age, which holds only integers.
  3. The compiler checks the line age = age + 1;. The age + 1 on the right reads the value stored in age. age is declared as an int and a value was stored in it on the previous line, so it can be read. The result of adding 1 to an int is also an integer, so it may be stored in age again.
  4. The compiler checks the line System.out.println(age);. age is an int variable and has a value stored in it, so it can be read and printed.
  5. Compiling succeeds, and the Main class file to run is created. Whether age is an int, whether the stored value fits, and whether age can be read were all checked now, while compiling, and not when the program runs.
  6. You run it with java Main. main starts, and the line int age = 20; runs. An int slot with the name tag age is created, and 20 is stored in that slot.
  7. The line age = age + 1; runs. First it calculates the age + 1 on the right. Adding 1 to the 20 in the age slot gives 21. This value is stored in the same age slot. The slot stays the same, and only the value inside changes from 20 to 21. Here = does not mean "equals." It means "store the result on the right in the slot on the left."
  8. System.out.println(age); runs. It reads the value in the age slot and prints 21 on the screen.

Result of this run

Code

public class Main {
    public static void main(String[] args) {
        // Declaration: create a variable age of type int and store 20 in it
        int age = 20;
        age = age + 1;
        System.out.println(age);
    }
}

Assumptions of this model

The compiler and the runtime environment are JDK 21.0.12.1 (javac 21). All six combinations were compiled with javax.tools from the same source as the code on the screen (identical line by line). The ones that compiled successfully were loaded with a new class loader and Main.main was run, and the results were checked against the captured standard output. What was checked is whether compiling succeeded, the diagnostic code of the first error (compiler.err.cant.resolve.location, prob.found.req, and var.might.not.have.been.initialized, which are shown on the screen as the three error descriptions), the number of errors and the lines they occurred on, whether the Main class file was created, and the output when run. The documentation was checked by opening the Java Language Specification (Java SE 21) directly. That every variable and expression has a type known at compile time follows the beginning of chapter 4; that a variable is a storage location with a compile-time type follows section 4.12; that a variable of a primitive type holds only values of that type follows section 4.12.1; that int is a 32-bit signed integer follows sections 4.2 and 4.2.1; that a local variable declaration consists of a type (or var), a name, and an optional initializer follows section 14.4; that a variable declared without an initializer must be assigned before it is read, or else it is a compile-time error, follows sections 14.4.2 and 4.12.5 and the beginning of chapter 16. That a local variable, unlike a field, does not automatically get a default value is also in section 4.12.5. That only reading a value counts as access, and the name on the left of = does not, is in the beginning of chapter 16. The kinds of errors, the number of errors, and the lines they occur on are not set by the specification but were observed with this javac. When there are several errors javac reports all of them, but the table shows only the first. In every combination that failed to compile, the Main class file was not created, which is why the screen says it cannot run. In the combination with neither the type int nor a value, the declaration line was left out entirely. A line with only age; and no type is not a statement allowed by the grammar (section 14.8: the only expressions that can be used as statements are assignments, increments and decrements, method invocations, and object creations), and when this form was compiled once separately, javac gave a syntax error saying not a statement (it was not included in the check of the combinations). This lab covers only a local variable and a single int. It does not cover other primitive types, variables of reference types, var, naming and scope of variables, or constants (final). How values are copied for variables of primitive and reference types is covered in "In-depth lab: Variables and types".

Next lab: Methods

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these