Learn in 10 minutes

Learn in 10 minutes

Learn Java in 10 minutes

Java is a high-level, object-oriented programming language known for its “write once, run anywhere” principle. This tutorial covers Java 21+ features, helping you quickly learn Java fundamentals.

1. Writing Your First Java Program

Java programs are organized into classes. Let’s start with a simple program. Create a file named HelloWorld.java:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Compile and run the program:

javac HelloWorld.java
java HelloWorld

The output will be:

Hello, World!

This simple program demonstrates Java’s basic structure. Every Java program must have at least one class, and the main method is the entry point.

2. Basic Syntax

Java syntax is structured and follows specific rules:

// This is a single-line comment
/* This is a 
   multi-line comment */

public class BasicSyntax {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

Basic syntax rules in Java:

  • Case Sensitivity: Java is case-sensitive. Variable and variable are different.
  • Class Names: Should start with an uppercase letter and follow CamelCase convention.
  • Method Names: Should start with a lowercase letter and follow camelCase convention.
  • Semicolons: Every statement must end with a semicolon ;.
  • Braces: Code blocks are defined using curly braces {}.
  • Comments: Single-line comments use //, multi-line comments use /* */.

3. Variables and Data Types

Java is a statically typed language, meaning you must declare variable types explicitly.

Variable naming rules:

  • Must start with a letter, underscore _, or dollar sign $.
  • Can contain letters, digits, underscores, and dollar signs.
  • Cannot be Java keywords.
  • Should follow camelCase convention.

Java’s primitive data types:

