Java is one of the world's most widely used programming languages — running on 3+ billion devices across Android apps, enterprise backends, financial systems, and cloud services. This tutorial takes you from zero to writing real Java programs, with no prior experience required.
What you'll learn
| Topic | What you'll be able to do |
|---|---|
| Setup | Install Java and write your first program |
| Syntax & variables | Understand how Java code works |
| Data types | Work with primitives, strings, arrays |
| Control flow | Use if/else, loops, and switch |
| OOP | Write classes, objects, inheritance, interfaces |
| Collections | Use ArrayList, HashMap, and more |
| Error handling | Handle exceptions safely |
| File I/O | Read and write files |
| Projects | Build a calculator, To-Do app, and more |
Why learn Java?
| Use case | Example technologies |
|---|---|
| Android development | Android SDK, Kotlin interop |
| Backend / enterprise | Spring Boot, Quarkus, Micronaut |
| Financial systems | Banking, trading platforms |
| Big Data | Apache Kafka, Hadoop, Spark |
| Cloud services | AWS Lambda, Google Cloud |
| Desktop apps | JavaFX, Swing |
| Web scraping | Jsoup, Selenium |
| Game development | LibGDX, Minecraft modding |
Java's "Write Once, Run Anywhere" philosophy means Java code compiled on any platform runs on any JVM-equipped device.
1. Setup: Install Java
Step 1 — Download JDK
Download Java Development Kit (JDK) 21 (LTS) from adoptium.net or Oracle:
- Windows/Mac/Linux: download the installer for your OS, run it, follow prompts
Step 2 — Verify installation
Open a terminal and run:
java --version
# java 21.0.x 2024-...
javac --version
# javac 21.0.x
Step 3 — Choose an editor
| Editor | Best for |
|---|---|
| IntelliJ IDEA Community (recommended) | Full Java development |
| VS Code + Extension Pack for Java | Lightweight |
| Eclipse | Traditional enterprise |
Step 4 — Your first program
Create a file called Hello.java:
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Compile and run:
javac Hello.java # produces Hello.class
java Hello # Hello, World!
Key observations:
- Every Java program lives inside a class —
Hellohere - The
mainmethod is the entry point System.out.println()prints to the console with a newline
2. Syntax basics
Comments
// Single-line comment
/*
* Multi-line comment
*/
/**
* Javadoc comment — used to generate documentation
* @param args command-line arguments
*/
Statements end with ;
int x = 5; // must have semicolon
System.out.println(x);
Case sensitivity
Hello, hello, and HELLO are three different identifiers in Java.
3. Variables and data types
Java is statically typed — you must declare the type of every variable.
Primitive types
| Type | Size | Range / Description | Example |
|---|---|---|---|
byte |
8-bit | -128 to 127 | byte b = 100; |
short |
16-bit | -32,768 to 32,767 | short s = 1000; |
int |
32-bit | ~-2.1B to 2.1B | int n = 42; |
long |
64-bit | ~±9.2 quintillion | long l = 123L; |
float |
32-bit | ~6-7 decimal digits | float f = 3.14f; |
double |
64-bit | ~15-16 decimal digits | double d = 3.14159; |
char |
16-bit | Single Unicode character | char c = 'A'; |
boolean |
1-bit | true or false |
boolean flag = true; |
int age = 25;
double price = 9.99;
char grade = 'A';
boolean isActive = true;
long population = 8_000_000_000L; // underscores for readability
var (type inference, Java 10+)
var name = "Alice"; // inferred as String
var count = 42; // inferred as int
var list = new ArrayList<String>();
Reference types
Everything that is not a primitive is a reference type (object):
String message = "Hello";
int[] numbers = {1, 2, 3};
final — constants
final double PI = 3.14159;
// PI = 3.0; // compile error — can't reassign
Naming conventions:
- variables & methods:
camelCase - classes:
PascalCase - constants:
UPPER_SNAKE_CASE
4. Strings
String name = "Alice";
String greeting = "Hello, " + name; // concatenation
int len = name.length(); // 5
String upper = name.toUpperCase(); // "ALICE"
String lower = name.toLowerCase(); // "alice"
boolean starts = name.startsWith("Al"); // true
String trimmed = " hi ".strip(); // "hi"
String replaced = name.replace("l", "L"); // "ALice"
boolean contains = name.contains("lic"); // true
String[] parts = "a,b,c".split(","); // ["a","b","c"]
String formatting
// String.format
String msg = String.format("Name: %s, Age: %d", "Alice", 25);
// Text blocks (Java 15+)
String json = """
{
"name": "Alice",
"age": 25
}
""";
// printf
System.out.printf("Price: %.2f%n", 9.999); // Price: 10.00
Important: compare Strings with .equals()
String a = "hello";
String b = "hello";
// WRONG
if (a == b) { } // compares references, not content
// CORRECT
if (a.equals(b)) { } // compares content — true
if (a.equalsIgnoreCase(b)) { } // case-insensitive
5. Arrays
// Declaration and initialization
int[] scores = new int[5]; // [0, 0, 0, 0, 0]
int[] nums = {10, 20, 30};
// Access
System.out.println(nums[0]); // 10
nums[1] = 99;
// Length
System.out.println(nums.length); // 3
// Iterate
for (int n : nums) {
System.out.println(n);
}
// 2D arrays
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println(matrix[1][2]); // 6
6. Control flow
if / else if / else
int score = 75;
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("F");
}
Ternary operator
String result = (score >= 70) ? "Pass" : "Fail";
switch (classic and modern)
// Classic
switch (grade) {
case 'A':
System.out.println("Excellent");
break;
case 'B':
System.out.println("Good");
break;
default:
System.out.println("Other");
}
// Switch expression (Java 14+)
String label = switch (grade) {
case 'A' -> "Excellent";
case 'B' -> "Good";
case 'C' -> "Average";
default -> "Below average";
};
Loops
// for loop
for (int i = 0; i < 5; i++) {
System.out.println(i); // 0 1 2 3 4
}
// enhanced for (for-each)
int[] numbers = {1, 2, 3, 4, 5};
for (int n : numbers) {
System.out.println(n);
}
// while
int count = 0;
while (count < 3) {
System.out.println(count);
count++;
}
// do-while (runs at least once)
int x = 0;
do {
System.out.println(x);
x++;
} while (x < 3);
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); // 0 1 2 4 5 6
}
7. Methods (functions)
public class Calculator {
// Static method — call without creating object
public static int add(int a, int b) {
return a + b;
}
// void — returns nothing
public static void greet(String name) {
System.out.println("Hello, " + name + "!");
}
// Method overloading — same name, different parameters
public static double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
int sum = add(3, 4); // 7
double dSum = add(1.5, 2.5); // 4.0
greet("Alice");
}
}
Varargs (variable arguments)
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) total += n;
return total;
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15
8. Object-Oriented Programming (OOP)
OOP is Java's core paradigm. Everything is organized around classes and objects.
Classes and objects
public class Person {
// Fields (instance variables)
private String name;
private int age;
// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String name) {
this.name = name;
}
// Method
public void introduce() {
System.out.println("Hi, I'm " + name + ", age " + age);
}
// toString — called when printing object
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
// Using the class
Person alice = new Person("Alice", 30);
alice.introduce(); // Hi, I'm Alice, age 30
System.out.println(alice); // Person{name='Alice', age=30}
The 4 pillars of OOP
| Pillar | Meaning | Java mechanism |
|---|---|---|
| Encapsulation | Hide internal state | private fields + getters/setters |
| Abstraction | Expose only what matters | Abstract classes, interfaces |
| Inheritance | Reuse and extend behaviour | extends |
| Polymorphism | One interface, many forms | Method overriding, interfaces |
Inheritance
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void makeSound() {
System.out.println(name + " makes a sound");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name); // call parent constructor
}
@Override
public void makeSound() {
System.out.println(name + " barks!");
}
public void fetch() {
System.out.println(name + " fetches the ball!");
}
}
// Usage
Animal a = new Dog("Rex");
a.makeSound(); // Rex barks! (polymorphism)
Interfaces
public interface Drawable {
void draw(); // abstract (no body)
default String getColor() { // default method (Java 8+)
return "black";
}
}
public interface Resizable {
void resize(double factor);
}
// Class can implement multiple interfaces
public class Circle implements Drawable, Resizable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing circle with radius " + radius);
}
@Override
public void resize(double factor) {
radius *= factor;
}
}
Abstract classes
public abstract class Shape {
// Abstract method — subclasses MUST implement
public abstract double area();
// Concrete method — subclasses inherit this
public void describe() {
System.out.println("This shape has area: " + area());
}
}
public class Rectangle extends Shape {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
}
| Feature | Abstract class | Interface |
|---|---|---|
| Instantiation | Cannot instantiate | Cannot instantiate |
| Methods | Can have concrete + abstract | Abstract by default, default for concrete |
| Fields | Can have instance fields | Constants only (public static final) |
| Inheritance | extends (single) |
implements (multiple) |
| Constructor | Can have | Cannot have |
| Use when | Shared base + partial implementation | Define a contract/capability |
9. Collections Framework
Java's Collections Framework provides ready-to-use data structures.
ArrayList — dynamic array
import java.util.ArrayList;
import java.util.Collections;
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
System.out.println(fruits.get(0)); // Apple
System.out.println(fruits.size()); // 3
fruits.remove("Banana");
fruits.set(0, "Avocado"); // replace index 0
// Iterate
for (String fruit : fruits) {
System.out.println(fruit);
}
// Sort
Collections.sort(fruits);
// Contains
boolean has = fruits.contains("Cherry"); // true
HashMap — key-value store
import java.util.HashMap;
import java.util.Map;
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 87);
scores.put("Charlie", 92);
System.out.println(scores.get("Alice")); // 95
System.out.println(scores.containsKey("Bob")); // true
scores.remove("Bob");
// Iterate entries
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// getOrDefault
int score = scores.getOrDefault("Dave", 0); // 0
HashSet — unique elements
import java.util.HashSet;
HashSet<String> tags = new HashSet<>();
tags.add("java");
tags.add("backend");
tags.add("java"); // duplicate — ignored
System.out.println(tags.size()); // 2
System.out.println(tags.contains("java")); // true
Collections cheat sheet
| Structure | Use when | Key operations |
|---|---|---|
ArrayList<E> |
Ordered list, frequent reads | add, get, remove, size |
LinkedList<E> |
Frequent insertions/deletions at ends | addFirst, addLast, poll |
HashMap<K,V> |
Key-value lookup | put, get, containsKey, remove |
TreeMap<K,V> |
Sorted key-value | Same as HashMap, keys sorted |
HashSet<E> |
Unique elements, fast lookup | add, contains, remove |
TreeSet<E> |
Unique sorted elements | Same as HashSet, sorted |
ArrayDeque<E> |
Stack or queue | push, pop, offer, poll |
PriorityQueue<E> |
Min-heap / priority processing | offer, poll, peek |
10. Exception handling
public class ExceptionDemo {
// Declaring checked exceptions
public static int divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("Cannot divide by zero");
}
return a / b;
}
public static void main(String[] args) {
// try-catch-finally
try {
int result = divide(10, 0);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("This always runs");
}
// Multi-catch
try {
String s = null;
s.length();
} catch (NullPointerException | IllegalArgumentException e) {
System.out.println("Caught: " + e.getClass().getSimpleName());
}
}
}
Custom exceptions
public class InsufficientFundsException extends RuntimeException {
private double amount;
public InsufficientFundsException(double amount) {
super("Insufficient funds. Need: " + amount);
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// Usage
throw new InsufficientFundsException(100.0);
Checked vs unchecked exceptions
| Type | Examples | Must handle? |
|---|---|---|
| Checked | IOException, SQLException |
Yes — compile error if not caught or declared |
| Unchecked (Runtime) | NullPointerException, ArrayIndexOutOfBoundsException |
No — optional |
| Error | OutOfMemoryError, StackOverflowError |
No — don't catch these |
11. File I/O
import java.io.*;
import java.nio.file.*;
import java.util.List;
public class FileDemo {
public static void main(String[] args) throws IOException {
Path filePath = Path.of("notes.txt");
// Write to file
Files.writeString(filePath, "Hello, file!\nSecond line.");
// Read entire file
String content = Files.readString(filePath);
System.out.println(content);
// Read lines
List<String> lines = Files.readAllLines(filePath);
for (String line : lines) {
System.out.println(line);
}
// Append to file
Files.writeString(filePath, "\nThird line.",
StandardOpenOption.APPEND);
// Check if file exists
boolean exists = Files.exists(filePath);
System.out.println("Exists: " + exists);
// Delete file
Files.delete(filePath);
}
}
12. Java 8+ features you need to know
Lambda expressions
import java.util.*;
import java.util.stream.*;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Without lambda
numbers.sort(new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return b - a;
}
});
// With lambda
numbers.sort((a, b) -> b - a);
// forEach
numbers.forEach(n -> System.out.println(n));
numbers.forEach(System.out::println); // method reference
Stream API
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Anna", "Dave");
// Filter + map + collect
List<String> result = names.stream()
.filter(n -> n.startsWith("A")) // ["Alice", "Anna"]
.map(String::toUpperCase) // ["ALICE", "ANNA"]
.sorted() // ["ALICE", "ANNA"]
.collect(Collectors.toList());
// Reduce
int sum = numbers.stream()
.reduce(0, Integer::sum); // 55
// Count, min, max
long count = names.stream().filter(n -> n.length() > 3).count();
Optional<String> longest = names.stream().max(Comparator.comparingInt(String::length));
// map to numbers
int totalLength = names.stream()
.mapToInt(String::length)
.sum();
Optional
import java.util.Optional;
Optional<String> opt = Optional.of("Hello");
Optional<String> empty = Optional.empty();
// Safe usage
opt.ifPresent(System.out::println); // Hello
String val = opt.orElse("default"); // Hello
String val2 = empty.orElse("default"); // default
String val3 = empty.orElseGet(() -> "computed"); // computed
Optional<String> mapped = opt.map(String::toUpperCase); // Optional["HELLO"]
Record classes (Java 16+)
// Immutable data carrier — auto-generates constructor, getters, equals, hashCode, toString
public record Point(double x, double y) {
// Optional: add methods
public double distanceTo(Point other) {
double dx = this.x - other.x;
double dy = this.y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
Point p = new Point(3.0, 4.0);
System.out.println(p.x()); // 3.0
System.out.println(p); // Point[x=3.0, y=4.0]
13. Generics
// Generic class
public class Box<T> {
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);
// Generic method
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
max(3, 7); // 7
max("apple", "banana"); // "banana"
Project 1: Command-line calculator
import java.util.Scanner;
public class Calculator {
public static double calculate(double a, String op, double b) {
return switch (op) {
case "+" -> a + b;
case "-" -> a - b;
case "*" -> a * b;
case "/" -> {
if (b == 0) throw new ArithmeticException("Division by zero");
yield a / b;
}
default -> throw new IllegalArgumentException("Unknown operator: " + op);
};
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== Calculator ===");
System.out.println("Enter: number operator number (e.g. 5 + 3)");
System.out.println("Type 'quit' to exit");
while (true) {
System.out.print("> ");
String input = scanner.nextLine().trim();
if (input.equalsIgnoreCase("quit")) break;
String[] parts = input.split(" ");
if (parts.length != 3) {
System.out.println("Invalid format. Example: 5 + 3");
continue;
}
try {
double a = Double.parseDouble(parts[0]);
double b = Double.parseDouble(parts[2]);
double result = calculate(a, parts[1], b);
System.out.printf("= %.4f%n", result);
} catch (NumberFormatException e) {
System.out.println("Invalid numbers.");
} catch (ArithmeticException | IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
scanner.close();
System.out.println("Goodbye!");
}
}
Project 2: To-Do list app
import java.util.*;
public class TodoApp {
record Task(int id, String title, boolean done) {
Task complete() {
return new Task(id, title, true);
}
@Override
public String toString() {
return String.format("[%s] #%d %s", done ? "x" : " ", id, title);
}
}
private final List<Task> tasks = new ArrayList<>();
private int nextId = 1;
public void add(String title) {
tasks.add(new Task(nextId++, title, false));
System.out.println("Added: " + title);
}
public void complete(int id) {
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i).id() == id) {
tasks.set(i, tasks.get(i).complete());
System.out.println("Completed task #" + id);
return;
}
}
System.out.println("Task #" + id + " not found.");
}
public void remove(int id) {
boolean removed = tasks.removeIf(t -> t.id() == id);
System.out.println(removed ? "Removed task #" + id : "Task #" + id + " not found.");
}
public void list() {
if (tasks.isEmpty()) {
System.out.println("No tasks!");
return;
}
long pending = tasks.stream().filter(t -> !t.done()).count();
System.out.println("Tasks (" + pending + " pending):");
tasks.forEach(System.out::println);
}
public static void main(String[] args) {
TodoApp app = new TodoApp();
Scanner scanner = new Scanner(System.in);
System.out.println("=== To-Do App ===");
System.out.println("Commands: add <title> | done <id> | remove <id> | list | quit");
while (true) {
System.out.print("> ");
String line = scanner.nextLine().trim();
if (line.isEmpty()) continue;
String[] parts = line.split(" ", 2);
String cmd = parts[0].toLowerCase();
switch (cmd) {
case "add" -> app.add(parts.length > 1 ? parts[1] : "Untitled");
case "done" -> app.complete(Integer.parseInt(parts[1]));
case "remove" -> app.remove(Integer.parseInt(parts[1]));
case "list" -> app.list();
case "quit" -> { scanner.close(); return; }
default -> System.out.println("Unknown command: " + cmd);
}
}
}
}
Project 3: Student grade tracker
import java.util.*;
import java.util.stream.*;
public class GradeTracker {
record Student(String name, List<Integer> grades) {
double average() {
return grades.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
}
String letterGrade() {
double avg = average();
if (avg >= 90) return "A";
if (avg >= 80) return "B";
if (avg >= 70) return "C";
if (avg >= 60) return "D";
return "F";
}
@Override
public String toString() {
return String.format("%-15s avg=%.1f (%s)", name, average(), letterGrade());
}
}
public static void main(String[] args) {
List<Student> students = List.of(
new Student("Alice", List.of(95, 88, 92, 97)),
new Student("Bob", List.of(72, 68, 75, 80)),
new Student("Charlie", List.of(85, 90, 88, 82)),
new Student("Diana", List.of(60, 55, 70, 65))
);
System.out.println("=== Grade Report ===");
students.stream()
.sorted(Comparator.comparingDouble(Student::average).reversed())
.forEach(System.out::println);
double classAvg = students.stream()
.mapToDouble(Student::average)
.average()
.orElse(0);
System.out.printf("%nClass average: %.1f%n", classAvg);
System.out.println("\nTop student: " +
students.stream()
.max(Comparator.comparingDouble(Student::average))
.map(Student::name)
.orElse("N/A"));
}
}
Learning path
| Stage | Topics | Timeline |
|---|---|---|
| 1. Foundations | Setup, syntax, variables, control flow, methods | Weeks 1–2 |
| 2. OOP basics | Classes, objects, encapsulation, constructors | Weeks 3–4 |
| 3. OOP advanced | Inheritance, interfaces, abstract classes, polymorphism | Weeks 5–6 |
| 4. Collections | ArrayList, HashMap, HashSet, iteration | Week 7 |
| 5. Error handling | Exceptions, try-catch, custom exceptions | Week 8 |
| 6. Modern Java | Streams, lambdas, Optional, records | Weeks 9–10 |
| 7. Build tools | Maven or Gradle for dependency management | Week 11 |
| 8. Framework | Spring Boot (backend) or Android SDK | Weeks 12–16 |
Java vs other languages
| Feature | Java | Python | JavaScript | C++ |
|---|---|---|---|---|
| Typing | Static | Dynamic | Dynamic | Static |
| Speed | Fast (JIT compiled) | Slower | Medium | Fastest |
| Verbosity | More verbose | Concise | Medium | Very verbose |
| Memory | GC managed | GC managed | GC managed | Manual |
| Main use | Enterprise, Android | Data science, AI | Web frontend/backend | Systems, games |
| Learning curve | Medium | Easy | Easy | Hard |
| Jobs | Very high demand | Very high demand | Very high demand | Medium demand |
Common mistakes
| Mistake | Wrong | Right |
|---|---|---|
Comparing Strings with == |
if (a == b) |
if (a.equals(b)) |
| Forgetting to import | ArrayList list (error) |
import java.util.ArrayList; |
| Off-by-one in arrays | for (i=0; i<=arr.length; i++) |
for (i=0; i<arr.length; i++) |
| Not closing resources | Scanner sc = new Scanner(...) |
Use try-with-resources |
| Ignoring exceptions | catch (Exception e) {} |
At least e.printStackTrace() |
| Using raw types | ArrayList list = new ArrayList() |
ArrayList<String> list = new ArrayList<>() |
| Null pointer exception | String s = null; s.length() |
Check s != null or use Optional |
| Integer overflow | int x = 3_000_000_000 (overflow) |
Use long x = 3_000_000_000L |
Java vs related terms
| Term | What it is |
|---|---|
| Java | Programming language + platform |
| JDK | Java Development Kit — tools to compile + run Java |
| JRE | Java Runtime Environment — runs Java programs (subset of JDK) |
| JVM | Java Virtual Machine — executes bytecode on any OS |
| Maven / Gradle | Build tools + dependency managers |
| Spring Boot | Most popular Java web framework |
| Kotlin | Modern JVM language, fully interoperable with Java |
| Android | Mobile platform that uses Java and Kotlin |
| OpenJDK | Open-source JDK implementation (recommended) |
| GraalVM | Alternative JVM with native image compilation |
Frequently asked questions
Q: Should I learn Java or Python first?
A: Both are excellent first languages. Choose Java if you're interested in Android, enterprise software, or backend development. Choose Python if you lean toward data science, ML, or automation. Java's strictness can actually help build good habits.
Q: Is Java still worth learning in 2025?
A: Absolutely. Java consistently ranks in the top 3 most-used languages. Spring Boot dominates enterprise backends, Android development uses Java/Kotlin, and big-data tools like Kafka and Spark are Java-based.
Q: How long does it take to learn Java?
A: The basics (variables, OOP, collections) take 4–8 weeks with daily practice. Being job-ready with Spring Boot takes 4–6 months total.
Q: What's the difference between Java and JavaScript?
A: They are completely different languages — similar name, different purpose. Java is compiled, statically typed, and used for backend/Android. JavaScript runs in browsers, is dynamically typed, and is the language of the web.
Q: Do I need a computer science degree to learn Java?
A: No. Many professional Java developers are self-taught. Focus on building projects, learning data structures, and practising on LeetCode.
Q: What should I build first?
A: Start with the three projects in this tutorial (calculator, to-do app, grade tracker). Then build a simple REST API with Spring Boot and deploy it — that gives you portfolio-worthy experience employers value.