Java Programming

Complete Guide from Basics to Advanced OOP Concepts

Introduction to Java

Java is a high-level, class-based, object-oriented programming language. It follows the principle "Write Once, Run Anywhere" (WORA).

Key Features

  • Platform Independent: Runs on JVM
  • Object-Oriented: Everything is an object
  • Secure: No explicit pointers, bytecode verification
  • Robust: Strong memory management, exception handling
  • Multithreaded: Built-in support for concurrent programming
Java
// Your first Java program
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
        
        // Taking input
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();
        System.out.println("Welcome, " + name + "!");
    }
}

Variables & Data Types

Java is statically typed - variables must be declared with their type.

Primitive Data Types

TypeSizeRangeExample
byte1 byte-128 to 127byte b = 100;
short2 bytes-32,768 to 32,767short s = 1000;
int4 bytes-2³¹ to 2³¹-1int i = 100000;
long8 bytes-2⁶³ to 2⁶³-1long l = 100000L;
float4 bytes6-7 decimal digitsfloat f = 3.14f;
double8 bytes15 decimal digitsdouble d = 3.14;
char2 bytesUnicode characterchar c = 'A';
boolean1 bittrue/falseboolean b = true;
Java
// Variable declarations
int age = 25;
double salary = 50000.50;
char grade = 'A';
boolean isEmployed = true;
String name = "Alice";  // String is a class, not primitive

// Constants
final double PI = 3.14159;

// Type casting
int x = 10;
double y = x;           // Implicit casting (widening)
int z = (int) 3.14;     // Explicit casting (narrowing)

// Wrapper classes
Integer intObj = Integer.valueOf(10);
int intValue = intObj.intValue();

// Auto-boxing and unboxing (Java 5+)
Integer num = 100;      // Auto-boxing
int val = num;          // Unboxing

Operators

Java
// Arithmetic Operators
int a = 10, b = 3;
System.out.println(a + b);    // 13 - Addition
System.out.println(a - b);    // 7  - Subtraction
System.out.println(a * b);    // 30 - Multiplication
System.out.println(a / b);    // 3  - Division (integer)
System.out.println(a % b);    // 1  - Modulus

// Increment/Decrement
int x = 5;
System.out.println(++x);  // 6 (pre-increment)
System.out.println(x++);  // 6, then x becomes 7 (post-increment)

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

// Logical Operators
boolean p = true, q = false;
System.out.println(p && q);   // false - AND
System.out.println(p || q);   // true  - OR
System.out.println(!p);       // false - NOT

// Bitwise Operators
System.out.println(5 & 3);    // 1 - AND
System.out.println(5 | 3);    // 7 - OR
System.out.println(5 ^ 3);    // 6 - XOR
System.out.println(~5);       // -6 - NOT
System.out.println(5 << 1);   // 10 - Left shift
System.out.println(5 >> 1);   // 2 - Right shift

// Ternary Operator
int max = (a > b) ? a : b;

Control Flow

Java
// if-else
int age = 18;
if (age < 13) {
    System.out.println("Child");
} else if (age < 20) {
    System.out.println("Teenager");
} else {
    System.out.println("Adult");
}

// Switch statement
int day = 3;
switch (day) {
    case 1:
        System.out.println("Monday");
        break;
    case 2:
        System.out.println("Tuesday");
        break;
    default:
        System.out.println("Other day");
}

// Switch expression (Java 14+)
String dayName = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    default -> "Other";
};

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

// Enhanced for loop
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    System.out.println(num);
}

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

// Do-while loop
do {
    System.out.println(count);
    count--;
} while (count > 0);

// Break and Continue
for (int i = 0; i < 10; i++) {
    if (i == 3) continue;  // Skip 3
    if (i == 7) break;     // Stop at 7
    System.out.println(i);
}

Arrays

Java
// Array declaration and initialization
int[] arr1 = new int[5];        // Creates array of size 5
int[] arr2 = {1, 2, 3, 4, 5};   // Array literal
int[] arr3 = new int[]{1, 2, 3};

// Accessing elements
arr1[0] = 10;
System.out.println(arr2[2]);    // 3

// Array length
System.out.println(arr2.length); // 5

// Iterating arrays
for (int i = 0; i < arr2.length; i++) {
    System.out.println(arr2[i]);
}

for (int num : arr2) {
    System.out.println(num);
}

// 2D Arrays
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

System.out.println(matrix[1][2]); // 6

// Arrays utility class
import java.util.Arrays;

int[] nums = {5, 2, 8, 1, 9};
Arrays.sort(nums);                    // Sort
System.out.println(Arrays.toString(nums)); // [1, 2, 5, 8, 9]
int index = Arrays.binarySearch(nums, 5);  // Binary search
Arrays.fill(nums, 0);                 // Fill with value
int[] copy = Arrays.copyOf(nums, 10); // Copy with new size

Object-Oriented Programming

Four Pillars of OOP

  • Encapsulation: Bundling data and methods together
  • Inheritance: Deriving new classes from existing ones
  • Polymorphism: Many forms - overloading and overriding
  • Abstraction: Hiding implementation details