  • byte: 8-bit signed integer (-128 to 127)
  • short: 16-bit signed integer (-32,768 to 32,767)
  • int: 32-bit signed integer (-2^31 to 2^31-1)
  • long: 64-bit signed integer (-2^63 to 2^63-1)
  • float: 32-bit floating point
  • double: 64-bit floating point
  • boolean: true or false
  • char: 16-bit Unicode character
public class DataTypes {
    public static void main(String[] args) {
        // Integer types
        byte age = 25;
        short year = 2024;
        int population = 1000000;
        long distance = 93000000L; // L suffix for long
        
        // Floating point types
        float temperature = 36.5f; // f suffix for float
        double pi = 3.14159265359;
        
        // Boolean and character
        boolean isActive = true;
        char grade = 'A';
        
        // String (reference type)
        String name = "Alice";
        
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

3.1 String Operations

Strings in Java are objects, not primitive types:

public class StringExample {
    public static void main(String[] args) {
        String text = "Java Programming";
        
        System.out.println("Length: " + text.length());
        System.out.println("Uppercase: " + text.toUpperCase());
        System.out.println("Lowercase: " + text.toLowerCase());
        System.out.println("Character at index 0: " + text.charAt(0));
        System.out.println("Substring: " + text.substring(0, 4));
        System.out.println("Contains 'Java': " + text.contains("Java"));
        
        // String concatenation
        String greeting = "Hello, " + "World!";
        System.out.println(greeting);
        
        // String formatting
        String formatted = String.format("Pi is approximately %.2f", 3.14159);
        System.out.println(formatted);
    }
}

4. Arrays and Collections

4.1 Arrays

Arrays store multiple values of the same type:

public class ArrayExample {
    public static void main(String[] args) {
        // Array declaration and initialization
        int[] numbers = {1, 2, 3, 4, 5};
        String[] fruits = new String[3];
        fruits[0] = "apple";
        fruits[1] = "banana";
        fruits[2] = "orange";
        
        // Accessing array elements
        System.out.println("First number: " + numbers[0]);
        System.out.println("Array length: " + numbers.length);
        
        // Iterating through arrays
        for (int i = 0; i < numbers.length; i++) {
            System.out.println("Number " + i + ": " + numbers[i]);
        }
        
        // Enhanced for loop (for-each)
        for (String fruit : fruits) {
            System.out.println("Fruit: " + fruit);
        }
        
        // Multi-dimensional arrays
        int[][] matrix = {{1, 2}, {3, 4}, {5, 6}};
        System.out.println("Matrix element [1][1]: " + matrix[1][1]);
    }
}

4.2 Collections

Java Collections Framework provides dynamic data structures:

import java.util.*;

public class CollectionsExample {
    public static void main(String[] args) {
        // ArrayList (dynamic array)
        ArrayList<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.remove("Bob");
        System.out.println("Names: " + names);
        
        // HashMap (key-value pairs)
        HashMap<String, Integer> ages = new HashMap<>();
        ages.put("Alice", 25);
        ages.put("Bob", 30);
        ages.put("Charlie", 35);
        System.out.println("Alice's age: " + ages.get("Alice"));
        
        // HashSet (unique elements)
        HashSet<Integer> uniqueNumbers = new HashSet<>();
        uniqueNumbers.add(1);
        uniqueNumbers.add(2);
        uniqueNumbers.add(2); // Duplicate, won't be added
        uniqueNumbers.add(3);
        System.out.println("Unique numbers: " + uniqueNumbers);
        
        // Iterating through collections
        for (String name : names) {
            System.out.println("Name: " + name);
        }
        
        for (Map.Entry<String, Integer> entry : ages.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

5. Operations and Operators

Java provides various operators for different operations:

  • Arithmetic Operators: +, -, *, /, % (modulus), ++ (increment), -- (decrement)
  • Comparison Operators: ==, !=, >, <, >=, <=
  • Logical Operators: && (and), || (or), ! (not)
  • Bitwise Operators: &, |, ^, ~, <<, >>, >>>
  • Assignment Operators: =, +=, -=, *=, /=, %=
public class OperatorsExample {
    public static void main(String[] args) {
        int a = 10, b = 3;
        
        // Arithmetic operations
        System.out.println("Addition: " + (a + b));
        System.out.println("Subtraction: " + (a - b));
        System.out.println("Multiplication: " + (a * b));
        System.out.println("Division: " + (a / b));
        System.out.println("Modulus: " + (a % b));
        
        // Increment and decrement
        System.out.println("Pre-increment: " + (++a));
        System.out.println("Post-decrement: " + (b--));
        
        // Comparison operations
        System.out.println("Equal: " + (a == b));
        System.out.println("Not equal: " + (a != b));
        System.out.println("Greater than: " + (a > b));
        
        // Logical operations
        boolean x = true, y = false;
        System.out.println("AND: " + (x && y));
        System.out.println("OR: " + (x || y));
        System.out.println("NOT: " + (!x));
        
        // Assignment operations
        int c = 5;
        c += 3; // c = c + 3
        System.out.println("After += 3: " + c);
    }
}

6. Control Flow

6.1 Conditional Statements

public class ConditionalExample {
    public static void main(String[] args) {
        int score = 85;
        
        // if-else statement
        if (score >= 90) {
            System.out.println("Grade: A");
        } else if (score >= 80) {
            System.out.println("Grade: B");
        } else if (score >= 70) {
            System.out.println("Grade: C");
        } else {
            System.out.println("Grade: F");
        }
        
        // Ternary operator
        String result = (score >= 60) ? "Pass" : "Fail";
        System.out.println("Result: " + result);
        
        // switch statement
        char grade = 'B';
        switch (grade) {
            case 'A':
                System.out.println("Excellent!");
                break;
            case 'B':
                System.out.println("Good!");
                break;
            case 'C':
                System.out.println("Average");
                break;
            default:
                System.out.println("Invalid grade");
        }
    }
}

6.2 Loops

public class LoopExample {
    public static void main(String[] args) {
        // for loop
        System.out.println("For loop:");
        for (int i = 0; i < 5; i++) {
            System.out.println("Iteration: " + i);
        }
        
        // Enhanced for loop (for-each)
        System.out.println("\nFor-each loop:");
        int[] numbers = {1, 2, 3, 4, 5};
        for (int num : numbers) {
            System.out.println("Number: " + num);
        }
        
        // while loop
        System.out.println("\nWhile loop:");
        int count = 0;
        while (count < 3) {
            System.out.println("Count: " + count);
            count++;
        }
        
        // do-while loop
        System.out.println("\nDo-while loop:");
        int x = 0;
        do {
            System.out.println("X: " + x);
            x++;
        } while (x < 3);
        
        // break and continue
        System.out.println("\nBreak and continue:");
        for (int i = 0; i < 10; i++) {
            if (i == 5) {
                break; // Exit the loop
            }
            if (i % 2 == 0) {
                continue; // Skip even numbers
            }
            System.out.println("Odd number: " + i);
        }
    }
}

7. Methods (Functions)

Methods in Java are functions that belong to classes:

public class MethodExample {
    
    // Method with no parameters and no return value
    public static void greet() {
        System.out.println("Hello, World!");
    }
    
    // Method with parameters and return value
    public static int add(int a, int b) {
        return a + b;
    }
    
    // Method with multiple parameters
    public static String formatName(String firstName, String lastName) {
        return firstName + " " + lastName;
    }
    
    // Method overloading (same name, different parameters)
    public static int multiply(int a, int b) {
        return a * b;
    }
    
    public static double multiply(double a, double b) {
        return a * b;
    }
    
    // Variable arguments (varargs)
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    public static void main(String[] args) {
        greet();
        
        int result = add(5, 3);
        System.out.println("Addition result: " + result);
        
        String fullName = formatName("John", "Doe");
        System.out.println("Full name: " + fullName);
        
        System.out.println("Multiply integers: " + multiply(4, 5));
        System.out.println("Multiply doubles: " + multiply(2.5, 3.0));
        
        System.out.println("Sum of multiple numbers: " + sum(1, 2, 3, 4, 5));
    }
}

8. Object-Oriented Programming

8.1 Classes and Objects

public class Person {
    // Instance variables (fields)
    private String name;
    private int age;
    private String email;
    
    // Constructor
    public Person(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    // Default constructor
    public Person() {
        this("Unknown", 0, "");
    }
    
    // Getter methods
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public String getEmail() {
        return email;
    }
    
    // Setter methods
    public void setName(String name) {
        this.name = name;
    }
    
    public void setAge(int age) {
        if (age >= 0) {
            this.age = age;
        }
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
    
    // Instance method
    public void introduce() {
        System.out.println("Hi, I'm " + name + ", " + age + " years old.");
    }
    
    // Method with logic
    public boolean isAdult() {
        return age >= 18;
    }
    
    // toString method (overriding Object's toString)
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", email='" + email + "'}";
    }
    
    public static void main(String[] args) {
        // Creating objects
        Person person1 = new Person("Alice", 25, "[email protected]");
        Person person2 = new Person();
        
        // Using methods
        person1.introduce();
        System.out.println("Is adult: " + person1.isAdult());
        
        person2.setName("Bob");
        person2.setAge(17);
        person2.setEmail("[email protected]");
        
        System.out.println(person1.toString());
        System.out.println(person2.toString());
    }
}

8.2 Inheritance

// Base class
class Animal {
    protected String name;
    protected String species;
    
    public Animal(String name, String species) {
        this.name = name;
        this.species = species;
    }
    
    public void eat() {
        System.out.println(name + " is eating.");
    }
    
    public void sleep() {
        System.out.println(name + " is sleeping.");
    }
    
    public void makeSound() {
        System.out.println(name + " makes a sound.");
    }
}

// Derived class
class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name, "Dog"); // Call parent constructor
        this.breed = breed;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " barks: Woof! Woof!");
    }
    
    public void fetch() {
        System.out.println(name + " fetches the ball.");
    }
    
    public String getBreed() {
        return breed;
    }
}

// Another derived class
class Cat extends Animal {
    private String color;
    
    public Cat(String name, String color) {
        super(name, "Cat");
        this.color = color;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " meows: Meow! Meow!");
    }
    
    public void climb() {
        System.out.println(name + " climbs a tree.");
    }
    
    public String getColor() {
        return color;
    }
}

public class InheritanceExample {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", "Golden Retriever");
        Cat cat = new Cat("Whiskers", "Orange");
        
