📘 Core Java Notes — Ekdum Basic Se

Java ke 34 topics — Basics se leke Java 8+ tak — har ek ek chhoti kahani + animation ke saath, jaise koi bachha pehli baar Java seekh raha ho. Category chuno, card par click karke kholo.

💡 Java ek recipe likhne jaisa hai jise duniya ki kisi bhi kitchen (computer) mein banaya ja sakta hai.

Java ek programming language hai jisse hum computer ko instructions dete hain. Ye 1995 mein bani thi aur aaj bhi apps, websites, games — sabme use hoti hai.

Sabse khaas baat: "Write Once, Run Anywhere". Matlab ek baar Java code likho, wo Windows, Mac, Linux — har jagah chal sakta hai, bina dobara likhe!

Kaise? Tumhara .java file pehle "compile" hoti hai aur .class file (bytecode) banti hai. Fir JVM (Java Virtual Machine) us bytecode ko har computer par samajh kar chala deti hai — jaise ek universal translator!

public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello, Code10x!");
  }
}
Animation
💡 Variable ek labeled dabba (box) hai jisme tum ek value rakhte ho — dabbe ka naam aur us mein kya rakh sakte ho (type), pehle se tay hota hai.

Java mein har variable ka ek type hota hai — jaise int (whole number), double (decimal number), char (single letter), boolean (true/false), aur String (text).

Java "statically typed" language hai — matlab dabbe ka type shuru mein hi batana padta hai, aur us dabbe mein sirf wahi type ki cheez fit hogi.

int age = 10;
double price = 99.5;
char grade = 'A';
boolean isFun = true;
String name = "Duke";
Animation
💡 Operators tumhari calculator ke buttons jaise hain — +, -, *, / se maths, aur ==, >, < se comparison karte ho.

Arithmetic operators (+ - * / %) numbers par maths karte hain. % operator "remainder" deta hai — jaise 10 % 3 = 1.

Relational operators (== != > < >= <=) do values compare karke true/false batate hain. Logical operators (&& || !) multiple conditions jodte hain.

int a = 10, b = 3;
System.out.println(a % b);            // 1
System.out.println(a > b && b > 0);   // true
Animation
💡 if-else ek railway junction jaisa hai — track condition ke hisaab se left ya right switch hota hai.

if block tabhi chalta hai jab condition true ho. Agar false ho, to else block chalta hai.

Tum kai conditions bhi laga sakte ho else if se — jaise ek ke baad ek gate check karna.

int marks = 85;
if (marks >= 90) {
  System.out.println("A grade");
} else if (marks >= 60) {
  System.out.println("B grade");
} else {
  System.out.println("Keep trying!");
}
Animation
💡 Loop ek runner hai jo track par baar-baar chakkar lagata hai, jab tak coach (condition) na bole "ruk jao!"

for loop tab use karte hain jab pata ho kitni baar repeat karna hai. while loop tab jab condition ke true rehne tak repeat karna ho.

do-while loop kam se kam ek baar zaroor chalta hai, chahe condition false hi kyun na ho.

for (int i = 1; i <= 5; i++) {
  System.out.println("Lap " + i);
}
Animation
💡 Array numbered lockers ki row jaisa hai — har locker ka apna index (0 se shuru) hota hai.

Array ek fixed-size collection hai jisme same type ki multiple values ek saath store hoti hain.

Har value ka apna "index" hota hai, jo 0 se start hota hai — pehla element index 0 par hota hai, na ki 1!

int[] scores = {90, 85, 77, 60};
System.out.println(scores[0]); // 90
Animation
💡 Class ek ghar ka blueprint (naksha) hai. Object us naksha se bana ek asli ghar — aur tum ek naksha se kayi ghar bana sakte ho!

Class define karti hai ki object ke paas kya properties (fields) aur kya behavior (methods) honge.

Object class ka ek "instance" hota hai — real cheez jisko tum use kar sakte ho, apni values ke saath.

class Car {
  String color;
  void drive() { System.out.println(color + " car driving!"); }
}
Car myCar = new Car();
myCar.color = "Red";
myCar.drive();
Animation
💡 Constructor ek "welcome kit" hai jo object banते hi turant use uske starting values de deta hai.

Constructor ek special method hai jiska naam class ke naam jaisa hota hai, aur wo tab call hota hai jab "new" keyword se object banaya jaata hai.

Isse hum object ko turant valid starting state de sakte hain — bina alag se har field set kiye.