Java
// Class and Object
public class Person {
    // Instance variables (Encapsulation)
    private String name;
    private int age;
    
    // Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Getter and Setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    // Method
    public void greet() {
        System.out.println("Hello, I'm " + name);
    }
    
    // Method overloading (Compile-time polymorphism)
    public void greet(String greeting) {
        System.out.println(greeting + ", I'm " + name);
    }
}

// Inheritance
public class Employee extends Person {
    private double salary;
    
    public Employee(String name, int age, double salary) {
        super(name, age);  // Call parent constructor
        this.salary = salary;
    }
    
    // Method overriding (Runtime polymorphism)
    @Override
    public void greet() {
        System.out.println("Hello, I'm " + getName() + ", an employee");
    }
}

// Abstract class
public abstract class Shape {
    abstract double area();  // Abstract method
    
    public void display() {  // Concrete method
        System.out.println("This is a shape");
    }
}

public class Circle extends Shape {
    private double radius;
    
    @Override
    double area() {
        return Math.PI * radius * radius;
    }
}

// Interface
public interface Drawable {
    void draw();                    // Abstract method
    default void print() {          // Default method (Java 8+)
        System.out.println("Printing...");
    }
    static void info() {            // Static method
        System.out.println("Drawable interface");
    }
}

Strings

Java
// String creation
String s1 = "Hello";              // String literal (String pool)
String s2 = new String("Hello");  // New object

// String methods
String str = "Hello World";
System.out.println(str.length());         // 11
System.out.println(str.charAt(0));        // H
System.out.println(str.substring(0, 5));  // Hello
System.out.println(str.toLowerCase());    // hello world
System.out.println(str.toUpperCase());    // HELLO WORLD
System.out.println(str.trim());           // Remove whitespace
System.out.println(str.replace("o", "0")); // Hell0 W0rld
System.out.println(str.split(" "));       // ["Hello", "World"]
System.out.println(str.contains("World")); // true
System.out.println(str.startsWith("Hello")); // true
System.out.println(str.indexOf("o"));     // 4

// String comparison
String a = "Hello";
String b = "Hello";
System.out.println(a == b);         // true (same pool reference)
System.out.println(a.equals(b));    // true (content comparison)
System.out.println(a.equalsIgnoreCase("HELLO")); // true

// StringBuilder (mutable, not thread-safe)
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" World");
sb.insert(5, ",");
sb.reverse();
String result = sb.toString();

// StringBuffer (mutable, thread-safe)
StringBuffer sbf = new StringBuffer();
sbf.append("Thread").append("-safe");

// String formatting
String formatted = String.format("Name: %s, Age: %d", "Alice", 25);
System.out.printf("Pi: %.2f%n", 3.14159);  // Pi: 3.14

Collections Framework

Java
import java.util.*;

// ArrayList - Dynamic array
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.get(0);           // Apple
list.set(0, "Orange");
list.remove("Banana");
list.size();
list.contains("Orange");

// LinkedList - Doubly linked list
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.addFirst(1);
linkedList.addLast(3);
linkedList.getFirst();
linkedList.removeLast();

// HashSet - Unique elements, no order
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("A");  // Duplicate, ignored
System.out.println(set.size()); // 2

// TreeSet - Sorted unique elements
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(2);
treeSet.add(8);  // Sorted: [2, 5, 8]

// HashMap - Key-value pairs
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
map.get("Alice");      // 25
map.getOrDefault("Charlie", 0);
map.containsKey("Alice");
map.keySet();          // All keys
map.values();          // All values
map.entrySet();        // Key-value pairs

// Iterate HashMap
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// Queue
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);        // Add
queue.poll();          // Remove and return head
queue.peek();          // Return head without removing

// Stack
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.pop();
stack.peek();

Exception Handling

Java
// Basic try-catch
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero!");
}

// Multiple catch blocks
try {
    int[] arr = new int[5];
    arr[10] = 50;
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index error");
} catch (Exception e) {
    System.out.println("General error: " + e.getMessage());
} finally {
    System.out.println("This always executes");
}

// Try-with-resources (Java 7+)
try (FileReader fr = new FileReader("file.txt");
     BufferedReader br = new BufferedReader(fr)) {
    String line = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
}

// Throwing exceptions
public void validateAge(int age) throws IllegalArgumentException {
    if (age < 0) {
        throw new IllegalArgumentException("Age cannot be negative");
    }
}

// Custom exception
public class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

// Exception hierarchy
// Throwable
//   ├── Error (unchecked)
//   └── Exception
//       ├── RuntimeException (unchecked)
//       │   ├── NullPointerException
//       │   ├── ArrayIndexOutOfBoundsException
//       │   └── ArithmeticException
//       └── Checked Exceptions
//           ├── IOException
//           └── SQLException
Interview Tips:
• Know difference between checked and unchecked exceptions
• Use specific exceptions, not generic Exception
• Always close resources (use try-with-resources)
• Don't catch Throwable or Error