thecodex.expert · The Codex Family of Knowledge
Java

Variables and Types in Java

Statically typed from the start — every variable declares its type, the compiler enforces it, and there is no silent coercion.

Java 21 LTSOpenJDKLast verified:
Canonical Definition

In Java, every variable has a declared type enforced at compile time — 8 primitive types (int, double, boolean, char, byte, short, long, float) stored by value, and reference types (all objects) stored as heap pointers, with autoboxing bridging primitives and their wrapper class equivalents.

The key difference from Python/JS

Java is statically typed — every variable has a declared type that the compiler enforces. There is no type coercion. No surprises at runtime about what a variable holds.

Primitive types

Java has 8 primitive types — not objects. They are stored directly (on the stack for local variables) and compared by value. Everything else is a reference type (an object on the heap).

TypeSizeDefaultRange / Notes
byte8 bit0−128 to 127
short16 bit0−32,768 to 32,767
int32 bit0−2,147,483,648 to 2,147,483,647
long64 bit0L±9.2 × 10¹⁸. Suffix L required: 9876543210L
float32 bit0.0fIEEE 754 single. Suffix f: 3.14f
double64 bit0.0dIEEE 754 double. Default for decimals
char16 bit'\u0000'Single Unicode code unit. Single quotes
boolean1 bitfalseOnly true or false. No int conversion
Javavariables.java
// Declare type explicitly — compiler enforces it
int    age       = 28;
double salary    = 85_000.50;   // underscores for readability (Java 7+)
boolean active   = true;
char   grade     = 'A';
long   population = 1_400_000_000L;

// var — local type inference (Java 10+)
var name = "Priya";       // inferred as String
var items = new ArrayList<String>();  // inferred as ArrayList<String>
// var is only allowed for local variables — not fields, parameters, return types

// Literals
int hex  = 0xFF;        // 255
int bin  = 0b1010;      // 10
int oct  = 0777;        // deprecated style, avoid

// Widening — automatic, safe
int    i = 42;
long   l = i;     // int widens to long automatically
double d = i;     // int widens to double

// Narrowing — explicit cast required (potential data loss)
double pi    = 3.14159;
int    floor = (int) pi;  // 3 — truncates, does NOT round

String and wrapper types

Javastrings_wrappers.java
// String — immutable, reference type, but gets special treatment
String s1 = "Hello";          // string pool (preferred)
String s2 = new String("Hello"); // new heap object (avoid)

// CRITICAL: == compares references, not values
System.out.println(s1 == s2);          // false — different objects
System.out.println(s1.equals(s2));     // true  — same content

// String is immutable — "changing" it creates a new object
String s = "Hello";
s = s + " World";   // new String object created; old "Hello" eligible for GC

// StringBuilder for building strings in a loop (mutable, fast)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
    sb.append(i).append(", ");
}
String result = sb.toString();   // "0, 1, 2, 3, 4, "

// Text blocks (Java 13+)
String json = """
    {
        "name": "Priya",
        "age": 28
    }
    """;

// Wrapper types — int → Integer, double → Double, etc.
Integer boxed = 42;    // autoboxing: int → Integer
int unboxed   = boxed; // unboxing: Integer → int

// Autoboxing pitfall
Integer a = 127;
Integer b = 127;
System.out.println(a == b);   // true  — cached range (−128 to 127)
Integer x = 1000;
Integer y = 1000;
System.out.println(x == y);   // false — outside cache range!
System.out.println(x.equals(y)); // true — always use equals()

Type casting and instanceof

Javacasting.java
// Pattern matching instanceof (Java 16+)
Object obj = "Hello, Java!";

// Old style
if (obj instanceof String) {
    String s = (String) obj;   // explicit cast needed
    System.out.println(s.length());
}

// Pattern matching — cleaner
if (obj instanceof String s) {
    System.out.println(s.length());   // s is already cast
}

