Java is statically typed — every variable must have a declared type at compile time.
int age = 25; // 32-bit integer
long bigNum = 123456L; // 64-bit integer
double pi = 3.14159; // 64-bit float
float f = 3.14f; // 32-bit float
boolean flag = true; // true / false
char letter = 'A'; // single character
String name = "Alice"; // text (object)
final int MAX = 100; // constant
var x = 42; // type inference (Java 10+)
Tip: Use int for whole numbers, double for decimals, String for text.
String is immutable — every modification creates a new object. Use StringBuilder for repeated concatenation.
String s = "Hello, World!";
s.length() // 13
s.toUpperCase() // "HELLO, WORLD!"
s.substring(0, 5) // "Hello"
s.contains("World") // true
s.replace("World","Java")
s.trim() // removes whitespace
s.split(",") // ["Hello", " World!"]
s.charAt(0) // 'H'
s.equals("hi") // compare (never use ==)
String.valueOf(42) // "42"
String.format("Hi %s, age %d", name, age)
// Mutable string
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" World");
String result = sb.toString();
Java supports if/else, switch (classic & enhanced), for, while, and do-while.
// if-else
if (x > 0) { System.out.println("Positive"); }
else if (x < 0) { System.out.println("Negative"); }
else { System.out.println("Zero"); }
// Enhanced switch (Java 14+)
switch (day) {
case "MON" -> System.out.println("Monday");
case "TUE" -> System.out.println("Tuesday");
default -> System.out.println("Other");
}
// for loop
for (int i = 0; i < 5; i++) { System.out.println(i); }
// enhanced for-each
int[] nums = {1, 2, 3, 4, 5};
for (int n : nums) { System.out.println(n); }
// while
int i = 0;
while (i < 5) { i++; }
// Ternary
String result = (x > 0) ? "positive" : "non-positive";
A class is a blueprint; an object is an instance. Java enforces encapsulation with access modifiers.
public class Animal {
private String name; // private field
private int age;
// Constructor
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// Getter / Setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// Method
public void speak() {
System.out.println(name + " makes a sound");
}
@Override
public String toString() {
return "Animal(" + name + ", " + age + ")";
}
}
// Usage
Animal dog = new Animal("Rex", 3);
dog.speak(); // Rex makes a sound
System.out.println(dog); // Animal(Rex, 3)
Inheritance uses extends. Polymorphism lets a parent reference hold a child object and call overridden methods.
public class Shape {
protected String color;
public Shape(String color) { this.color = color; }
public double area() { return 0; }
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color); // call parent constructor
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
// Polymorphism — parent ref, child object
Shape s = new Circle("red", 5.0);
System.out.println(s.area()); // 78.53...
System.out.println(s instanceof Circle); // true
An interface defines a contract (all methods abstract by default). An abstract class can mix abstract and concrete methods.
// Interface
public interface Drawable {
void draw(); // abstract
default void display() { // concrete default
System.out.println("Displaying...");
}
}
// Abstract class
public abstract class Vehicle {
protected int speed;
public abstract void move(); // must override
public void stop() { System.out.println("Stopped"); }
}
// Class can extend one class, implement many interfaces
public class Car extends Vehicle implements Drawable {
public void move() { System.out.println("Car moves"); }
public void draw() { System.out.println("Drawing car"); }
}
Java Collections provide ready-made data structures: List, Set, Map, Queue — all in java.util.
// ArrayList — ordered, allows duplicates
List<String> list = new ArrayList<>();
list.add("Java"); list.add("Python");
list.get(0); list.size(); list.remove("Java");
Collections.sort(list);
// HashMap — key-value pairs
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 90); map.put("Bob", 85);
map.get("Alice"); // 90
for (Map.Entry<String,Integer> e : map.entrySet())
System.out.println(e.getKey() + ": " + e.getValue());
// HashSet — unique elements
Set<Integer> set = new HashSet<>();
set.add(1); set.add(2); set.add(1); // {1, 2}
// Queue (LinkedList)
Queue<String> q = new LinkedList<>();
q.offer("first"); q.offer("second");
q.poll(); // "first"
Java uses try-catch-finally. Checked exceptions must be declared or caught; unchecked (RuntimeException) don't need to be.
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("Always runs");
}
// Custom exception
public class AgeException extends Exception {
public AgeException(String msg) { super(msg); }
}
public void setAge(int age) throws AgeException {
if (age < 0) throw new AgeException("Negative age");
this.age = age;
}
// try-with-resources (auto-close)
try (FileReader fr = new FileReader("file.txt")) {
// fr is automatically closed
} catch (IOException e) { e.printStackTrace(); }
Lambdas are anonymous functions. Streams enable functional-style pipeline operations on collections.
List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8);
// filter → collect
List<Integer> evens = nums.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList()); // [2,4,6,8]
// map → collect
List<Integer> doubled = nums.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
// reduce (sum)
int sum = nums.stream()
.reduce(0, Integer::sum); // 36
// sorted + distinct + limit + forEach
nums.stream().sorted().distinct().limit(5)
.forEach(System.out::println);
// Method reference
list.forEach(System.out::println);
Java supports multithreading via Thread, Runnable, and the ExecutorService thread pool API.
// Method 1: Extend Thread
class MyThread extends Thread {
public void run() {
System.out.println("Running: "
+ Thread.currentThread().getName());
}
}
new MyThread().start();
// Method 2: Runnable lambda
Thread t = new Thread(() -> System.out.println("Task!"));
t.start();
// Synchronized method (thread-safe)
public synchronized void increment() { count++; }
// ExecutorService (thread pool)
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> System.out.println("Task 1"));
pool.submit(() -> System.out.println("Task 2"));
pool.shutdown();