class Student {
  String name;
  Student(String n) { name = n; }
}
Student s1 = new Student("Aarav");
Animation
💡 "this" ka matlab "main khud" — apne hi field ko point karta hai. "static" ek shared locker jaisa hai jo saare objects milke use karte hain.

this current object ko refer karta hai — jab parameter aur field ka naam same ho, tab confusion door karta hai.

static member class ka hota hai, kisi ek object ka nahi — sab objects usko share karte hain, jaise ek common counter.

class Counter {
  static int total = 0;
  Counter() { total++; }
}
Animation
💡 Inheritance mein child class apne parent class ke features "virse" (inherit) mein paati hai — jaise beta apne papa ki properties paata hai, plus khud ki nayi cheezein add kar sakta hai.

extends keyword se ek class dusri class ke fields aur methods use kar sakti hai, bina dobara likhe.

Ye code reuse badhata hai — common cheezein parent mein likho, specific cheezein child mein.

class Animal {
  void eat() { System.out.println("Eating..."); }
}
class Dog extends Animal {
  void bark() { System.out.println("Woof!"); }
}
Animation
💡 Polymorphism ka matlab "ek naam, kayi roop" — jaise ek actor alag-alag costume pehen kar alag role play karta hai.

Overloading: same method naam, alag parameters — jaise add(int,int) aur add(double,double). Ye compile-time par decide hota hai.

Overriding: child class parent ke method ko apne tareeke se dobara likhti hai — jaise Dog apna sound() khud define karta hai. Ye run-time par decide hota hai.

class Animal { void sound() { System.out.println("..."); } }
class Cat extends Animal { void sound() { System.out.println("Meow"); } }
Animation
💡 Encapsulation data ko ek capsule ke andar band kar deta hai — bahar se seedha touch nahi kar sakte, sirf "get" aur "set" darwaazon se aana-jaana hota hai.

Fields ko private banao, taaki koi bahar se seedha change na kar sake.

public getter/setter methods do jisse controlled tareeke se value padhi/badli ja sake — jaise ATM se paisa nikalna, seedha locker khol kar nahi.

class Account {
  private double balance;
  public double getBalance() { return balance; }
  public void deposit(double amt) { if (amt > 0) balance += amt; }
}
Animation
💡 Car chalate waqt tum sirf steering aur pedal use karte ho — engine ke andar kya ho raha hai, wo dikhna zaroori nahi. Yahi Abstraction hai!

Abstraction complex implementation ko chhupa kar sirf zaroori cheezein dikhata hai.

abstract class ya interface se hum "kya karna hai" batate hain, "kaise karna hai" wo implementing class decide karti hai.

abstract class Shape {
  abstract double area();
}
class Circle extends Shape {
  double r;
  double area() { return 3.14 * r * r; }
}
Animation
💡 Interface ek 100% contract hai — sirf rules, koi kaam pehle se nahi kiya gaya. Abstract class ek adhoora (half-built) ghar hai — kuch kaam already ho chuka, baaki tumhe karna hai.

Interface mein (Java 8 se pehle) sirf method signatures hote the, koi body nahi — implementing class ko sab likhna padta tha.

Abstract class mein kuch methods complete ho sakte hain aur kuch abstract (incomplete) — aur ek class sirf ek abstract class extend kar sakti hai, par kayi interfaces implement kar sakti hai.

interface Flyable { void fly(); }

abstract class Bird {
  void breathe() { System.out.println("breathing"); }
  abstract void fly();
}
Animation
💡 try-catch ek safety net jaisa hai circus mein — agar performer (code) gir jaaye (error aaye), net (catch) use pakad leta hai taaki show (program) crash na ho.

try block mein wo code likhte hain jo error de sakta hai. Agar error aaye, catch block use "pakad" leta hai aur program crash nahi hota.

finally block hamesha chalta hai — chahe error aaye ya na aaye — jaise cleanup karna, files band karna.

try {
  int x = 10 / 0;
} catch (ArithmeticException e) {
  System.out.println("Cannot divide by zero!");
} finally {
  System.out.println("Done trying.");
}
Animation
💡 ArrayList ek train hai jiske bogie order mein hain (index se access). HashSet ek sticker album hai jisme koi sticker repeat nahi hota. HashMap ek locker room hai jaha har locker ka apna naam-tag (key) hota hai.

ArrayList ordered list hai, duplicates allowed, index se access hota hai.

HashSet sirf unique values rakhta hai, order guarantee nahi karta. HashMap key-value pairs store karta hai — key se turant value dhoond sakte ho, jaise naam se locker.

