Variables, primitive types, and references
The eight primitive types, the difference between values and references, and how the compiler infers types.
Runs on a sandboxed JVM via the public Piston API. Edit the code and hit Run.
The eight primitives
Java has exactly eight primitive types: byte (8-bit), short (16), int (32), long (64), float (32-bit IEEE 754), double (64-bit IEEE 754), char (16-bit unsigned, a UTF-16 code unit), and boolean. Primitives store their value directly in the variable — no heap allocation, no null.
References vs values
Everything that is not a primitive is a reference: String, arrays, your own classes. The variable holds a pointer-like handle to an object on the heap. Two references can point at the same object, and passing a reference to a method lets the callee mutate that object — even though Java is technically pass-by-value (of the reference).
Literals and suffixes
100 is an int; write 100L for a long. 3.14 is a double; write 3.14f for a float. Underscores are legal separators in numeric literals: 1_000_000. Character literals use single quotes ('A'); double quotes make a String.
Runs on a sandboxed JVM via the public Piston API. Edit the code and hit Run.
`var` is inference, not dynamic typing
Since Java 10 you can write var n = 10; and the compiler infers int. The type is fixed forever at that point — reassigning n = "hello" fails to compile. var is only allowed for local variables with an initializer; it can't be used for fields, method parameters, or return types. Prefer it when the right-hand side already spells out the type (var list = new ArrayList<String>()).
Boxing and wrappers
Every primitive has a matching wrapper class (int → Integer, double → Double, etc.). Autoboxing converts silently, but it costs a heap allocation and can bite you: Integer a = 128; Integer b = 128; a == b is false because values outside -128..127 aren't cached. Always compare wrappers with .equals() or unbox first.
Scope and final
Local variables live from declaration to the end of their enclosing block. Marking a variable final prevents reassignment — the reference is fixed, though the object it points to may still mutate. final is required for variables captured by lambdas and anonymous classes.