HakiDocs
Java

Compiler Time Constants

Checks happening at Compile Time

Imagine the Compiler as a.
super-smart cashier 🧠.
checking a pre-calculated bill.

Normally, if you add two small items.
(byte + byte), the cashier (the JVM)
is instructed to put the result into a larger tray (int)
to prevent spillage (overflow).
So, byte b3 = b1 + b2; -> fails because the result is an int.

The Exception with Compile-Time Constant

When all the numbers in.
an arithmetic expression.
are fixed, known values.
(literals like 10 or 50),
the Compiler says, "Wait, I don't need the JVM for this; I can do the math myself right now."

If the math works:
The compiler calculates 10 + 50 = 60.
Since 60 fits within the target byte's range (−128 to 127),
the compiler simply places the final value (60)
directly into the byte variable.
No explicit cast is needed..

If the math overflows

If the expression was 100 + 50 = 150, the compiler would see that 150 is outside the byte range and immediately throw a compile-time error, saving the JVM the trouble.

[[Compiler VS Runtime Error]]

The core idea is that.
the check happens
entirely at compile time,
making the code safer and
more concise than if it
were calculated at runtime.

public class CompileTimeConstantTest {

    // Helper method to demonstrate the final output
    public static void main(String[] args) {
        System.out.println("--- 1. Success with Constant Expressions ---");
        successExamples();
        
        System.out.println("\n--- 2. Overflow Traps (Compile-Time Errors) ---");
        overflowExamples();
        
        System.out.println("\n--- 3. Non-Constant Traps (Compile-Time Errors) ---");
        nonConstantTraps();
    }

    // 1. Examples that compile due to constant folding
    public static void successExamples() {
        // RULE: Constant expression is evaluated at compile time.
        // Result (120) fits in byte (max 127). No cast needed.
        byte b1 = 50 + 70;
        System.out.println("1a. b1 (50+70): " + b1 + " (Compiles OK)");

        // RULE: The 'final' keyword makes an initialized variable a compile-time constant.
        final int MAX_VAL = 100;
        final byte OFFSET = 27;
        // MAX_VAL + OFFSET (127) is a constant expression and fits in byte.
        byte b2 = MAX_VAL + OFFSET; 
        System.out.println("1b. b2 (final + final): " + b2 + " (Compiles OK)");

        // Result (32767) fits in short (max 32767).
        short s1 = 30000 + 2767;
        System.out.println("1c. s1: " + s1 + " (Compiles OK)");
    }

    // 2. Examples that fail due to Constant Overflow
    public static void overflowExamples() {
        // The compiler evaluates 100 + 50 to 150.
        // 150 is outside the byte range [-128 to 127].
        // byte b3 = 100 + 50; // COMPILE ERROR: Incompatible types. Lossy conversion from int to byte.

        // The compiler evaluates 32000 + 1000 to 33000.
        // 33000 is outside the short range [-32768 to 32767].
        // short s2 = 32000 + 1000; // COMPILE ERROR: Incompatible types. Lossy conversion from int to short.

        System.out.println("2a & 2b. Compile Errors (commented out in code).");
    }

    // 3. Examples that fail due to Arithmetic Promotion (Not a Constant)
    public static void nonConstantTraps() {
        byte a = 10; // Not a compile-time constant (can change)
        byte b = 20; // Not a compile-time constant (can change)

        // RULE: 'a + b' is evaluated at runtime, promoting 'a' and 'b' to 'int'.
        // The result is an 'int' (30). Cannot assign 'int' to 'byte'.
        // byte c = a + b; // COMPILE ERROR: Incompatible types. Lossy conversion from int to byte.

        // FIX: The only way to make this work is to explicitly cast the result back to byte.
        byte c_fixed = (byte)(a + b);
        System.out.println("3a. c_fixed (with cast): " + c_fixed + " (Compiles OK)");

        // OCA TRAP: Even if the result is small, the promotion rule still applies!
        byte x = 5;
        // byte y = x + 1; // COMPILE ERROR: x is not final, so x + 1 is int.
        System.out.println("3b. Compile Error (commented out in code).");
    }
}

🦕 Sources