// Switch expressions (Java 14+) with pattern matching (Java 21)
String result = switch (obj) {
    case Integer i  -> "Integer: " + i;
    case String  s  -> "String: "  + s.toUpperCase();
    case null       -> "null";
    default         -> "Other: " + obj.getClass().getSimpleName();
};

// Records (Java 16+) — compact immutable data carriers
record Point(double x, double y) {
    // Compact canonical constructor
    Point {
        if (x < 0 || y < 0) throw new IllegalArgumentException("Negative coordinates");
    }
    double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
}
Point p = new Point(3, 4);
System.out.println(p.x());                    // 3.0
System.out.println(p.distanceFromOrigin());   // 5.0
System.out.println(p);    // Point[x=3.0, y=4.0]  — auto toString

final, static, and constants

Javamodifiers.java
// final variable — cannot be reassigned after initialisation
final int MAX_SIZE = 100;
// MAX_SIZE = 200;  // compile error

// static — belongs to the class, not instances
class MathUtils {
    public static final double PI = 3.14159265358979;
    public static int add(int a, int b) { return a + b; }
}
MathUtils.add(2, 3);   // call without creating an object
double pi = MathUtils.PI;

// Sealed classes (Java 17+) — restrict which classes can extend
sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double base, double height) implements Shape {}

// Exhaustive switch on sealed type — compiler verifies all cases covered
double area = switch (shape) {
    case Circle    c -> Math.PI * c.radius() * c.radius();
    case Rectangle r -> r.w() * r.h();
    case Triangle  t -> 0.5 * t.base() * t.height();
};   // no default needed — sealed
Commonly confused
== compares references for objects, not values. For String and any object, == checks if both variables point to the same object in memory. "hello" == "hello" may be true due to string pooling, but new String("hello") == new String("hello") is false. Always use .equals() for objects.
Autoboxing Integer cache only covers −128 to 127. Integer a = 127; Integer b = 127; a == b is true because JVM caches these. Integer a = 1000; Integer b = 1000; a == b is false — different objects. This is a real source of bugs. Always use .equals() for Integer comparison.
Java and JavaScript are completely different languages. The name similarity is marketing from 1995. Java is statically typed, compiled to JVM bytecode, class-based, and has no connection to web browsers without a plugin. JavaScript is dynamically typed, runs in browsers natively, and is prototype-based.

The Java Memory Model and value semantics

The Java Language Specification §17 defines the Java Memory Model (JMM). For local variables, primitives are stored on the thread stack — each thread has its own copy. Objects are allocated on the heap and shared across threads via references. The JMM defines a happens-before relation — if action A happens-before action B, then all effects of A are visible to B. Without explicit synchronisation, there is no happens-before between threads, and the JVM and CPU are free to reorder operations. This is why unsynchronised access to shared mutable state produces data races.

String interning and the string pool

String literals are automatically interned — stored in the JVM's string pool (part of the heap since Java 7; previously PermGen). All string literals with the same content share the same object. String.intern() explicitly interns a string. This is why "hello" == "hello" is usually true (same interned object) but new String("hello") == new String("hello") is false (two new heap objects). The JLS §3.10.5 specifies that string literals of the same compile-time constant value share the same String object.

Sources

1
Java Language Specification §4 — Types, Values, Variables. docs.oracle.com/javase/specs/jls/se21/html/jls-4.html.
2
Java Language Specification §17 — Threads and Locks (Java Memory Model). docs.oracle.com/javase/specs/jls/se21/html/jls-17.html.
3
Java SE 21 API — java.lang.String. docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/String.html.
4
JEP 395 — Records. openjdk.org/jeps/395.
Source confidence: HighLast verified: Primary source: Java SE Documentation · docs.oracle.com/en/java/

Sources

1
JLS §4 — Types, Values, Variables. docs.oracle.com/javase/specs/jls/se21/html/jls-4.html.
2
JLS §17 — Java Memory Model. docs.oracle.com/javase/specs/jls/se21/html/jls-17.html.
3
Java SE 21 API — java.lang.String. docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/String.html.
4
JEP 395 — Records. openjdk.org/jeps/395.