Introduction to Java
Java is a high-level, object-oriented programming language developed by Sun Microsystems in 1995 (now owned by Oracle). It follows the Write Once, Run Anywhere (WORA) principle — code compiled to bytecode runs on any platform with a JVM.
Why Learn Java?
- Most popular language for enterprise backend development
- Powers Android apps, Spring Boot APIs, and big-data tools
- Strong type system catches bugs at compile time
- Massive ecosystem — Maven, Gradle, Spring, Hibernate
Key Components
- JDK — Java Development Kit (compiler + tools)
- JRE — Java Runtime Environment (runs bytecode)
- JVM — Java Virtual Machine (executes on the host OS)
Setup & Installation
Install the JDK and set up your development environment before writing your first line of Java.
Step 1 — Download JDK 21
Go to adoptium.net and download the Temurin JDK 21 for your OS. It's free and open source.
Step 2 — Verify Installation
javac -version
Step 3 — Choose an IDE
- IntelliJ IDEA — best-in-class for Java (Community edition is free)
- Eclipse — classic, used widely in enterprise
- VS Code — lightweight with Java Extension Pack
Hello World
Every Java program starts with a class. The entry point is the main method.
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
To Run
java HelloWorld
java HelloWorld.javaVariables & Data Types
Java is statically typed — every variable has a declared type that cannot change.
Primitive Types
long population = 8_000_000_000L;
double price = 99.99;
boolean isActive = true;
char grade = 'A';
byte level = 5;
short code = 1234;
float temp = 36.6f;
Reference Types
int[] scores = {90, 85, 92};
Object obj = null;
var (Java 10+)
var count = 42; // inferred as int
Operators
Arithmetic
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 (modulus)
Comparison & Logical
(a > 5) && (b < 5); // AND
(a > 5) || (b > 5); // OR
!(a == b); // NOT
Ternary
Control Flow
if / else
System.out.println("A");
} else if (score >= 75) {
System.out.println("B");
} else {
System.out.println("C");
}
switch (Java 14+ enhanced)
String type = switch (day) {
case "SAT", "SUN" -> "Weekend";
default -> "Weekday";
};
Loops
for (int i = 0; i < 5; i++) { System.out.println(i); }
// while
int n = 0;
while (n < 5) { System.out.println(n++); }
// for-each
int[] nums = {1, 2, 3};
for (int x : nums) { System.out.println(x); }
Arrays
Arrays in Java are fixed-size, zero-indexed, and hold elements of the same type.
int[] scores = {90, 85, 92, 78}; // initializer
scores[0] = 95; // update element
System.out.println(scores.length); // 4
2D Arrays
System.out.println(matrix[1][2]); // 6
Arrays Utility
Arrays.sort(scores);
System.out.println(Arrays.toString(scores));
Strings
Strings in Java are immutable objects of the String class.
s.length() // 11
s.toUpperCase() // "HELLO, JAVA"
s.substring(7) // "Java"
s.contains("Java") // true
s.replace("Java", "World") // "Hello, World"
s.split(", ") // ["Hello", "Java"]
s.trim() // removes leading/trailing spaces
String Comparison
s.equalsIgnoreCase("hello, java") // true
s == "Hello, Java" // may be false — avoid!
StringBuilder (mutable)
sb.append("Hello").append(" Java");
System.out.println(sb.toString()); // "Hello Java"
Classes & Objects
A class is a blueprint; an object is an instance of that class.
private String name;
private int age;
// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String greet() {
return "Hi, I'm " + name;
}
}
// Usage
Person p = new Person("Aftab", 30);
System.out.println(p.greet());
Inheritance
Inheritance lets a child class reuse code from a parent class using extends.
public void eat() { System.out.println("eating"); }
}
public class Dog extends Animal {
public void bark() { System.out.println("woof!"); }
}
Dog d = new Dog();
d.eat(); // inherited
d.bark(); // own method
Polymorphism
Polymorphism means "many forms." A parent reference can hold a child object and call overridden methods.
public String draw() { return "shape"; }
}
class Circle extends Shape {
@Override public String draw() { return "circle"; }
}
class Square extends Shape {
@Override public String draw() { return "square"; }
}
Shape s = new Circle();
System.out.println(s.draw()); // "circle" — runtime dispatch
Interfaces & Abstract Classes
void fly(); // implicitly public abstract
default void land() { System.out.println("landing"); }
}
class Bird implements Flyable {
@Override public void fly() { System.out.println("flap flap"); }
}
Abstract Class
abstract void move();
void stop() { System.out.println("stopped"); }
}
Encapsulation
Hide internal state behind private fields and expose it through public getters/setters.
private double balance;
public double getBalance() { return balance; }
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
}
Collections Framework
List
names.add("Alice"); names.add("Bob");
names.get(0); // "Alice"
names.size(); // 2
names.remove("Bob");
Map
scores.put("Alice", 95);
scores.get("Alice"); // 95
scores.containsKey("Bob"); // false
Set
// {1, 2, 3} — duplicates removed
Generics
Generics let you write type-safe code that works for any type without casting.
private T value;
public Box(T value) { this.value = value; }
public T get() { return value; }
}
Box<String> strBox = new Box<>("hello");
Box<Integer> intBox = new Box<>(42);
Exception Handling
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("always runs");
}
Custom Exception
public InsufficientFundsException(String msg) { super(msg); }
}
Streams & Lambda (Java 8+)
Streams allow functional-style operations on collections — filter, map, reduce — without loops.
// filter evens, square them, collect
List<Integer> result = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
// [4, 16, 36]
Common Stream Operations
nums.stream().count(); // 6
nums.stream().anyMatch(n -> n > 5); // true
nums.stream().sorted().toList(); // [1,2,3,4,5,6]
Multithreading
Creating Threads
Thread t = new Thread(() -> {
System.out.println("Running in thread: " + Thread.currentThread().getName());
});
t.start();
ExecutorService
pool.submit(() -> System.out.println("task 1"));
pool.submit(() -> System.out.println("task 2"));
pool.shutdown();
synchronized
count++; // thread-safe
}
java.util.concurrent classes (AtomicInteger, ConcurrentHashMap, ExecutorService) over raw synchronized for most use cases.