Home /Java /Crash Course

Java Course

Java Crash Course

The Essential Reference Guide for Beginners

1. Hello World & Program Structure

Every Java program starts with a class containing a main method — the entry point the JVM calls when you run the program.

public class HelloWorld {

    // The entry point — JVM starts here
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Key Rule

The file name must match the class name exactly — case-sensitive. HelloWorld.java must contain public class HelloWorld.

2. Variables & Data Types

Java is statically typed — you must declare a variable's type before using it.

// Primitive types
int     age     = 25;
double  gpa     = 3.85;
boolean active  = true;
char    grade   = 'A';
long    bigNum  = 9_000_000_000L;   // L suffix for long
float   price   = 9.99f;             // f suffix for float

// Reference type — String is a class, not a primitive
String  name    = "Ayman";

// var — type inferred by compiler (Java 10+)
var     score   = 95;               // inferred as int
var     message = "Hello";           // inferred as String

// Constants — use final
final double PI = 3.14159;

Tip

Use final for values that should never change. By convention, constant names are UPPER_SNAKE_CASE.

3. Operators

// Arithmetic
int a = 10, b = 3;
System.out.println(a + b);    // 13
System.out.println(a - b);    // 7
System.out.println(a * b);    // 30
System.out.println(a / b);    // 3  (integer division)
System.out.println(a % b);    // 1  (remainder)

// Compound assignment
a += 5;   // a = a + 5
a++;      // a = a + 1

// Comparison (returns boolean)
System.out.println(a == b);   // false
System.out.println(a != b);   // true
System.out.println(a >= b);   // true

// Logical
System.out.println(true && false);  // false
System.out.println(true || false);  // true
System.out.println(!true);          // false

// String concatenation
String msg = "Score: " + 95;          // "Score: 95"

4. Control Flow

int score = 85;

// if / else if / else
if (score >= 90) {
    System.out.println("Grade: A");
} else if (score >= 80) {
    System.out.println("Grade: B");    // ← this runs
} else {
    System.out.println("Grade: F");
}

// Ternary operator
String result = (score >= 60) ? "Pass" : "Fail";

// Switch expression (Java 14+)
String letter = switch (score / 10) {
    case 10, 9  -> "A";
    case 8      -> "B";
    case 7      -> "C";
    default     -> "F";
};

Modern Java

The arrow -> switch expression (Java 14+) is cleaner than the old case X: break; pattern — no fall-through bugs.

5. Loops

// for loop
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

// while loop
int count = 0;
while (count < 3) {
    System.out.println("count = " + count);
    count++;
}

// do-while — always executes at least once
do {
    System.out.println("runs once minimum");
} while (false);

// Enhanced for-each loop
int[] nums = {10, 20, 30};
for (int n : nums) {
    System.out.println(n);
}

6. Arrays & ArrayLists

// Fixed-size array
int[] scores = {90, 85, 78, 92};
System.out.println(scores[0]);          // 90
System.out.println(scores.length);       // 4

// Dynamic ArrayList (import required)
import java.util.ArrayList;

ArrayList<String> names = new ArrayList<>();
names.add("Ayman");
names.add("Sara");
names.add("Ali");

System.out.println(names.get(0));        // "Ayman"
System.out.println(names.size());        // 3
names.remove("Sara");
System.out.println(names.contains("Ali")); // true

// Iterate with for-each
for (String name : names) {
    System.out.println(name);
}

Tip

Use arrays when size is fixed and performance is critical. Use ArrayList when you need to add/remove items dynamically.

7. Methods

public class MathUtils {

    // Static method — call without creating an object
    public static int add(int a, int b) {
        return a + b;
    }

    // Method overloading — same name, different parameters
    public static double add(double a, double b) {
        return a + b;
    }

    // Varargs — variable number of arguments
    public static int sum(int... nums) {
        int total = 0;
        for (int n : nums) total += n;
        return total;
    }

    public static void main(String[] args) {
        System.out.println(add(3, 4));           // 7
        System.out.println(add(1.5, 2.5));       // 4.0
        System.out.println(sum(1, 2, 3, 4));     // 10
    }
}

8. OOP & Classes

public class Student {

