Control flow, methods and the modern main

Conditionals, the enhanced switch, loops and method design, plus compact source files for scripts and small tools.

Conditionals and the enhanced switch

int score = 87;
String grade = score >= 90 ? "A" : score >= 80 ? "B" : "C";

enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }

String kind = switch (day) {                 // switch expression: it returns a value
    case SAT, SUN -> "weekend";
    case MON, TUE, WED, THU, FRI -> "weekday";
};

String describe(Object o) {                  // pattern matching with a guard
    return switch (o) {
        case null -> "nothing";
        case Integer i when i < 0 -> "negative " + i;
        case Integer i -> "int " + i;
        case String s -> "text of length " + s.length();
        default -> "other";
    };
}
ConstructUse it whenWatch out for
if / else ifA few conditions with different actionsLong chains are a switch waiting to happen
Ternary ?:Choosing one of two valuesNesting more than twice
switch statementA block of side effects per caseFall-through when a break is missing
switch expressionMapping an input to a valueEvery path must yield or throw
Pattern switchDispatching on type or shapeOrder matters — specific cases first
Labelled breakLeaving a nested loopUsually clearer as an extracted method
⚠️
A classic switch statement without break falls through into the next case and runs code you did not intend. The arrow form of switch removes the hazard entirely, so prefer it in all new code.

Loops and method design

for (int i = 0; i < 3; i++) System.out.print(i);
for (String n : names) System.out.print(n);
while (!queue.isEmpty()) process(queue.poll());

names.removeIf(String::isBlank);        // never modify a collection inside a for-each

static int max(int first, int... rest) {   // varargs: last parameter, at most one
    int best = first;
    for (int value : rest) best = Math.max(best, value);
    return best;
}

max(1);
max(1, 2, 3);
  • Java passes primitives by value and object references by value, so reassigning a parameter never affects the caller, but mutating the object does.
  • Overloads are chosen at compile time from the static types, which is why a null argument can bind to an unexpected method.
  • Varargs are an array at run time: passing no arguments gives an empty array, but passing null explicitly does not.
  • Return a value instead of mutating a parameter when you can; it makes the method easier to test and to reason about.
  • Keep methods short enough to read without scrolling, and give one reason to change.

Compact source files and instance main

// Hello.java — a compact source file: no class declaration, no static, no args
void main() {
    String name = IO.readln("Name? ");
    IO.println("Hello, " + name);
}
java Hello.java        # compiles and runs in one step, no build file needed

A compact source file allows top-level methods, gives the file an implicit unnamed class, and makes main instance-based and argument-free. The java.lang.IO convenience API removes the ceremony of System.out and a reader for small tools.

  • The unnamed class cannot be imported from another file; a compact source file is a program, not a library.
  • Add ordinary classes and methods after main in the same file when the program grows a little.
  • Move to a normal package with explicit classes as soon as you need tests, visibility control or reuse.
  • The traditional public static void main(String[] args) still works and is what any framework expects.

FAQ

Is a compact source file suitable for production?
For scripts, internal tools and teaching, yes. For anything with tests, packages or public API surface, use ordinary classes so visibility, imports and build layout stay explicit.
When should I prefer a switch expression over if/else?
Whenever the code maps one input to one result and the set of cases is closed — enums, sealed hierarchies, command strings. The compiler then checks exhaustiveness, so adding a case later surfaces every place that must change.

Setting up a modern Java toolchain Generics, lambdas and the streams API

Last refreshed 2026-09-18.