📖 Deep Theory — Package Ki Puri Kahani
Java mein jab hum bade projects banate hain toh hazaaron classes hoti hain. Agar sab ek hi jagah rakhein toh chaos ho jaayega. Package is problem ka solution hai.
Package basically ek namespace mechanism hai jo related Java classes, interfaces, enums, aur annotations ko logically organize karta hai. Physically yeh computer ke folder/directory ke roop mein hota hai.
Package ke 3 main kaam hain:
- Organization: Related classes ko ek jagah rakhta hai — jaise
com.bank.model mein Account, Customer, Transaction classes hongi
- Namespace Management: Do alag jagah ek jaisi naam ki class ho sakti hai bina conflict ke —
java.util.Date aur java.sql.Date dono exist karte hain
- Access Control: Package-level visibility control karta hai — default access sirf same package mein work karta hai
Package ke 2 main types hain:
- Built-in Packages: Java ke saath pehle se aate hain —
java.lang, java.util, java.io, java.math, java.net, javax.swing
- User-defined Packages: Hum khud banate hain apne project ke liye —
com.amazon.order, com.paytm.payment
🏢 Real-World Analogy — Company Office
Socho ek badi company hai. Usme alag-alag departments hain — HR, Finance, IT, Marketing. Har department mein alag log aur documents hain. com.company.hr, com.company.finance, com.company.it — exactly aise hi Java packages kaam karte hain. Ek department ke documents doosre department automatically accessible nahi hote — theek waise hi package-private access kaam karta hai!
⚡ KEY POINTS
Main Purpose
Organize Classes
Physical Form
Folder/Directory
// Jab hum package declare NAHI karte
// class automatically "default package" mein jaati hai
// Production mein DEFAULT PACKAGE use karna AVOID karo!
public class HelloJava {
public static void main(String[] args) {
System.out.println("Namaste! Main default package mein hoon.");
System.out.println("Mere paas koi package nahi hai.");
System.out.println("Yeh sirf beginners ke liye theek hai.");
System.out.println("Real projects mein hamesha package use karo!");
}
}
Output
Namaste! Main default package mein hoon.
Mere paas koi package nahi hai.
Yeh sirf beginners ke liye theek hai.
Real projects mein hamesha package use karo!
// PROBLEM DEMONSTRATE KARTE HAIN
// java.util.Date aur java.sql.Date dono ka naam "Date" hai
// Package ki wajah se dono alag hain — koi conflict nahi!
public class NameConflict {
public static void main(String[] args) {
// Full Qualified Name use karke dono alag classes use kar sakte hain
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(0);
System.out.println("=== Package Ne Naam Conflict Solve Kiya ===");
System.out.println("java.util.Date → " + utilDate.getClass().getName());
System.out.println("java.sql.Date → " + sqlDate.getClass().getName());
System.out.println("\nDono 'Date' hain lekin ALAG packages mein!");
System.out.println("Agar package nahi hota toh → COMPILE ERROR!");
}
}
Output
=== Package Ne Naam Conflict Solve Kiya ===
java.util.Date → java.util.Date
java.sql.Date → java.sql.Date
Dono 'Date' hain lekin ALAG packages mein!
Agar package nahi hota toh → COMPILE ERROR!
// Package organization ka faayda dikhate hain
// Imagine karo ek project mein ye sab classes hain
public class PackageDemo {
public static void main(String[] args) {
System.out.println("=== E-Commerce Project Package Structure ===");
System.out.println();
// Without packages — CHAOS
System.out.println("❌ Bina Package ke (All in one folder):");
String[] chaos = {
"User.java", "Product.java", "Order.java", "Payment.java",
"UserService.java", "ProductService.java", "UserRepo.java",
"UserController.java", "DBHelper.java", "EmailUtil.java"
};
for (String f : chaos) System.out.println(" 📄 " + f);
System.out.println();
System.out.println("✅ Package ke saath (Organized):");
String[][] organized = {
{"com.shop.model", "User, Product, Order, Payment"},
{"com.shop.service", "UserService, ProductService"},
{"com.shop.repository", "UserRepo, ProductRepo"},
{"com.shop.controller", "UserController, OrderController"},
{"com.shop.util", "DBHelper, EmailUtil"}
};
for (String[] pkg : organized)
System.out.printf(" 📁 %-25s → %s%n", pkg[0], pkg[1]);
}
}
Output
=== E-Commerce Project Package Structure ===
❌ Bina Package ke (All in one folder):
📄 User.java
📄 Product.java ... (10 files, confusion!)
✅ Package ke saath (Organized):
📁 com.shop.model → User, Product, Order, Payment
📁 com.shop.service → UserService, ProductService
📁 com.shop.repository → UserRepo, ProductRepo
📁 com.shop.controller → UserController, OrderController
📁 com.shop.util → DBHelper, EmailUtil
import java.util.ArrayList;
import java.math.BigDecimal;
public class PackageTypes {
public static void main(String[] args) {
// ── Built-in package classes use kar rahe hain ──
ArrayList<String> builtIn = new ArrayList<>();
builtIn.add("java.lang → String, Math, System, Thread");
builtIn.add("java.util → ArrayList, HashMap, Scanner");
builtIn.add("java.io → File, BufferedReader, FileWriter");
builtIn.add("java.math → BigInteger, BigDecimal");
builtIn.add("java.net → URL, Socket, HttpURLConnection");
System.out.println("=== Built-in Java Packages ===");
builtIn.forEach(p -> System.out.println(" 📦 " + p));
// Math class (java.lang.Math) — auto-imported, explicit import nahi chahiye
System.out.println("\n--- java.lang.Math se calculations ---");
System.out.println("sqrt(625) = " + Math.sqrt(625));
System.out.println("pow(2, 10) = " + (int)Math.pow(2, 10));
// BigDecimal (java.math) — banking ke liye
BigDecimal balance = new BigDecimal("99999.75");
System.out.println("\n--- java.math.BigDecimal ---");
System.out.println("Bank Balance: ₹" + balance);
}
}
Output
=== Built-in Java Packages ===
📦 java.lang → String, Math, System, Thread
📦 java.util → ArrayList, HashMap, Scanner
📦 java.io → File, BufferedReader, FileWriter
📦 java.math → BigInteger, BigDecimal
📦 java.net → URL, Socket, HttpURLConnection
--- java.lang.Math se calculations ---
sqrt(625) = 25.0
pow(2, 10) = 1024
--- java.math.BigDecimal ---
Bank Balance: ₹99999.75
import java.util.ArrayList;
import java.util.Date;
public class PackageInfo {
public static void main(String[] args) {
// Kisi bhi class ka package info nikaal sakte hain
Class<?>[] classes = {
String.class,
ArrayList.class,
Date.class,
Math.class,
Integer.class,
java.io.File.class,
java.math.BigDecimal.class
};
System.out.println("=== Class ka Package Information ===");
System.out.printf("%-16s %-30s%n", "CLASS", "PACKAGE");
System.out.println("─".repeat(48));
for (Class<?> c : classes) {
Package pkg = c.getPackage();
System.out.printf("%-16s %s%n",
c.getSimpleName(),
pkg != null ? pkg.getName() : "(default)");
}
// Number of classes info
System.out.println("\nTotal classes checked: " + classes.length);
}
}
Output
=== Class ka Package Information ===
CLASS PACKAGE
────────────────────────────────────────────────
String java.lang
ArrayList java.util
Date java.util
Math java.lang
Integer java.lang
File java.io
BigDecimal java.math
Total classes checked: 7
📖 Package Declaration — Puri Theory
Apna package banane ke liye Java file ki bilkul pehli line mein package keyword likhte hain. Yeh Java compiler ko batata hai ki "yeh class is package mein hai."
3 Important Rules:
- Pehli Line: Package statement HAMESHA file ki first executable line honi chahiye. Sirf blank lines aur comments pehle aa sakte hain — koi import, koi class declaration nahi
- Ek hi Package: Ek Java file mein sirf ek package declaration ho sakti hai
- Folder Match: Package name aur folder structure match karni chahiye. Agar package
com.myapp.model hai toh file com/myapp/model/ folder mein hogi
Compilation: javac -d . FileName.java — yahan -d . flag automatically sahi folder structure create karta hai!
📝 Syntax
package packageName; // simple — avoid in production
package com.company.project; // standard — always use this format
package com.company.project.module; // sub-package
// Compilation:
javac -d . MyClass.java // -d . se folders auto-create hote hain
java com.company.MyClass // run karte waqt full package name
⚠️
Golden Rule: Ek Java file mein order hamesha: package → import → class. Yeh order kabhi ulta nahi hoga, warna COMPILE ERROR aayega!
// File location: com/school/Student.java
// Compile: javac -d . Student.java
// Run: java com.school.Student
package com.school; // ← MANDATORY: File ki pehli line
public class Student {
private String name;
private int rollNo;
private double percentage;
private String grade;
public Student(String name, int rollNo, double pct) {
this.name = name;
this.rollNo = rollNo;
this.percentage = pct;
this.grade = calcGrade(pct);
}
private String calcGrade(double pct) {
if (pct >= 90) return "A+";
if (pct >= 80) return "A";
if (pct >= 70) return "B";
if (pct >= 60) return "C";
return "F";
}
public void display() {
System.out.printf("%-5d %-15s %6.1f%% Grade: %s%n",
rollNo, name, percentage, grade);
}
public static void main(String[] args) {
Student[] students = {
new Student("Rahul Kumar", 101, 92.5),
new Student("Priya Sharma", 102, 85.0),
new Student("Amit Verma", 103, 73.8),
new Student("Neha Singh", 104, 58.2)
};
System.out.println("Package: com.school");
System.out.println("Roll Name %age Grade");
System.out.println("─".repeat(42));
for (Student s : students) s.display();
}
}
Output
Package: com.school
Roll Name %age Grade
──────────────────────────────────────────
101 Rahul Kumar 92.5% Grade: A+
102 Priya Sharma 85.0% Grade: A
103 Amit Verma 73.8% Grade: B
104 Neha Singh 58.2% Grade: F
package com.bank;
public class Account {
private String accNo;
private String owner;
private double balance;
private int txCount = 0;
public Account(String accNo, String owner, double initBalance) {
this.accNo = accNo;
this.owner = owner;
this.balance = initBalance;
}
public void deposit(double amount) {
if (amount <= 0) { System.out.println("❌ Invalid amount!"); return; }
balance += amount;
txCount++;
System.out.printf("[TX-%03d] ✅ Credited ₹%8.2f | Balance: ₹%.2f%n", txCount, amount, balance);
}
public void withdraw(double amount) {
if (amount <= 0) { System.out.println("❌ Invalid amount!"); return; }
if (amount > balance) { System.out.println("❌ Insufficient Balance!"); return; }
balance -= amount;
txCount++;
System.out.printf("[TX-%03d] ✅ Debited ₹%8.2f | Balance: ₹%.2f%n", txCount, amount, balance);
}
public void statement() {
System.out.println("\n────── Account Statement ──────");
System.out.println("Account: " + accNo + " | Owner: " + owner);
System.out.printf("Balance: ₹%.2f | Transactions: %d%n", balance, txCount);
System.out.println("──────────────────────────────");
}
public static void main(String[] args) {
System.out.println("=== Package: com.bank ===");
Account acc = new Account("SBI-001", "Rahul Kumar", 10000.0);
acc.deposit(5000);
acc.withdraw(2500);
acc.deposit(1500);
acc.withdraw(20000); // should fail
acc.statement();
}
}
Output
=== Package: com.bank ===
[TX-001] ✅ Credited ₹ 5000.00 | Balance: ₹15000.00
[TX-002] ✅ Debited ₹ 2500.00 | Balance: ₹12500.00
[TX-003] ✅ Credited ₹ 1500.00 | Balance: ₹14000.00
❌ Insufficient Balance!
────── Account Statement ──────
Account: SBI-001 | Owner: Rahul Kumar
Balance: ₹14000.00 | Transactions: 3
// File: com/shapes/Shape.java
package com.shapes;
public interface Shape {
double area();
double perimeter();
default String info() {
return String.format("%s → Area: %.2f | Perimeter: %.2f",
getClass().getSimpleName(), area(), perimeter());
}
}
// File: com/shapes/Circle.java
package com.shapes;
public class Circle implements Shape {
private double r;
public Circle(double r) { this.r = r; }
public double area() { return Math.PI * r * r; }
public double perimeter() { return 2 * Math.PI * r; }
}
// File: com/shapes/Rectangle.java
package com.shapes;
public class Rectangle implements Shape {
private double l, w;
public Rectangle(double l, double w) { this.l = l; this.w = w; }
public double area() { return l * w; }
public double perimeter() { return 2 * (l + w); }
}
// File: com/shapes/Triangle.java
package com.shapes;
public class Triangle implements Shape {
private double a, b, c;
public Triangle(double a, double b, double c) { this.a=a; this.b=b; this.c=c; }
public double area() {
double s = (a+b+c)/2;
return Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
public double perimeter() { return a + b + c; }
}
// Test class (same package mein)
package com.shapes;
public class ShapeTest {
public static void main(String[] args) {
Shape[] shapes = {
new Circle(7),
new Rectangle(6, 4),
new Triangle(3, 4, 5)
};
System.out.println("=== Package: com.shapes ===");
for (Shape s : shapes)
System.out.println(" → " + s.info());
}
}
Output
=== Package: com.shapes ===
→ Circle → Area: 153.94 | Perimeter: 43.98
→ Rectangle → Area: 24.00 | Perimeter: 20.00
→ Triangle → Area: 6.00 | Perimeter: 12.00
package com.ecom;
public enum OrderStatus {
PENDING("⏳", "Order received, processing..."),
CONFIRMED("✅", "Payment confirmed"),
PACKED("📦", "Items packed"),
SHIPPED("🚚", "Out for delivery"),
DELIVERED("🎉", "Successfully delivered"),
CANCELLED("❌", "Order cancelled");
private final String icon, desc;
OrderStatus(String icon, String desc) { this.icon=icon; this.desc=desc; }
public void print() { System.out.println(" Status: " + icon + " " + name() + " — " + desc); }
}
// Order class — same package
package com.ecom;
public class Order {
private int id;
private String item;
private OrderStatus status;
public Order(int id, String item) {
this.id = id; this.item = item;
this.status = OrderStatus.PENDING;
}
public void update(OrderStatus s) {
this.status = s;
System.out.println("\n[Order #" + id + "] Item: " + item);
s.print();
}
public static void main(String[] args) {
Order o = new Order(501, "Laptop — Dell Inspiron");
o.update(OrderStatus.CONFIRMED);
o.update(OrderStatus.PACKED);
o.update(OrderStatus.SHIPPED);
o.update(OrderStatus.DELIVERED);
}
}
Output
[Order #501] Item: Laptop — Dell Inspiron
Status: ✅ CONFIRMED — Payment confirmed
[Order #501] Item: Laptop — Dell Inspiron
Status: 📦 PACKED — Items packed
[Order #501] Item: Laptop — Dell Inspiron
Status: 🚚 SHIPPED — Out for delivery
[Order #501] Item: Laptop — Dell Inspiron
Status: 🎉 DELIVERED — Successfully delivered
📖 Import Statement — Complete Theory
Jab tumhe doosre package ki class use karni ho, toh Java ko batana padta hai ki woh class kahan se leni hai. Iske liye import statement use hoti hai.
Import statement kaam kaise karta hai? Java compiler jab code compile karta hai, toh import statements ko dekhkar samajhta hai ki kaunsi class, kahan se chahiye. Yeh sirf compile-time shortcut hai — runtime par koi farak nahi padta.
3 Tarike hain classes use karne ke:
- Specific Import —
import java.util.ArrayList; — Sirf ek specific class import. Best practice!
- Wildcard Import —
import java.util.*; — Poore package ki saari classes. Convenient lekin risky (name conflicts)
- Fully Qualified Name —
java.util.ArrayList list = new java.util.ArrayList(); — Koi import nahi, seedha full name. Verbose lekin 100% clear
Misconception: import java.util.* sirf package ki directly available classes import karta hai, sub-packages nahi! Toh import java.util.* se java.util.concurrent.atomic.AtomicInteger NAHI milega.
| Type | Syntax | Pros | Cons |
| Specific | import java.util.List; | Clear, readable, IDE-friendly | Multiple lines for many classes |
| Wildcard | import java.util.*; | Short, convenient | Ambiguous, name conflicts possible |
| Fully Qualified | java.util.Scanner sc | No conflicts ever | Very verbose code |
// ✅ SPECIFIC IMPORT — har class individually import karo
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.TreeMap;
public class SpecificImport {
public static void main(String[] args) {
// ArrayList — dynamic array
ArrayList<String> fruits = new ArrayList<>();
fruits.add("🍎 Apple"); fruits.add("🥭 Mango");
fruits.add("🍌 Banana"); fruits.add("🍊 Orange");
System.out.println("ArrayList: " + fruits);
// HashMap — key-value pairs
HashMap<String, Integer> prices = new HashMap<>();
prices.put("Apple", 80); prices.put("Mango", 60);
prices.put("Banana", 40); prices.put("Orange", 50);
System.out.println("Prices: " + prices);
// LinkedList — doubly linked list
LinkedList<Integer> queue = new LinkedList<>();
queue.add(10); queue.add(20); queue.add(30);
System.out.println("Queue peek: " + queue.peek() + " | size: " + queue.size());
// TreeMap — sorted key-value
TreeMap<String, Integer> sorted = new TreeMap<>(prices);
System.out.println("Sorted Prices: " + sorted);
}
}
Output
ArrayList: [🍎 Apple, 🥭 Mango, 🍌 Banana, 🍊 Orange]
Prices: {Apple=80, Mango=60, Banana=40, Orange=50}
Queue peek: 10 | size: 3
Sorted Prices: {Apple=80, Banana=40, Mango=60, Orange=50}
// Wildcard import — saari classes ek saath
import java.util.*;
public class WildcardDemo {
public static void main(String[] args) {
// java.util.* se milne waali classes
List<String> list = new ArrayList<>(
Arrays.asList("Zara", "Amit", "Priya", "Kiran"));
// Collections utility class
System.out.println("Before sort: " + list);
Collections.sort(list);
System.out.println("After sort: " + list);
Collections.reverse(list);
System.out.println("Reversed: " + list);
// Set — unique values only
Set<Integer> set = new HashSet<>(
Arrays.asList(5, 3, 8, 3, 1, 5)); // duplicates removed
System.out.println("Set (unique): " + new TreeSet<>(set));
// Stack
Stack<String> stack = new Stack<>();
stack.push("First"); stack.push("Second"); stack.push("Third");
System.out.println("Stack top: " + stack.peek());
System.out.println("Popped: " + stack.pop() + " | Remaining: " + stack.size());
// NOTE: wildcard * sirf java.util tak — sub-packages nahi!
// java.util.concurrent.* ko alag import karna hoga!
System.out.println("\n⚠️ import java.util.* se java.util.concurrent milta NAHI!");
}
}
Output
Before sort: [Zara, Amit, Priya, Kiran]
After sort: [Amit, Kiran, Priya, Zara]
Reversed: [Zara, Priya, Kiran, Amit]
Set (unique): [1, 3, 5, 8]
Stack top: Third
Popped: Third | Remaining: 2
⚠️ import java.util.* se java.util.concurrent milta NAHI!
// Koi bhi import nahi! Seedha full name use kar rahe hain
// Yeh tab useful hai jab name conflicts ho
public class FullyQualified {
public static void main(String[] args) {
// java.util.Date aur java.sql.Date dono ek saath — ZERO conflict
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(0);
System.out.println("util.Date class: " + utilDate.getClass().getName());
System.out.println("sql.Date class: " + sqlDate.getClass().getName());
// ArrayList — fully qualified
java.util.ArrayList<String> names = new java.util.ArrayList<>();
names.add("Using fully");
names.add("qualified");
names.add("names!");
System.out.println("\nNames: " + names);
// Scanner with fully qualified name
System.out.println("\njava.util.Scanner se input le sakte hain");
System.out.println("java.io.PrintWriter se file write kar sakte hain");
System.out.println("\n📝 Note: Yeh readable nahi — import prefer karo!");
}
}
Output
util.Date class: java.util.Date
sql.Date class: java.sql.Date
Names: [Using fully, qualified, names!]
java.util.Scanner se input le sakte hain
java.io.PrintWriter se file write kar sakte hain
📝 Note: Yeh readable nahi — import prefer karo!
// ── File 1: com/utils/Calculator.java ──
package com.utils;
public class Calculator {
public static double add(double a, double b) { return a + b; }
public static double subtract(double a, double b) { return a - b; }
public static double multiply(double a, double b) { return a * b; }
public static double divide(double a, double b) {
if (b == 0) throw new ArithmeticException("Division by zero!");
return a / b;
}
public static double power(double base, double exp) {
return Math.pow(base, exp);
}
public static double percentage(double val, double total) {
return (val / total) * 100;
}
}
// ── File 2: Main.java (root mein) ──
import com.utils.Calculator; // ← custom package import
public class Main {
public static void main(String[] args) {
System.out.println("=== Custom Package Import Demo ===");
System.out.printf("15 + 7 = %.1f%n", Calculator.add(15, 7));
System.out.printf("15 - 7 = %.1f%n", Calculator.subtract(15, 7));
System.out.printf("15 * 7 = %.1f%n", Calculator.multiply(15, 7));
System.out.printf("22 / 7 = %.4f%n", Calculator.divide(22, 7));
System.out.printf("2^10 = %.0f%n", Calculator.power(2, 10));
System.out.printf("75/100%% = %.1f%%%n", Calculator.percentage(75, 100));
}
}
Output
=== Custom Package Import Demo ===
15 + 7 = 22.0
15 - 7 = 8.0
15 * 7 = 105.0
22 / 7 = 3.1429
2^10 = 1024
75/100% = 75.0%
📖 Access Modifiers — Complete Theory
Java mein 4 access modifiers hain jo control karte hain ki kaunsi class/method/variable, kahan se accessible hai. Package ke saath inka bahut strong connection hai.
1. private: Sirf usi class ke andar accessible. Duniya ki koi aur class — same package ho ya different — access nahi kar sakti. Best for data hiding (encapsulation).
2. default (no keyword): Package-private bhi kehte hain. Sirf same package mein accessible. Doosre package mein bilkul nahi — chahe subclass ho. Agar koi modifier nahi likha toh yahi hota hai.
3. protected: Same package + doosre packages ki subclasses mein accessible. Inheritance ke saath use hota hai.
4. public: Har jagah se accessible — same package, different package, anywhere in the world!
Golden Rule: Minimum access do! private sabse pehle socho, phir default, phir protected, aur public sirf tab jab zaroorat ho. Yahi Encapsulation ka matlab hai!
| Modifier | Same Class | Same Package | Subclass (diff pkg) | Any Class |
| private |
✅ Yes |
❌ No |
❌ No |
❌ No |
| default |
✅ Yes |
✅ Yes |
❌ No |
❌ No |
| protected |
✅ Yes |
✅ Yes |
✅ Yes |
❌ No |
| public |
✅ Yes |
✅ Yes |
✅ Yes |
✅ Yes |
public class BankVault {
private String vaultCode = "SECRET-7829"; // ← PRIVATE — sirf is class mein
private double totalCash = 9_50_00_000.00;
private boolean authenticate(String code) {
return vaultCode.equals(code);
}
// PUBLIC method — bahar wale isi se interact kar sakte hain
public boolean access(String enteredCode) {
if (authenticate(enteredCode)) { // private method andar se call kar sakte hain
System.out.println("✅ Vault open! Cash: ₹" + totalCash);
return true;
}
System.out.println("❌ Wrong code! Access denied.");
return false;
}
public static void main(String[] args) {
BankVault vault = new BankVault();
// ❌ Direct access attempt — compile error hoga
// System.out.println(vault.vaultCode); // ERROR: private!
// vault.authenticate("any"); // ERROR: private!
// ✅ Public method se access
vault.access("WRONG-CODE");
vault.access("SECRET-7829");
System.out.println("\n📌 private members: class ke bahar koi access nahi!");
}
}
Output
❌ Wrong code! Access denied.
✅ Vault open! Cash: ₹9.5E7
📌 private members: class ke bahar koi access nahi!
// File 1: com/demo/Helper.java
package com.demo;
class Helper { // ← DEFAULT class — no public keyword
String message = "Hello"; // ← DEFAULT field
void greet(String name) { // ← DEFAULT method
System.out.println(message + ", " + name + "! (from com.demo.Helper)");
}
}
// File 2: com/demo/Tester.java — SAME PACKAGE — can access!
package com.demo;
public class Tester {
public static void main(String[] args) {
Helper h = new Helper(); // ✅ Same package — accessible
h.message = "Namaste"; // ✅ Default field — accessible
h.greet("Rahul"); // ✅ Default method — accessible
h.message = "Aadab";
h.greet("Priya");
System.out.println("\n📌 Default access = Same Package Only!");
System.out.println(" Doosre package se Helper ka use NAHI hoga!");
}
}
// File 3: com/other/Outside.java — DIFFERENT PACKAGE — Error!
// package com.other;
// import com.demo.Helper; ← ERROR: Helper is not public
// public class Outside {
// Helper h = new Helper(); ← COMPILE ERROR!
// }
Output
Namaste, Rahul! (from com.demo.Helper)
Aadab, Priya! (from com.demo.Helper)
📌 Default access = Same Package Only!
Doosre package se Helper ka use NAHI hoga!
// com/vehicle/Vehicle.java
package com.vehicle;
public class Vehicle {
protected String brand; // ← protected — subclass accessible
protected int speed; // ← protected
private String engineCode; // ← private — nobody else
public Vehicle(String brand, int speed) {
this.brand = brand;
this.speed = speed;
this.engineCode = "ENG-" + (int)(Math.random() * 9999);
}
protected void showBase() { // ← protected method
System.out.println("Brand: " + brand + " | Speed: " + speed + " km/h");
}
}
// com/car/Car.java — DIFFERENT PACKAGE — extends Vehicle
package com.car;
import com.vehicle.Vehicle;
public class Car extends Vehicle {
private int doors;
private String type;
public Car(String brand, int speed, int doors, String type) {
super(brand, speed);
this.doors = doors; this.type = type;
}
public void display() {
showBase(); // ✅ protected — accessible in subclass
System.out.println("Type: " + type + " | Doors: " + doors);
// System.out.println(engineCode); // ❌ COMPILE ERROR — private!
}
public static void main(String[] args) {
Car[] cars = {
new Car("Maruti Swift", 150, 4, "Hatchback"),
new Car("Honda City", 180, 4, "Sedan"),
new Car("BMW M3", 290, 2, "Sports")
};
for (Car c : cars) { c.display(); System.out.println("──"); }
}
}
Output
Brand: Maruti Swift | Speed: 150 km/h
Type: Hatchback | Doors: 4
──
Brand: Honda City | Speed: 180 km/h
Type: Sedan | Doors: 4
──
Brand: BMW M3 | Speed: 290 km/h
Type: Sports | Doors: 2
public class AccessDemo {
public String publicVar = "PUBLIC — sabko dikhe";
protected String protectedVar = "PROTECTED — pkg + subclass";
String defaultVar = "DEFAULT — sirf same package";
private String privateVar = "PRIVATE — sirf yahan";
public void showAll() {
// Is class ke andar SABHHI accessible hain
System.out.println("=== Andar se (Same Class) ===");
System.out.println("✅ public: " + publicVar);
System.out.println("✅ protected: " + protectedVar);
System.out.println("✅ default: " + defaultVar);
System.out.println("✅ private: " + privateVar);
}
public static void main(String[] args) {
AccessDemo obj = new AccessDemo();
obj.showAll();
System.out.println("\n=== Main se (Same Class) ===");
System.out.println("✅ public: " + obj.publicVar);
System.out.println("✅ protected: " + obj.protectedVar);
System.out.println("✅ default: " + obj.defaultVar);
System.out.println("✅ private: " + obj.privateVar);
System.out.println("\n=== Access Modifier Summary ===");
System.out.println("private → Only THIS class");
System.out.println("default → Same package only");
System.out.println("protected → Package + subclasses");
System.out.println("public → Everywhere");
}
}
Output
=== Andar se (Same Class) ===
✅ public: PUBLIC — sabko dikhe
✅ protected: PROTECTED — pkg + subclass
✅ default: DEFAULT — sirf same package
✅ private: PRIVATE — sirf yahan
=== Access Modifier Summary ===
private → Only THIS class
default → Same package only
protected → Package + subclasses
public → Everywhere
📖 Java Standard Library — Complete Theory
Java ke saath ek huge standard library aati hai jisme hazaaron ready-made classes hain. Inhe Java Standard Edition (SE) API kehte hain. Backend developer ko inhe acche se jaanna zaroori hai.
java.lang: Java ka sabse important package. Auto-imported hota hai — explicitly likhna nahi padta. Isme hain: String, Math, System, Object, Integer, Boolean, Thread, Exception
java.util: Utility classes. Backend mein sabse zyada use hota hai. Isme Collections Framework (List, Map, Set, Queue), Scanner, Random, Date, Optional, Arrays, Collections
java.io: Input/Output operations — File reading, writing. File, FileReader, BufferedReader, FileWriter, InputStream, OutputStream
java.math: Precise mathematics — Banking/Finance ke liye. BigDecimal (exact decimal), BigInteger (huge numbers), MathContext, RoundingMode
java.net: Network programming. URL, HttpURLConnection, Socket, ServerSocket, InetAddress
// java.lang AUTOMATIC import hota hai — explicitly import nahi karna!
public class JavaLangDemo {
public static void main(String[] args) {
// ── String class ──
String s = " Hello Backend World! ";
System.out.println("Original: '" + s + "'");
System.out.println("Trimmed: '" + s.trim() + "'");
System.out.println("Upper: '" + s.trim().toUpperCase() + "'");
System.out.println("Contains 'Backend': " + s.contains("Backend"));
System.out.println("Replace: '" + s.trim().replace("Backend", "Java") + "'");
// ── Math class ──
System.out.println("\n--- Math Operations ---");
System.out.printf("sqrt(144) = %.1f%n", Math.sqrt(144));
System.out.println("min(5,9) = " + Math.min(5, 9));
System.out.println("max(5,9) = " + Math.max(5, 9));
System.out.println("abs(-42) = " + Math.abs(-42));
System.out.printf("PI = %.5f%n", Math.PI);
// ── Integer Wrapper ──
System.out.println("\n--- Integer Wrapper Class ---");
System.out.println("parseInt('42'): " + Integer.parseInt("42"));
System.out.println("toBinary(10): " + Integer.toBinaryString(10));
System.out.println("toHex(255): " + Integer.toHexString(255));
System.out.println("MAX_VALUE: " + Integer.MAX_VALUE);
// ── System class ──
System.out.println("\n--- System Class ---");
System.out.println("JVM Version: " + System.getProperty("java.version"));
System.out.println("OS Name: " + System.getProperty("os.name"));
System.out.println("Time (ms): " + System.currentTimeMillis());
}
}
Output
Original: ' Hello Backend World! '
Trimmed: 'Hello Backend World!'
Upper: 'HELLO BACKEND WORLD!'
Contains 'Backend': true
Replace: 'Hello Java World!'
--- Math Operations ---
sqrt(144) = 12.0
min(5,9) = 5
max(5,9) = 9
abs(-42) = 42
PI = 3.14159
--- Integer Wrapper Class ---
parseInt('42'): 42
toBinary(10): 1010
toHex(255): ff
MAX_VALUE: 2147483647
import java.util.*;
public class JavaUtilDemo {
public static void main(String[] args) {
// ── ArrayList ──
List<String> cities = new ArrayList<>(
Arrays.asList("Mumbai", "Delhi", "Indore", "Pune", "Bengaluru"));
Collections.sort(cities);
System.out.println("Sorted cities: " + cities);
System.out.println("Min city: " + Collections.min(cities));
// ── HashMap ──
Map<String, Integer> pop = new HashMap<>();
pop.put("Mumbai", 2080); pop.put("Delhi", 1900);
pop.put("Indore", 360); pop.put("Pune", 700);
System.out.println("\nCity populations (lakhs):");
new TreeMap<>(pop).forEach((k,v) ->
System.out.printf(" %-12s → %d L%n", k, v));
// ── Optional (Java 8) ──
Optional<String> found = cities.stream()
.filter(c -> c.startsWith("I"))
.findFirst();
System.out.println("\nCity starting with I: " + found.orElse("Not found"));
// ── Random — OTP generate karo ──
Random rnd = new Random();
int otp = 100000 + rnd.nextInt(900000);
System.out.println("Generated OTP: " + otp);
// ── Queue (LinkedList as Queue) ──
Queue<String> ticketQ = new LinkedList<>();
ticketQ.add("Person1"); ticketQ.add("Person2"); ticketQ.add("Person3");
System.out.println("\nTicket Queue:");
while (!ticketQ.isEmpty())
System.out.println(" Serving: " + ticketQ.poll());
}
}
Output
Sorted cities: [Bengaluru, Delhi, Indore, Mumbai, Pune]
Min city: Bengaluru
City populations (lakhs):
Delhi → 1900 L
Indore → 360 L
Mumbai → 2080 L
Pune → 700 L
City starting with I: Indore
Generated OTP: 487392
Ticket Queue:
Serving: Person1
Serving: Person2
Serving: Person3
import java.io.*;
public class JavaIODemo {
public static void main(String[] args) {
String file = "students.csv";
// ── Write to file ──
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write("Name,Marks,Grade\n");
bw.write("Rahul,88,A\n");
bw.write("Priya,95,A+\n");
bw.write("Amit,72,B\n");
bw.write("Neha,65,C\n");
System.out.println("✅ File written: " + file);
} catch (IOException e) {
System.out.println("❌ Write error: " + e.getMessage());
}
// ── Read from file ──
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
System.out.println("\n📄 Reading CSV file:");
System.out.printf("%-12s %-8s %-6s%n", "Name", "Marks", "Grade");
System.out.println("─".repeat(28));
String line = br.readLine(); // skip header
while ((line = br.readLine()) != null) {
String[] parts = line.split(",");
System.out.printf("%-12s %-8s %-6s%n", parts[0], parts[1], parts[2]);
}
} catch (IOException e) {
System.out.println("❌ Read error: " + e.getMessage());
}
// File info
File f = new File(file);
System.out.printf("%nFile: %s | Size: %d bytes | Exists: %b%n",
f.getName(), f.length(), f.exists());
f.delete(); // cleanup
System.out.println("Cleaned up. Exists now: " + f.exists());
}
}
Output
✅ File written: students.csv
📄 Reading CSV file:
Name Marks Grade
────────────────────────────
Rahul 88 A
Priya 95 A+
Amit 72 B
Neha 65 C
File: students.csv | Size: 52 bytes | Exists: true
Cleaned up. Exists now: false
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
public class BigDecimalDemo {
public static void main(String[] args) {
// PROBLEM: double precision issue
System.out.println("=== Floating Point Problem ===");
System.out.println("double 0.1+0.2 = " + (0.1 + 0.2)); // 0.30000000000000004 !!!
// SOLUTION: BigDecimal
System.out.println("BigDecimal: " + new BigDecimal("0.1").add(new BigDecimal("0.2")));
// Banking use case
System.out.println("\n=== Salary Calculation ===");
BigDecimal salary = new BigDecimal("85000.00");
BigDecimal taxRate = new BigDecimal("0.30");
BigDecimal pfRate = new BigDecimal("0.12");
BigDecimal tax = salary.multiply(taxRate);
BigDecimal pf = salary.multiply(pfRate);
BigDecimal inHand = salary.subtract(tax).subtract(pf);
System.out.println("Gross Salary : ₹" + salary);
System.out.println("Tax (30%) : ₹" + tax);
System.out.println("PF (12%) : ₹" + pf);
System.out.println("In-hand : ₹" + inHand);
// EMI calculation
System.out.println("\n=== Home Loan EMI ===");
BigDecimal loan = new BigDecimal("5000000");
BigDecimal months = new BigDecimal("240");
BigDecimal emi = loan.divide(months, 2, RoundingMode.HALF_UP);
System.out.println("₹50L / 20yr EMI (simple) = ₹" + emi);
// BigInteger — 25! factorial
System.out.println("\n=== BigInteger — Large Factorial ===");
BigInteger fact = BigInteger.ONE;
for (int i=1; i<=25; i++) fact = fact.multiply(BigInteger.valueOf(i));
System.out.println("25! = " + fact);
System.out.println("Digits: " + fact.toString().length());
}
}
Output
double 0.1+0.2 = 0.30000000000000004
BigDecimal: 0.3
=== Salary Calculation ===
Gross Salary : ₹85000.00
Tax (30%) : ₹25500.000
PF (12%) : ₹10200.000
In-hand : ₹49300.000
=== Home Loan EMI ===
₹50L / 20yr EMI (simple) = ₹20833.33
=== BigInteger — Large Factorial ===
25! = 15511210043330985984000000
Digits: 26
📖 Sub-Package — Deep Theory
Package ke andar package hona — issi ko Sub-Package kehte hain. Java mein sub-package sirf dot notation se banate hain. Physically yeh nested folders hain.
Example: java.util.concurrent — yahan concurrent ek sub-package hai java.util ke andar. Iska full path file system mein hoga: java/util/concurrent/
CRITICAL MISCONCEPTION: Bahut log sochte hain ki parent package import karne se sub-package bhi import ho jaata hai. BILKUL GALAT! import java.util.* se java.util.concurrent ki classes nahi miltin — dono ko alag-alag import karna padta hai. Java mein parent-child koi inheritance nahi hoti packages ke beech!
Why Sub-Packages? Real backend projects bahut bade hote hain — 50+ classes. Unhe logically organize karna padta hai. Standard hai: com.company.app.model, com.company.app.service, com.company.app.controller
💡
Big Rule: import java.util.* sirf java.util package ki classes import karta hai. java.util.concurrent.*, java.util.stream.* etc. ko alag import statement chahiye. Parent ka wildcard sub-package cover NAHI karta!
/*
* 📁 Hospital Management System
* com.hospital.model → Patient, Doctor, Appointment
* com.hospital.service → PatientService, DoctorService
* com.hospital.billing → Bill, Insurance
* com.hospital.util → DateHelper, Validator
*/
// ── com/hospital/model/Patient.java ──
package com.hospital.model;
public class Patient {
private int id;
private String name, bloodGroup;
private int age;
public Patient(int id, String name, int age, String blood) {
this.id=id; this.name=name; this.age=age; this.bloodGroup=blood;
}
public int getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
public String getBlood() { return bloodGroup; }
@Override
public String toString() {
return String.format("[P%03d] %-15s Age:%-3d Blood:%s", id, name, age, bloodGroup);
}
}
// ── com/hospital/service/PatientService.java ──
package com.hospital.service;
import com.hospital.model.Patient; // ← sub-package alag import
import java.util.*;
public class PatientService {
private List<Patient> patients = new ArrayList<>();
public void register(Patient p) {
patients.add(p);
System.out.println("✅ Registered: " + p.getName());
}
public void listAll() {
System.out.println("\n📋 All Patients:");
patients.forEach(System.out::println);
}
public Optional<Patient> findByBlood(String bg) {
return patients.stream().filter(p -> p.getBlood().equals(bg)).findFirst();
}
}
// ── Main entry point ──
import com.hospital.model.Patient; // ← model sub-package
import com.hospital.service.PatientService; // ← service sub-package
public class HospitalApp {
public static void main(String[] args) {
PatientService svc = new PatientService();
svc.register(new Patient(1, "Rahul Sharma", 35, "B+"));
svc.register(new Patient(2, "Priya Patel", 28, "O+"));
svc.register(new Patient(3, "Amit Verma", 45, "A-"));
svc.register(new Patient(4, "Neha Singh", 32, "B+"));
svc.listAll();
svc.findByBlood("O+").ifPresent(p ->
System.out.println("\nO+ donor found: " + p.getName()));
}
}
Output
✅ Registered: Rahul Sharma
✅ Registered: Priya Patel
✅ Registered: Amit Verma
✅ Registered: Neha Singh
📋 All Patients:
[P001] Rahul Sharma Age:35 Blood:B+
[P002] Priya Patel Age:28 Blood:O+
[P003] Amit Verma Age:45 Blood:A-
[P004] Neha Singh Age:32 Blood:B+
O+ donor found: Priya Patel
📖 Static Import — Complete Theory
Java 5 mein aaya ek feature — import static. Yeh tumhe kisi class ke static members (variables aur methods) ko class name ke bina directly use karne deta hai.
Normal way: Math.sqrt(25), Math.PI, Math.pow(2, 10) — bar-bar Math. likhna padta hai
Static import way: sqrt(25), PI, pow(2, 10) — class name bilkul nahi!
2 Types:
- Specific:
import static java.lang.Math.sqrt; — sirf sqrt import
- Wildcard:
import static java.lang.Math.*; — Math ke saare static members
Caution: Static import se code short zaroor hota hai lekin zyada use karne se readability kharab ho sakti hai — reader ko pata nahi chalega ki yeh method/variable kahan se aa raha hai. Sirf commonly-known utilities jaise Math ke liye use karo.
import static java.lang.Math.*; // Math ke sab static members
import static java.lang.System.out; // System.out ko sirf 'out' se use karo
public class StaticImportMath {
public static void main(String[] args) {
// Math. prefix ki zaroorat nahi!
out.println("=== Static Import Demo ===");
out.println("PI = " + PI);
out.println("E = " + E);
out.printf("sqrt(625) = %.1f%n", sqrt(625));
out.printf("pow(2, 10) = %.0f%n", pow(2, 10));
out.printf("sin(PI/2) = %.1f%n", sin(PI / 2));
out.printf("cos(0) = %.1f%n", cos(0));
out.printf("abs(-99) = %d%n", abs(-99));
out.printf("ceil(4.2) = %.1f%n", ceil(4.2));
out.printf("floor(4.9) = %.1f%n", floor(4.9));
out.printf("log(E) = %.1f%n", log(E));
// Geometry calculations — clean code!
out.println("\n--- Circle (radius=10) ---");
double r = 10;
out.printf("Area = %.4f%n", PI * pow(r, 2));
out.printf("Perimeter = %.4f%n", 2 * PI * r);
out.printf("Diagonal = %.4f%n", sqrt(2) * r);
// Hypotenuse of 3-4-5 triangle
out.printf("%nHypotenuse(3,4) = %.1f%n", sqrt(pow(3, 2) + pow(4, 2)));
}
}
Output
=== Static Import Demo ===
PI = 3.141592653589793
E = 2.718281828459045
sqrt(625) = 25.0
pow(2, 10) = 1024
sin(PI/2) = 1.0
cos(0) = 1.0
abs(-99) = 99
ceil(4.2) = 5.0
floor(4.9) = 4.0
--- Circle (radius=10) ---
Area = 314.1593
Perimeter = 62.8319
Hypotenuse(3,4) = 5.0
// ── AppConstants.java ──
package com.config;
public class AppConstants {
public static final String HOST = "localhost";
public static final int PORT = 8080;
public static final String DB_URL = "jdbc:mysql://localhost/mydb";
public static final int MAX_THREADS = 50;
public static final int SESSION_TIMEOUT = 3600;
public static final String VERSION = "v2.4.1";
public static String getBaseUrl() { return "http://" + HOST + ":" + PORT; }
public static String getApiUrl() { return getBaseUrl() + "/api"; }
}
// ── Server.java — static import use karo ──
import static com.config.AppConstants.*; // AppConstants. prefix nahi chahiye
public class Server {
public static void main(String[] args) {
// AppConstants prefix nahi lagate!
System.out.println("╔══════════════════════════════╗");
System.out.println("║ Server Configuration ║");
System.out.println("╚══════════════════════════════╝");
System.out.println("Version: " + VERSION);
System.out.println("Host: " + HOST);
System.out.println("Port: " + PORT);
System.out.println("DB URL: " + DB_URL);
System.out.println("Threads: " + MAX_THREADS);
System.out.println("Timeout: " + SESSION_TIMEOUT + " sec");
System.out.println("Base URL: " + getBaseUrl());
System.out.println("API URL: " + getApiUrl());
System.out.println("\n✅ Server started on " + getBaseUrl());
}
}
Output
╔══════════════════════════════╗
║ Server Configuration ║
╚══════════════════════════════╝
Version: v2.4.1
Host: localhost
Port: 8080
DB URL: jdbc:mysql://localhost/mydb
Threads: 50
Timeout: 3600 sec
Base URL: http://localhost:8080
API URL: http://localhost:8080/api
✅ Server started on http://localhost:8080
📖 Naming Rules — Complete Theory
Package naming ke liye Java community ne strict conventions define ki hain. Inhe follow karna zaroori hai — industry mein sab yahi karte hain.
Rule 1 — Lowercase Only: Package names hamesha lowercase mein hone chahiye. com.myapp ✅, com.MyApp ❌
Rule 2 — Reverse Domain Name: Globally unique package name ke liye apni company ki website ka domain reverse karke use karo. Google uses com.google, Paytm uses com.paytm, org ke liye org.apache
Rule 3 — Only Letters, Numbers, Underscore: Hyphen (-), dots (only between levels), spaces sab allowed nahi
Rule 4 — No Starting Digit: com.1app ❌, com.app1 ✅
Rule 5 — No Java Keywords: com.class.util ❌ (class is keyword)
Standard Backend Structure: com.{company}.{project}.{layer} jahan layer = model, service, repository, controller, util, config, exception, dto, security
| ❌ Wrong | ✅ Correct | Rule Violated |
| com.MyApp | com.myapp | Lowercase only |
| com.my-app.util | com.myapp.util | No hyphens |
| com.1stProject | com.project1 | No digit start |
| mypackage | com.company.mypackage | Use domain-based |
| com.my app | com.myapp | No spaces |
| com.class.utils | com.util.classes | No Java keywords |
/*
* ═══════════════════════════════════════════════════════
* REAL INDUSTRY PACKAGE EXAMPLES
* ═══════════════════════════════════════════════════════
*
* ── Famous Libraries ──
* org.springframework.boot ← Spring Boot
* com.google.gson ← Google Gson
* org.apache.commons.lang3 ← Apache Commons
* io.netty.channel ← Netty
* org.hibernate.orm ← Hibernate ORM
* com.fasterxml.jackson ← Jackson JSON
*
* ── Famous Companies ──
* com.flipkart.zeus.catalog ← Flipkart
* com.paytm.payments.gateway ← Paytm
* com.zomato.order.management ← Zomato
* in.ola.ride.booking ← Ola
* com.byju.learning.content ← BYJU's
*
* ── Standard Spring Boot Project ──
* com.company.myapp ← root package
* com.company.myapp.model ← data classes
* com.company.myapp.dto ← data transfer objects
* com.company.myapp.repository ← database layer
* com.company.myapp.service ← business logic
* com.company.myapp.controller ← REST APIs
* com.company.myapp.config ← configurations
* com.company.myapp.exception ← custom exceptions
* com.company.myapp.security ← auth/security
* com.company.myapp.util ← helper utilities
*/
package com.mycompany.hrms.employee;
public class Employee {
private String empId, name, dept;
private double salary;
public Employee(String id, String name, String dept, double sal) {
this.empId=id; this.name=name; this.dept=dept; this.salary=sal;
}
public static void main(String[] args) {
Employee[] team = {
new Employee("E01", "Rahul", "Backend", 75000),
new Employee("E02", "Priya", "Frontend", 65000),
new Employee("E03", "Amit", "DevOps", 85000),
new Employee("E04", "Kiran", "Database", 72000)
};
System.out.println("Package: com.mycompany.hrms.employee");
System.out.println("ID Name Department Salary");
System.out.println("─".repeat(42));
double total = 0;
for (Employee e : team) {
System.out.printf("%-5s %-10s %-14s ₹%.0f%n",
e.empId, e.name, e.dept, e.salary);
total += e.salary;
}
System.out.println("─".repeat(42));
System.out.printf("Total Payroll: ₹%.0f/month%n", total);
}
}
Output
Package: com.mycompany.hrms.employee
ID Name Department Salary
──────────────────────────────────────────
E01 Rahul Backend ₹75000
E02 Priya Frontend ₹65000
E03 Amit DevOps ₹85000
E04 Kiran Database ₹72000
──────────────────────────────────────────
Total Payroll: ₹297000/month
📖 MVC Architecture — Real Backend Theory
Real backend projects mein Layered Architecture ya MVC (Model-View-Controller) pattern use hota hai. Har layer ka ek specific kaam hota hai:
- model: Data classes — fields, getters, setters, constructors. Database tables ko represent karte hain
- repository: Database operations — CRUD (Create, Read, Update, Delete). Sirf data access logic
- service: Business logic — rules, validations, calculations. Repository use karta hai
- controller: Request handling — user/API ki request receive karta hai, service call karta hai, response deta hai
- exception: Custom exception classes — meaningful error messages
- util: Helper classes — date formatting, validators, constants
- config: Configuration classes — DB connection, security settings, etc.
Yeh separation Single Responsibility Principle (SRP) follow karta hai — ek class ka ek kaam!
/*
* 📁 Library Management System — MVC Architecture
* com.library.model → Book, Member
* com.library.exception → BookNotFoundException, MemberException
* com.library.repository → BookRepository, MemberRepository
* com.library.service → LibraryService
* com.library.controller → LibraryController
*/
// ════════════ 1. MODEL LAYER ════════════
package com.library.model;
public class Book {
private String isbn, title, author;
private boolean available;
public Book(String isbn, String title, String author) {
this.isbn=isbn; this.title=title; this.author=author;
this.available = true;
}
public String getIsbn() { return isbn; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public boolean isAvailable(){ return available; }
public void setAvailable(boolean a) { this.available = a; }
@Override
public String toString() {
return String.format("[%s] %-30s by %-15s %s",
isbn, title, author, available ? "✅ Available" : "📤 Borrowed");
}
}
// ════════════ 2. EXCEPTION LAYER ════════════
package com.library.exception;
public class BookNotFoundException extends RuntimeException {
public BookNotFoundException(String isbn) {
super("Book not found: ISBN = " + isbn);
}
}
public class BookNotAvailableException extends RuntimeException {
public BookNotAvailableException(String title) {
super("Book not available: " + title);
}
}
// ════════════ 3. REPOSITORY LAYER ════════════
package com.library.repository;
import com.library.model.Book;
import java.util.*;
public class BookRepository {
private Map<String, Book> db = new HashMap<>();
public void save(Book b) { db.put(b.getIsbn(), b); }
public List<Book> findAll() { return new ArrayList<>(db.values()); }
public Optional<Book> findByIsbn(String isbn) {
return Optional.ofNullable(db.get(isbn));
}
public List<Book> findAvailable() {
List<Book> avl = new ArrayList<>();
for (Book b : db.values()) if (b.isAvailable()) avl.add(b);
return avl;
}
}
// ════════════ 4. SERVICE LAYER ════════════
package com.library.service;
import com.library.model.Book;
import com.library.repository.BookRepository;
import com.library.exception.*;
import java.util.List;
public class LibraryService {
private BookRepository repo = new BookRepository();
public void addBook(Book b) { repo.save(b); }
public List<Book> getAllBooks() { return repo.findAll(); }
public List<Book> getAvailable(){ return repo.findAvailable(); }
public void issueBook(String isbn, String member) {
Book book = repo.findByIsbn(isbn)
.orElseThrow(() -> new BookNotFoundException(isbn));
if (!book.isAvailable())
throw new BookNotAvailableException(book.getTitle());
book.setAvailable(false);
System.out.println("📤 Issued: '"+book.getTitle().trim()+"' to "+member);
}
public void returnBook(String isbn) {
Book book = repo.findByIsbn(isbn)
.orElseThrow(() -> new BookNotFoundException(isbn));
book.setAvailable(true);
System.out.println("📥 Returned: '"+book.getTitle().trim()+"'");
}
}
// ════════════ 5. CONTROLLER LAYER ════════════
package com.library.controller;
import com.library.model.Book;
import com.library.service.LibraryService;
public class LibraryController {
private LibraryService service = new LibraryService();
public void addBook(String isbn, String title, String author) {
service.addBook(new Book(isbn, title, author));
System.out.println("✅ Added: " + title);
}
public void showAll() {
System.out.println("\n📚 ALL BOOKS:");
service.getAllBooks().forEach(System.out::println);
}
public void showAvailable() {
System.out.println("\n✅ AVAILABLE:");
service.getAvailable().forEach(System.out::println);
}
public void issue(String isbn, String member) {
try { service.issueBook(isbn, member); }
catch (RuntimeException e) { System.out.println("❌ Error: " + e.getMessage()); }
}
public void returnBook(String isbn) {
try { service.returnBook(isbn); }
catch (RuntimeException e) { System.out.println("❌ Error: " + e.getMessage()); }
}
}
// ════════════ 6. APP ENTRY POINT ════════════
import com.library.controller.LibraryController;
public class LibraryApp {
public static void main(String[] args) {
LibraryController ctrl = new LibraryController();
// Add books
ctrl.addBook("ISBN001", "Clean Code", "Robert C. Martin");
ctrl.addBook("ISBN002", "Effective Java", "Joshua Bloch");
ctrl.addBook("ISBN003", "Head First Design Patterns", "Freeman");
ctrl.addBook("ISBN004", "Spring in Action", "Craig Walls");
ctrl.showAll();
// Issue books
System.out.println();
ctrl.issue("ISBN001", "Rahul");
ctrl.issue("ISBN003", "Priya");
ctrl.issue("ISBN001", "Amit"); // Already issued — error
ctrl.showAvailable();
// Return book
System.out.println();
ctrl.returnBook("ISBN001");
ctrl.showAvailable();
}
}
Output
✅ Added: Clean Code
✅ Added: Effective Java
✅ Added: Head First Design Patterns
✅ Added: Spring in Action
📚 ALL BOOKS:
[ISBN001] Clean Code by Robert C. Martin ✅ Available
[ISBN002] Effective Java by Joshua Bloch ✅ Available
[ISBN003] Head First Design Patterns by Freeman ✅ Available
[ISBN004] Spring in Action by Craig Walls ✅ Available
📤 Issued: 'Clean Code' to Rahul
📤 Issued: 'Head First Design Patterns' to Priya
❌ Error: Book not available: Clean Code
✅ AVAILABLE:
[ISBN002] Effective Java by Joshua Bloch ✅ Available
[ISBN004] Spring in Action by Craig Walls ✅ Available
📥 Returned: 'Clean Code'
✅ AVAILABLE:
[ISBN001] Clean Code by Robert C. Martin ✅ Available
[ISBN002] Effective Java by Joshua Bloch ✅ Available
[ISBN004] Spring in Action by Craig Walls ✅ Available