        // Using inherited methods
        dog.eat();
        dog.sleep();
        dog.makeSound(); // Overridden method
        dog.fetch(); // Dog-specific method
        
        cat.eat();
        cat.makeSound(); // Overridden method
        cat.climb(); // Cat-specific method
        
        System.out.println("Dog breed: " + dog.getBreed());
        System.out.println("Cat color: " + cat.getColor());
    }
}

8.3 Interfaces and Abstract Classes

// Interface
interface Drawable {
    void draw(); // Abstract method (implicitly public abstract)
    
    // Default method (Java 8+)
    default void print() {
        System.out.println("Printing the shape...");
    }
    
    // Static method (Java 8+)
    static void info() {
        System.out.println("This is a drawable interface.");
    }
}

// Abstract class
abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Abstract method
    public abstract double getArea();
    
    // Concrete method
    public void setColor(String color) {
        this.color = color;
    }
    
    public String getColor() {
        return color;
    }
}

// Concrete class implementing interface and extending abstract class
class Circle extends Shape implements Drawable {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " circle with radius " + radius);
    }
}

class Rectangle extends Shape implements Drawable {
    private double width;
    private double height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " rectangle " + width + "x" + height);
    }
}

public class AbstractExample {
    public static void main(String[] args) {
        Circle circle = new Circle("Red", 5.0);
        Rectangle rectangle = new Rectangle("Blue", 4.0, 6.0);
        
        // Using implemented methods
        circle.draw();
        circle.print(); // Default method from interface
        System.out.println("Circle area: " + circle.getArea());
        
        rectangle.draw();
        rectangle.print();
        System.out.println("Rectangle area: " + rectangle.getArea());
        
        // Using static method from interface
        Drawable.info();
        
        // Polymorphism
        Shape[] shapes = {circle, rectangle};
        for (Shape shape : shapes) {
            System.out.println("Shape area: " + shape.getArea());
        }
    }
}