List<String> names = new ArrayList<>();
Set<Integer> ids = new HashSet<>();
Map<String, Integer> ages = new HashMap<>();
ages.put("Aarav", 10);
Animation
💡 Single thread ek akela runner hai jo ek-ek karke sab kaam karta hai. Multithreading kayi runners ek saath alag-alag tracks par daudte hain — kaam jaldi hota hai!

Thread program ka ek independent flow hai. Normally Java ek thread (main) mein chalta hai.

Thread class extend karke ya Runnable implement karke naye threads bana sakte ho, jo parallel kaam karte hain.

class MyThread extends Thread {
  public void run() { System.out.println("Running..."); }
}
new MyThread().start();
Animation
💡 String ek pathhar par likhai jaisa hai — ek baar likhne ke baad badla nahi ja sakta, badalne ke liye naya pathhar (naya object) banta hai. StringBuilder ek whiteboard hai jise mita kar dobara likh sakte ho.

String immutable hai — jab tum s = s + "x" karte ho, ek naya String object banta hai, purana wahi rehta hai.

Agar bahut saare changes karne hain (jaise loop mein), to StringBuilder use karo — wo same object ko modify karta hai, fast hota hai.

String s = "Hi";
s = s + " Java";      // new object created

StringBuilder sb = new StringBuilder("Hi");
sb.append(" Java");   // same object modified
Animation
💡 Type casting ek chhote gilas ka paani bade gilas mein daalna (widening) ya bade gilas ka paani zabardasti chhote mein bharna (narrowing, kuch chhalak sakta hai) jaisa hai.

Widening (implicit) casting mein chhota type bade type mein khud-ba-khud convert ho jaata hai — jaise int se double, kuch loss nahi hota.

Narrowing (explicit) casting mein bada type chhote mein manually convert karna padta hai — jaise double se int, kuch data (decimal part) kho sakta hai.

Wrapper classes (Integer, Double, Character, Boolean) primitive types ko object ki tarah use karne dete hain. Autoboxing primitive ko wrapper mein badal deta hai automatically, unboxing ulta karta hai.

double d = 100.99;
int i = (int) d;      // narrowing, i = 100

int x = 5;
Integer boxed = x;    // autoboxing
int y = boxed;        // unboxing
Animation
💡 Method ek reusable machine jaisa hai — ek baar bana lo, jab bhi zaroorat ho bas "call" karo, wahi kaam ho jayega. Recursion ek machine hai jo khud apne aap ko dobara call karti hai, jab tak stop na ho.

Method parameters leta hai, kaam karta hai, aur (chahe to) ek value return karta hai — isse code repeat nahi karna padta.

Java "pass by value" follow karta hai — method ko values ki copy milti hai, original variable change nahi hota (objects ke case mein reference ki copy milti hai).

Recursion mein ek method khud ko call karta hai — jaise factorial(5) = 5 * factorial(4)... jab tak base case (factorial(1)=1) na aaye.