    // Instance fields — private for encapsulation
    private String name;
    private int    grade;

    // Constructor
    public Student(String name, int grade) {
        this.name  = name;
        this.grade = grade;
    }

    // Getter
    public String getName()  { return name;  }
    public int    getGrade() { return grade; }

    // Instance method
    public String letterGrade() {
        return switch (grade / 10) {
            case 10, 9  -> "A";
            case 8      -> "B";
            case 7      -> "C";
            default     -> "F";
        };
    }

    // toString — called automatically by println
    @Override
    public String toString() {
        return name + " → " + letterGrade() + " (" + grade + ")";
    }
}

// Usage
Student s = new Student("Ayman", 92);
System.out.println(s);          // Ayman → A (92)
System.out.println(s.getName()); // Ayman

9. Inheritance & Polymorphism

// Parent class
public class Animal {
    protected String name;

    public Animal(String name) { this.name = name; }

    public String speak() { return "..."; }

    @Override
    public String toString() { return name; }
}

// Child class — extends inherits all parent members
public class Dog extends Animal {
    public Dog(String name) { super(name); }  // call parent constructor

    @Override
    public String speak() { return "Woof!"; }
}

public class Cat extends Animal {
    public Cat(String name) { super(name); }

    @Override
    public String speak() { return "Meow!"; }
}

// Polymorphism — same type, different behaviour
Animal[] animals = { new Dog("Rex"), new Cat("Luna") };
for (Animal a : animals) {
    System.out.println(a + ": " + a.speak());
}
// Rex: Woof!
// Luna: Meow!

10. Interfaces

An interface defines a contract — a set of methods a class promises to implement. A class can implement multiple interfaces.

// Define an interface
public interface Printable {
    void print();   // implicitly public abstract
}

public interface Saveable {
    boolean save(String path);
}

// Implement multiple interfaces
public class Document implements Printable, Saveable {
    private String content;

    public Document(String content) { this.content = content; }

    @Override
    public void print() {
        System.out.println(content);
    }

    @Override
    public boolean save(String path) {
        System.out.println("Saving to: " + path);
        return true;
    }
}

Interface vs Abstract Class

Use an interface when unrelated classes share behaviour (e.g. both Dog and Document can be Printable). Use an abstract class when related classes share code and state.

11. Exception Handling

// try-catch-finally
try {
    int result = 10 / 0;              // throws ArithmeticException
} catch (ArithmeticException e) {
    System.out.println("Error: " + e.getMessage());
} finally {
    System.out.println("Always runs");
}

// Multiple catch blocks
try {
    String s = null;
    s.length();                       // NullPointerException
} catch (NullPointerException e) {
    System.out.println("Null value!");
} catch (Exception e) {
    System.out.println("General error: " + e);
}

// Custom exception
public class InvalidGradeException extends RuntimeException {
    public InvalidGradeException(int grade) {
        super("Invalid grade: " + grade);
    }
}

// Throw it
if (grade < 0 || grade > 100) {
    throw new InvalidGradeException(grade);
}

Warning

Never catch Exception or Throwable as a general catch-all in production — you'll swallow errors silently. Catch the most specific exception type possible.

12. Generics

Generics let you write type-safe code that works with any data type, eliminating the need for casting and catching ClassCastException at runtime.

// Generic class — T is a type parameter
public class Box<T> {
    private T value;

    public Box(T value) { this.value = value; }
    public T getValue()  { return value; }

    @Override
    public String toString() { return "Box[" + value + "]"; }
}

// Usage — compiler enforces types
Box<String> sBox = new Box<>("Hello");
Box<Integer> iBox = new Box<>(42);
System.out.println(sBox);   // Box[Hello]
System.out.println(iBox);   // Box[42]

// Generic method
public static <T extends Comparable<T>> T max(T a, T b) {
    return (a.compareTo(b) >= 0) ? a : b;
}

System.out.println(max(10, 20));         // 20
System.out.println(max("apple", "mango")); // mango