9. Exception Handling

Exception handling in Java uses try-catch-finally blocks:

import java.io.*;
import java.util.Scanner;

public class ExceptionExample {
    
    public static void demonstrateBasicExceptions() {
        // Try-catch block
        try {
            int result = 10 / 0; // This will throw ArithmeticException
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero: " + e.getMessage());
        }
        
        // Multiple catch blocks
        try {
            String str = null;
            int length = str.length(); // NullPointerException
        } catch (NullPointerException e) {
            System.out.println("Null pointer exception: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("General exception: " + e.getMessage());
        }
        
        // Try-catch-finally
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[5]); // ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index out of bounds: " + e.getMessage());
        } finally {
            System.out.println("This always executes");
        }
    }
    
    // Method that throws an exception
    public static void checkAge(int age) throws IllegalArgumentException {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
        if (age > 150) {
            throw new IllegalArgumentException("Age cannot exceed 150");
        }
        System.out.println("Valid age: " + age);
    }
    
    // Custom exception class
    static class CustomException extends Exception {
        public CustomException(String message) {
            super(message);
        }
    }
    
    public static void demonstrateCustomException() throws CustomException {
        boolean errorCondition = true;
        if (errorCondition) {
            throw new CustomException("This is a custom exception");
        }
    }
    
    public static void main(String[] args) {
        demonstrateBasicExceptions();
        
        // Handling thrown exceptions
        try {
            checkAge(-5);
        } catch (IllegalArgumentException e) {
            System.out.println("Age validation error: " + e.getMessage());
        }
        
        // Try-with-resources (Java 7+)
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.println("Scanner will be automatically closed");
        }
        
        // Handling custom exceptions
        try {
            demonstrateCustomException();
        } catch (CustomException e) {
            System.out.println("Custom exception caught: " + e.getMessage());
        }
    }
}

10. Input and Output

10.1 Console Input/Output

import java.util.Scanner;

public class InputOutputExample {
    public static void main(String[] args) {
        // Output to console
        System.out.println("Hello, World!");
        System.out.print("This is on the same line. ");
        System.out.printf("Formatted output: %d, %.2f, %s%n", 42, 3.14159, "Java");
        
        // Input from console
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();
        
        System.out.print("Enter your age: ");
        int age = scanner.nextInt();
        
        System.out.print("Enter your salary: ");
        double salary = scanner.nextDouble();
        
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("Salary: $" + salary);
        
        scanner.close();
    }
}