int factorial(int n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
Animation
💡 switch ek vending machine jaisa hai — number dabao, seedha wahi cheez milti hai, ek-ek karke if-else check nahi karna padta. break loop se bahar nikal jaata hai, continue agla round shuru kar deta hai.

switch multiple if-else ki jagah use hota hai jab ek variable ki alag-alag fixed values check karni ho — har case ke baad break lagana zaroori hai, warna agla case bhi chal jaata hai (fall-through).

break loop ko turant rok deta hai. continue current iteration skip karke agli iteration par chala jaata hai.

switch (day) {
  case 1: System.out.println("Mon"); break;
  case 2: System.out.println("Tue"); break;
  default: System.out.println("Other");
}
Animation
💡 2D array ek seat-chart (rows aur columns) jaisa hai — jaise class mein rows aur seats, har seat ka apna row-column address hota hai.

2D array ek "array of arrays" hai — pehla index row batata hai, dusra column.

Isse grid-jaisa data store hota hai — jaise tic-tac-toe board, ya matrix.

int[][] grid = {
  {1, 2, 3},
  {4, 5, 6}
};
System.out.println(grid[1][2]); // 6 (row 1, col 2)
Animation
💡 Har Java object ke paas ek "default ID card" hota hai (Object class se) — toString() naam batata hai, equals() pehchaanta hai "ye wahi cheez hai kya", hashCode() ek unique-jaisa number deta hai fast lookup ke liye.

Har class implicitly Object class extend karti hai, isliye har object ko toString(), equals(), hashCode() free mein milte hain.

Default toString() ajeeb sa text deta hai (jaise ClassName@hashcode) — isliye hum usse override karte hain readable output ke liye.

equals() aur hashCode() ko saath mein override karna chahiye — HashMap/HashSet ko sahi se kaam karne ke liye ye zaroori hai.

class Point {
  int x, y;
  public String toString() { return "(" + x + "," + y + ")"; }
  public boolean equals(Object o) {
    if (!(o instanceof Point)) return false;
    Point p = (Point) o;
    return x == p.x && y == p.y;
  }
}
Animation
💡 Nested class ek matryoshka (russian doll) jaisi hai — ek class ke andar ek aur class chhipi ho sakti hai, jo bahar wali class se closely juda kaam karti hai.

Static nested class outer class ke bina bhi independently use ho sakti hai — sirf Outer.Nested se access.

Inner (non-static) class outer object se juda hota hai — usse outer ke instance members bhi directly dikhte hain.

Anonymous class ek naam-less class hai jo turant, one-time use ke liye define ki jaati hai — jaise ek button click listener.

class Outer {
  static class Nested { void show() { System.out.println("Nested"); } }
  class Inner { void show() { System.out.println("Inner"); } }
}
Animation
💡 Enum ek traffic signal jaisa hai — sirf RED, YELLOW, GREEN, in teen ke alawa koi 4th color exist hi nahi karta. Fixed, predefined choices.

enum ek special type hai jisme sirf fixed constants define hote hain — jaise Day.MONDAY, Day.TUESDAY.

Ye normal String/int se better hai kyunki compiler galat value use hone hi nahi deta — sirf wahi options allowed hain jo tumne define kiye.

enum Level { LOW, MEDIUM, HIGH }

Level l = Level.MEDIUM;
if (l == Level.MEDIUM) System.out.println("Medium level!");
Animation
💡 Generics ek universal toolbox jaisa hai jisme tum label laga sakte ho ki "is baar sirf screws (Integer) rakhunga" ya "is baar sirf nails (String)" — box wahi hai, par andar sirf ek type ki cheez jaati hai, mix-up nahi hota.

Generics <T> se hum classes/methods ko "kisi bhi type ke liye kaam karne wala" bana sakte hain, bina alag-alag versions likhe.

Compile-time par type-safety milti hai — galat type dalne ki koshish par compiler turant error de deta hai, run-time crash se bacha leta hai.

class Box<T> {
  T item;
  void set(T item) { this.item = item; }
  T get() { return item; }
}
Box<String> b = new Box<>();
b.set("Hello");
Animation
💡 Access modifiers ghar ke darwazon jaise hain — public darwaza sabke liye khula, private sirf tumhare apne kamre ka, protected sirf family (subclass) ke liye, aur default sirf same colony (package) ke logon ke liye.

public: kahin se bhi access ho sakta hai. private: sirf usi class ke andar. protected: same package + subclasses mein. default (kuch na likho): sirf same package mein.

Package related classes ka ek folder/group hai — jaise java.util mein List, Map jaise collection classes hote hain. Apna package banane ke liye "package com.code10x;" likhte hain.

package com.code10x;

public class Robot {
  private int battery;
  protected void charge() { battery = 100; }
}
Animation
💡 Comparable ek cheez khud batati hai "main kaise sort hoti hun" (jaise ek line mein khade bachhon ki height built-in hoti hai). Comparator ek bahar ka teacher hai jo custom order decide karta hai. Queue ek line jaisi hai (pehle aao, pehle jao).

Comparable (compareTo method) class ke andar define hota hai — "natural ordering" batata hai. Comparator (compare method) bahar se custom ordering deta hai, jitni chaho utni banao.

Queue FIFO (First-In-First-Out) order follow karta hai — jaise ticket line. Deque dono taraf se add/remove kar sakta hai.

TreeMap/TreeSet apne aap keys ko sorted order mein rakhte hain (HashMap/HashSet ke ulat, jaha order guaranteed nahi hota).

List<String> names = new ArrayList<>(List.of("Zoya","Aman","Ravi"));
names.sort(Comparator.naturalOrder());
// [Aman, Ravi, Zoya]

Queue<Integer> q = new LinkedList<>();
q.add(1); q.add(2);
System.out.println(q.poll()); // 1
Animation
💡 Lambda expression ek chhoti si "instant note" jaisi hai — poori formal chitthi (class banake method likhna) likhne ke bajaye, turant ek line mein kaam bata dena. Stream ek factory conveyor belt hai jisme data ek-ek stage se guzar kar (filter -> map -> collect) final result banta hai.

Lambda expression (param) -> { code } se ek functional interface (jisme sirf ek abstract method ho) ko chhote tareeke se implement karte hain.

Stream API collections par filter, map, sort jaise operations chain karke likhne deta hai — bina manual loops likhe, code chhota aur readable ban jaata hai.

List<Integer> nums = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenSquares = nums.stream()
    .filter(n -> n % 2 == 0)
    .map(n -> n * n)
    .toList();
// [4, 16, 36]
Animation
💡 File handling ek diary likhne/padhne jaisa hai — FileWriter se diary mein likhte ho, BufferedReader se diary padhte ho. try-with-resources ek smart helper hai jo diary band karna khud yaad rakhta hai.

java.io package files ke saath kaam karne ke tools deta hai — FileReader/FileWriter characters ke liye, BufferedReader fast line-by-line reading ke liye.

try-with-resources resource ko apne aap close kar deta hai jab block khatam ho — file/connection khuli reh jaane ki galti se bachata hai.

try (BufferedReader br = new BufferedReader(new FileReader("notes.txt"))) {
  String line = br.readLine();
  System.out.println(line);
} catch (IOException e) {
  System.out.println("File error: " + e.getMessage());
}
Animation
💡 Multi-catch ek hi security guard hai jo alag-alag tarah ke troublemakers (exceptions) ko ek hi gate par sambhal leta hai, alag-alag gate banane ki zaroorat nahi.

Ek catch block mein "|" se multiple exception types pakad sakte ho: catch (IOException | SQLException e).

Custom exceptions ka apna hierarchy bana sakte ho — jaise ek base AppException, aur usse extend karke specific PaymentFailedException — bade projects mein errors ko organize karta hai.

try {
  riskyOperation();
} catch (IOException | SQLException e) {
  System.out.println("Handled: " + e.getMessage());
}

class AppException extends Exception {}
class PaymentFailedException extends AppException {}
Animation
💡 Thread lifecycle ek runner ke safar jaisa hai — New (start line par khada) -> Runnable (daudne ko taiyar) -> Running (daud raha) -> Waiting (rukkar dam le raha) -> Terminated (finish line). Executor Framework ek race manager hai jo automatically decide karta hai kaunsa runner kab daude.

Thread ke 5 states hote hain: New, Runnable, Running, Waiting/Blocked, Terminated.

wait()/notify() threads ko ek doosre ke signal ka intezaar karne dete hain. ExecutorService thread pool manage karta hai — naye threads manually banane ke bajaye, ready threads reuse hote hain.

Deadlock tab hota hai jab do threads ek-doosre ke paas jo resource hai uska intezaar karte reh jaate hain, aur koi aage nahi badhta — jaise do log ek hi darwaze par ek-doosre ko pehle jaane de rahe hon, hamesha ke liye.

ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(() -> System.out.println("Task running!"));
pool.shutdown();
Animation
💡 Heap ek bada godown hai jaha saare objects rehte hain. Stack ek chhoti-si to-do list hai jo method calls track karti hai. Garbage Collector ek safai karamchari hai jo godown mein ghoom kar un objects ko hata deta hai jinhe ab koi use nahi kar raha.

Stack memory method calls aur local variables store karti hai — fast, aur method khatam hote hi automatically clean ho jaati hai.

Heap memory objects store karti hai (jo "new" se banaye jaate hain) — ye lambe samay tak rehti hai, jab tak koi reference use na kare.

Garbage Collector (GC) automatically un objects ko dhoondh kar hata deta hai jinki koi reference nahi bachi — Java mein manually memory free karne ki zaroorat nahi padti.

void createObjects() {
  Student s = new Student(); // heap par banta hai
} // method khatam -> s ab unreachable -> GC eligible
Animation
💡 Static block ek building ka "ek-baar-hone-wala" inauguration hai — class load hote hi sirf ek baar chalta hai. Cloning ek photocopier hai jo object ki hoobahoo copy bana deta hai. Serialization ek suitcase mein object ko pack karke kahin bhej dena hai, taaki baad mein wahi cheez wapas nikal (deserialize) sako.

Static block { } class load hote hi ek baar chalta hai — static variables initialize karne ke liye best. Instance block har object banते waqt chalta hai (constructor se pehle).

clone() Object class ka method hai jo ek existing object ki copy bana deta hai (Cloneable interface implement karna padta hai).

Serializable interface implement karke object ko bytes mein convert kar sakte ho (jaise file mein save karna ya network par bhejna), aur baad mein deserialize karke wapas object bana sakte ho.

class Config implements Cloneable, Serializable {
  static { System.out.println("Loaded once!"); }
  int value = 10;
}
Animation