JavaBeginner

Java Fundamentals: Types, Control Flow & First Classes

Build a solid Java foundation: primitive and reference types, variables, conditionals and loops, your first classes and objects, and everyday arrays and collections.

4 sections · ~28 min · 5-question quiz (pass ≥ 70%)

1Types, Variables, and the Java Memory Model (Basics)

Java is statically typed: every variable has a declared type checked at compile time. That catches an entire class of bugs before your code ever runs.

Primitive types store values directly: byte, short, int, long, float, double, char, and boolean. Everything else is a reference type — objects live on the heap, and your variable holds a reference (like a pointer) to them.

int count = 42;              // primitive — stored inline in the stack frame
String name = "Ada";         // reference — name points at a String object on the heap
final double TAX_RATE = 0.08; // final = cannot reassign the binding

Rules of thumb:

  • Use int for whole numbers and double for decimals unless you have a specific reason not to.
  • Prefer final for values that should never change after initialization — it makes intent obvious.
  • String literals are immutable: name.toUpperCase() returns a new String; it does not mutate the original.

2Control Flow: Conditionals, Loops, and switch

Control flow decides which code runs and how often.

if (score >= 90) {
    grade = "A";
} else if (score >= 80) {
    grade = "B";
} else {
    grade = "C";
}

// Enhanced for-loop — preferred for arrays and collections
for (String item : items) {
    System.out.println(item);
}

// Classic counter loop when you need the index
for (int i = 0; i < items.length; i++) {
    process(items[i], i);
}

switch works on primitives, enums, and (since Java 14+) String. Modern switch expressions can return a value:

String label = switch (status) {
    case ACTIVE   -> "Running";
    case PAUSED   -> "On hold";
    case STOPPED  -> "Stopped";
    default       -> "Unknown";
};

Avoid == when comparing Strings — use .equals(). == on objects compares references, not content.

3Classes, Objects, and Methods

Java is object-oriented at its core. A class is a blueprint; an object is a live instance created with new.

public class Employee {
    private final String name;
    private int yearsOfService;

    public Employee(String name) {
        this.name = name;           // constructor runs on new Employee(...)
    }

    public String getName() {
        return name;
    }

    public void promote() {
        yearsOfService++;
    }
}

Employee ada = new Employee("Ada");
ada.promote();

Encapsulation means keeping fields private and exposing behavior through public methods. Callers depend on your API, not your internals — you can refactor fields freely later.

Method overloading lets you define multiple methods with the same name but different parameter lists. The compiler picks the right one at compile time based on argument types.

4Arrays and Collections Basics

Arrays are fixed-size, ordered sequences. Great when size is known upfront:

int[] scores = { 95, 87, 72 };
scores[0] = 96;                    // mutate an element
int len = scores.length;           // note: .length, not .length()

String[] names = new String[3];    // all elements start as null

For dynamic sizing, reach for the Collections Framework. ArrayList is the default list implementation:

import java.util.ArrayList;
import java.util.List;

List<String> tasks = new ArrayList<>();
tasks.add("Write tests");
tasks.add("Ship feature");

for (String task : tasks) {
    System.out.println(task);
}

Rules of thumb:

  • Program to interfaces: declare List<String>, instantiate ArrayList<String>.
  • HashMap<K,V> for key–value lookups; HashSet<T> for unique elements with fast membership checks.
  • Generics (List<String>) give compile-time type safety — no casting needed when you read elements back out.

Ready to test yourself?

Sign in to take the quiz, track progress, and earn a certificate.

Sign in