10.2 File I/O

import java.io.*;
import java.nio.file.*;
import java.util.List;

public class FileIOExample {
    public static void main(String[] args) {
        String fileName = "example.txt";
        
        // Writing to file
        try (FileWriter writer = new FileWriter(fileName)) {
            writer.write("Hello, Java File I/O!\n");
            writer.write("This is line 2.\n");
            writer.write("This is line 3.\n");
            System.out.println("File written successfully.");
        } catch (IOException e) {
            System.out.println("Error writing file: " + e.getMessage());
        }
        
        // Reading from file
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            System.out.println("File contents:");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
        
        // Using NIO.2 (Java 7+)
        try {
            // Write all lines at once
            List<String> lines = List.of("Line 1", "Line 2", "Line 3");
            Files.write(Paths.get("nio-example.txt"), lines);
            
            // Read all lines at once
            List<String> readLines = Files.readAllLines(Paths.get("nio-example.txt"));
            System.out.println("NIO.2 file contents:");
            readLines.forEach(System.out::println);
            
        } catch (IOException e) {
            System.out.println("NIO.2 error: " + e.getMessage());
        }
    }
}

11. Advanced Features

11.1 Generics

import java.util.*;

// Generic class
class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

// Generic method
class Utility {
    public static <T> void swap(T[] array, int i, int j) {
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    
    public static <T extends Comparable<T>> T findMax(T[] array) {
        T max = array[0];
        for (T item : array) {
            if (item.compareTo(max) > 0) {
                max = item;
            }
        }
        return max;
    }
}

public class GenericsExample {
    public static void main(String[] args) {
        // Using generic class
        Box<String> stringBox = new Box<>();
        stringBox.set("Hello, Generics!");
        System.out.println("String box: " + stringBox.get());
        
        Box<Integer> intBox = new Box<>();
        intBox.set(42);
        System.out.println("Integer box: " + intBox.get());
        
        // Using generic collections
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        
        // Using generic method
        String[] fruits = {"apple", "banana", "orange"};
        System.out.println("Before swap: " + Arrays.toString(fruits));
        Utility.swap(fruits, 0, 2);
        System.out.println("After swap: " + Arrays.toString(fruits));
        
        Integer[] numbers = {5, 2, 8, 1, 9};
        Integer max = Utility.findMax(numbers);
        System.out.println("Max number: " + max);
    }
}

11.2 Lambda Expressions and Streams (Java 8+)

import java.util.*;
import java.util.stream.*;

public class LambdaStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // Lambda expressions
        System.out.println("Original numbers: " + numbers);
        
        // Filter even numbers
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
        System.out.println("Even numbers: " + evenNumbers);
        
        // Map to squares
        List<Integer> squares = numbers.stream()
            .map(n -> n * n)
            .collect(Collectors.toList());
        System.out.println("Squares: " + squares);
        
        // Sum of all numbers
        int sum = numbers.stream()
            .mapToInt(Integer::intValue)
            .sum();
        System.out.println("Sum: " + sum);
        
        // Find maximum
        Optional<Integer> max = numbers.stream()
            .max(Integer::compareTo);
        System.out.println("Maximum: " + max.orElse(0));
        
        // Complex stream operations
        List<String> words = Arrays.asList("java", "stream", "lambda", "functional", "programming");
        
        String result = words.stream()
            .filter(word -> word.length() > 4)
            .map(String::toUpperCase)
            .sorted()
            .collect(Collectors.joining(", "));
        System.out.println("Processed words: " + result);
        
        // Parallel streams
        long count = numbers.parallelStream()
            .filter(n -> n > 5)
            .count();
        System.out.println("Numbers greater than 5: " + count);
    }
}

This comprehensive Java tutorial covers the essential concepts needed to get started with Java programming. The language’s strong typing, object-oriented features, and extensive standard library make it powerful for building robust applications. Practice these examples and experiment with the code to deepen your understanding of Java programming concepts.