Module 1
Overview of Java
Java is an object-oriented programming (OOP) language that is designed to be platform-
independent, meaning it can run on any device that has a Java Virtual Machine (JVM). OOP
in Java emphasizes the use of objects and classes, which is different from procedural
programming. In this approach, everything revolves around objects, which are instances of
classes.
Object-Oriented Programming Paradigms:
1. Abstraction:
o Abstraction is the process of hiding the implementation details and showing
only the essential features of an object. It is achieved using abstract classes
and interfaces.
o Example: A car's engine is abstracted away in a program, and only the
features relevant to the user (e.g., speed, fuel level) are exposed.
o Code Example:
o abstract class Animal {
o abstract void sound(); // Abstract method
o }
o class Dog extends Animal {
o void sound() {
o [Link]("Bark");
o }
o }
2. Encapsulation:
o Encapsulation is the mechanism of wrapping the data (variables) and code
(methods) together as a single unit, or class. It also restricts access to certain
details of the object by using access modifiers.
o Example: A BankAccount class might encapsulate the balance and only
expose methods to deposit and withdraw money.
o Code Example:
o public class BankAccount {
o private double balance;
o public void deposit(double amount) {
o balance += amount;
o }
o public double getBalance() {
o return balance;
o }
o }
3. Inheritance:
o Inheritance allows a class to inherit methods and properties from another
class, facilitating code reuse. The class that inherits is called a subclass, and
the class from which it inherits is called a superclass.
o Example: A Dog class can inherit from a Mammal class, so it automatically has
characteristics of mammals.
o Code Example:
o class Mammal {
o void breathe() {
o [Link]("Breathing");
o }
o }
o class Dog extends Mammal {
o void bark() {
o [Link]("Bark");
o }
o }
4. Polymorphism:
o Polymorphism allows one interface to be used for different data types. The
method behavior depends on the object that it is acting upon.
o Example: A method sound() could have different implementations for Dog,
Cat, and Cow objects.
o Code Example:
o class Animal {
o void sound() {
o [Link]("Animal sound");
o }
o }
o class Dog extends Animal {
o void sound() {
o [Link]("Bark");
o }
o }
o public class Test {
o public static void main(String[] args) {
o Animal myDog = new Dog();
o [Link](); // Output: Bark
o }
o }
Using Blocks of Code
In Java, blocks of code are enclosed in curly braces {}. These blocks group statements
together, such as within loops, methods, classes, etc.
Example:
public class Main {
public static void main(String[] args) {
// Block of code within the main method
[Link]("Inside the block");
Lexical Issues in Java
1. Whitespace:
o Whitespace (spaces, tabs, newlines) is used to separate tokens but is ignored
by the compiler.
o Example:
o int x = 5; // Whitespace separates tokens
2. Identifiers:
o Identifiers are names given to variables, methods, classes, and other entities
in Java. They must start with a letter, underscore _, or dollar sign $, and can
contain numbers.
o Example:
o int myVariable = 10;
3. Literals:
o Literals are fixed values used in Java code, such as numbers (5, 3.14),
characters ('A'), and strings ("Hello").
o Example:
o int number = 5; // 5 is a literal
o String name = "John"; // "John" is a string literal
4. Comments:
o Single-line comments begin with //.
o Multi-line comments are enclosed in /* ... */.
o Documentation comments begin with /** ... */ and are used to generate API
documentation.
o Example:
o // This is a single-line comment
o /*
o This is a multi-line comment
o */
5. Separators:
o Separators are used to structure Java code, including (), {}, [], ;, etc.
o Example:
o int[] arr = {1, 2, 3}; // Braces for array initialization
6. Java Keywords:
o Java has reserved words like class, public, static, void, etc. These cannot be
used as identifiers.
o Example:
o class MyClass {
o public static void main(String[] args) {
o // 'class', 'public', and 'static' are keywords
o }
o }
Data Types, Variables, and Arrays in Java
1. Primitive Types:
Java has 8 primitive data types:
o int: Integer type.
o float: Floating-point type.
o double: Double-precision floating-point.
o char: Character type.
o boolean: Boolean type (true or false).
o byte, short, long: For integer values of different ranges.
Example:
int age = 25; // Integer type
double price = 19.99; // Floating-point type
char grade = 'A'; // Character type
boolean isValid = true; // Boolean type
2. Variables:
A variable is a name that stores data of a specific type.
o Example:
o int count = 100; // Variable declaration and initialization
3. Type Conversion and Casting:
o Implicit Casting: Java automatically converts a smaller type to a larger type.
o Explicit Casting: Requires the use of parentheses to cast types.
o Example:
o int x = 10;
o double y = x; // Implicit casting (int to double)
o double z = 9.8;
o int w = (int) z; // Explicit casting (double to int)
4. Arrays:
Arrays are used to store multiple values of the same type.
o Example:
o int[] arr = {1, 2, 3, 4, 5}; // Array initialization
o [Link](arr[0]); // Accessing first element: Output 1
5. Type Inference with Local Variables (Java 10+):
Java allows the use of var to automatically infer the type of a variable based on the
assigned value.
o Example:
o var name = "John"; // Type is inferred as String
Operators in Java
1. Arithmetic Operators:
These operators are used to perform arithmetic operations like addition, subtraction,
multiplication, and division.
o +, -, *, /, % (modulus)
o Example:
o int a = 5;
o int b = 3;
o int sum = a + b; // sum = 8
2. Relational Operators:
These are used to compare two values.
o ==, !=, >, <, >=, <=
o Example:
o int a = 5;
o int b = 10;
o boolean result = a < b; // result = true
3. Boolean Logical Operators:
These operators perform logical operations on boolean values.
o && (AND), || (OR), ! (NOT)
o Example:
o boolean x = true;
o boolean y = false;
o boolean result = x && y; // result = false
4. Assignment Operator:
The assignment operator (=) is used to assign a value to a variable.
o Example:
o int a = 5;
o a = 10; // Assigning new value to variable a
5. Ternary Operator (? :):
The ternary operator is a shorthand for if-else.
o Example:
o int a = 5;
o int result = (a > 3) ? 10 : 20; // result = 10
6. Operator Precedence:
Operators have precedence that determines the order of evaluation. Parentheses can
be used to override the precedence.
o Example:
o int result = 5 + 2 * 3; // result = 11 (multiplication happens first)
7. Using Parentheses:
Parentheses can be used to group expressions and force precedence.
o Example:
o int result = (5 + 2) * 3; // result = 21 (addition happens first)
Control Statements in Java
1. Selection Statements:
o if and switch are used to make decisions.
o Example:
o int a = 10;
o if (a > 5) {
o [Link]("a is greater than 5");
o }
2. Iteration Statements:
o while, do-while, for, and for-each loops are used for repeated execution.
o Example:
o for (int i = 0; i < 5; i++) {
o [Link](i);
o }
3. Jump Statements:
o break, continue, and return control the flow of loops or methods.
o Example:
o for (int i = 0; i < 10; i++) {
o if (i == 5) {
o break; // Exit loop when i is 5
o }
o }
Module 2
Introducing Classes in Java: Detailed Explanation with Examples
Java is an Object-Oriented Programming (OOP) language, and classes are one of the
fundamental building blocks of OOP. In Java, everything revolves around classes and objects.
Here's an in-depth look at the topics you've mentioned:
1. Class Fundamentals
A class is a blueprint or template from which objects are created. It defines properties
(attributes) and methods (behaviors) that the objects of the class will have.
Class Syntax:
class MyClass {
// Fields (variables)
int age;
String name;
// Method (behavior)
void display() {
[Link]("Name: " + name + ", Age: " + age);
}
• Explanation:
o A class is defined with the class keyword followed by its name.
o Inside the class, you can declare fields (attributes) and methods (functions).
o The display() method prints the values of the fields.
2. Declaring Objects
Objects are instances of classes. When a class is defined, no memory is allocated. Memory is
allocated when you create an object of the class using the new keyword.
Example:
public class Main {
public static void main(String[] args) {
// Declaring and creating an object of MyClass
MyClass obj = new MyClass();
[Link] = 25;
[Link] = "John";
[Link](); // Output: Name: John, Age: 25
• Explanation:
o MyClass obj = new MyClass(); creates an object of the MyClass type and
assigns it to the reference variable obj.
o [Link] = 25; assigns values to the fields of the object.
3. Assigning Object Reference Variables
In Java, variables that hold objects are called reference variables. A reference variable points
to the memory address where the object is stored.
Example:
MyClass obj1 = new MyClass();
[Link] = 30;
[Link] = "Alice";
MyClass obj2 = obj1; // obj2 now refers to the same object as obj1
[Link] = 35;
[Link]([Link]); // Output: 35
[Link]([Link]); // Output: 35
• Explanation:
o Both obj1 and obj2 reference the same object in memory. If you modify the
object's fields using obj2, the changes will be reflected when accessing the
object via obj1.
4. Introducing Methods
Methods in Java are functions defined within a class. They define the behaviors of objects
created from the class.
Example:
class Car {
String model;
int year;
// Method to display car details
void displayDetails() {
[Link]("Model: " + model + ", Year: " + year);
public class Main {
public static void main(String[] args) {
Car car = new Car();
[Link] = "Toyota";
[Link] = 2020;
[Link](); // Output: Model: Toyota, Year: 2020
• Explanation:
o The method displayDetails() prints the attributes of the Car object.
o The method is invoked on the object car using [Link]().
5. Constructors
A constructor is a special type of method that is called when an object of a class is created. It
is used to initialize the object.
Example:
class Person {
String name;
int age;
// Constructor
Person(String n, int a) {
name = n;
age = a;
void display() {
[Link]("Name: " + name + ", Age: " + age);
}
}
public class Main {
public static void main(String[] args) {
// Using constructor to create object
Person person1 = new Person("Alice", 25);
[Link](); // Output: Name: Alice, Age: 25
• Explanation:
o The constructor Person(String n, int a) is called when new Person("Alice", 25)
is executed. It initializes the name and age fields of the object.
6. The this Keyword
The this keyword refers to the current instance of the class. It is used to differentiate
between instance variables and parameters with the same name.
Example:
class Person {
String name;
int age;
// Constructor
Person(String name, int age) {
[Link] = name; // 'this' refers to the instance variable
[Link] = age;
void display() {
[Link]("Name: " + name + ", Age: " + age);
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("John", 30);
[Link](); // Output: Name: John, Age: 30
• Explanation:
o The [Link] refers to the instance variable name, while the name in the
parameter refers to the method's parameter.
7. Garbage Collection
Java uses automatic garbage collection to manage memory. When an object is no longer
referenced, it becomes eligible for garbage collection, which means it can be automatically
deleted by the JVM.
• Explanation:
o Java has an automatic garbage collector that checks for unreferenced objects
and reclaims their memory.
o The [Link]() method can be used to suggest garbage collection, but the
JVM decides when to run it.
Example:
class MyClass {
// This object will be garbage collected when no references point to it.
public void finalize() {
[Link]("Object is being garbage collected");
}
public class Main {
public static void main(String[] args) {
MyClass obj1 = new MyClass();
obj1 = null; // The object is now eligible for garbage collection
[Link](); // Request garbage collection
• Explanation:
o Setting obj1 = null means that the object is no longer referenced, so it
becomes eligible for garbage collection.
o The finalize() method is called just before the object is garbage collected.
Methods and Classes:
1. Method Overloading
Definition: Multiple methods in the same class with the same name but different
parameters (type, number, or order).
Example:
class MathUtil {
int add(int a, int b) {
return a + b;
double add(double a, double b) {
return a + b;
}
2. Objects as Parameters
Definition: Methods can receive objects as arguments instead of primitive values.
Example:
class Box {
int width, height;
Box(int w, int h) {
width = w;
height = h;
void compare(Box b) {
if ([Link] * [Link] > [Link] * [Link])
[Link]("Current box is larger");
else
[Link]("Given box is larger");
3. Argument Passing
Definition:
Java uses pass-by-value for both primitives and object references.
• Primitive: value is copied.
• Object: reference is copied (so method can modify the object).
Example:
void modify(int a) { a = 10; } // no change outside
void modifyObj(Box b) { [Link] = 50; } // object modified
4. Returning Objects
Definition: A method can create and return an object.
Example:
class Calculator {
Box createBox(int w, int h) {
return new Box(w, h);
5. Recursion
Definition: A method calling itself.
Example (Factorial):
int factorial(int n) {
if (n == 1) return 1;
return n * factorial(n - 1);
6. Access Control (public, private, protected)
Controls where class members can be accessed.
Modifier Accessible From
public Anywhere
private Same class only
protected Same package + subclasses
default Same package
Example:
class Person {
private String name; // accessible only inside this class
public int age; // accessible anywhere
7. Understanding static
Definition: Belongs to the class, not to objects.
• shared across all objects
• can be accessed without creating an object
Example:
class Counter {
static int count = 0;
Counter() { count++; }
8. Introducing final
final keyword makes something unchangeable.
Usage Meaning
final variable value cannot change
final method cannot be overridden
final class cannot be inherited
Example:
final int MAX = 100;
final class Constants {}
class Test {
final void show() {} // cannot be overridden
9. Nested and Inner Classes
Nested Class: A class inside another class.
• Static nested class: like a static member.
• Inner class: non-static, associated with an object.
Example:
class Outer {
static class StaticNested {
void display() {
[Link]("Static Nested Class");
class Inner {
void display() {
[Link]("Inner Class");
Below is one combined Java program that demonstrates:
• Method Overloading
• Objects as Parameters
• Argument Passing
• Returning Objects
• Recursion
• Access Control
• static keyword
• final keyword
• Nested & Inner Classes
Everything is clearly labeled so you can study it easily.
Complete Java Program Covering All Concepts using Methods and Classes
// Demonstration of Java Concepts in One Program
class Main {
public static void main(String[] args) {
[Link]("--- Method Overloading ---");
MathUtil util = new MathUtil();
[Link]([Link](5, 10)); // int add()
[Link]([Link](5.5, 4.5)); // double add()
[Link]("\n--- Objects as Parameters & Argument Passing ---");
Box b1 = new Box(5, 5);
Box b2 = new Box(10, 2);
[Link](b2); // passing objects
[Link]("Before modifyObj: width = " + [Link]);
[Link](b1); // modifies object
[Link]("After modifyObj: width = " + [Link]);
[Link]("\n--- Returning Objects ---");
Box b3 = [Link](3, 7);
[Link]();
[Link]("\n--- Recursion (Factorial) ---");
[Link]("Factorial of 5 = " + [Link](5));
[Link]("\n--- Access Control ---");
Person p = new Person("John", 30);
[Link](); // shows private data via public method
[Link]("\n--- static Keyword ---");
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();
[Link]("Number of Counter objects: " + [Link]);
[Link]("\n--- final Keyword ---");
FinalDemo fd = new FinalDemo();
[Link]();
[Link]("\n--- Nested and Inner Classes ---");
[Link] sn = new [Link]();
[Link]();
Outer outerObj = new Outer();
[Link] in = [Link] Inner();
[Link]();
}
}
///////////////////////////
// 1. METHOD OVERLOADING //
///////////////////////////
class MathUtil {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
// modifying object (argument passing)
void modifyObj(Box b) {
[Link] = 50;
// return object
Box createBox(int w, int h) {
return new Box(w, h);
// recursion
int factorial(int n) {
if (n == 1) return 1;
return n * factorial(n - 1);
}
///////////////////////////////
// 2. OBJECTS AS PARAMETERS //
///////////////////////////////
class Box {
int width, height;
Box(int w, int h) {
width = w;
height = h;
void compare(Box b) {
if ([Link] * [Link] > [Link] * [Link])
[Link]("Current box is larger");
else
[Link]("Given box is larger");
void show() {
[Link]("Box: " + width + " x " + height);
///////////////////////
// 3. ACCESS CONTROL //
///////////////////////
class Person {
private String name; // private → accessible only inside class
public int age;
Person(String n, int a) {
name = n;
age = a;
public void show() {
[Link]("Name: " + name + ", Age: " + age);
/////////////////////
// 4. static DEMO //
/////////////////////
class Counter {
static int count = 0; // shared by all objects
Counter() {
count++;
}
/////////////////////
// 5. final DEMO //
/////////////////////
final class FinalDemo {
final int MAX = 100;
final void show() {
[Link]("Final variable MAX = " + MAX);
//////////////////////////////////////
// 6. NESTED & INNER CLASS DEMO //
//////////////////////////////////////
class Outer {
// static nested class
static class StaticNested {
void display() {
[Link]("Inside Static Nested Class");
}
// inner class
class Inner {
void display() {
[Link]("Inside Inner Class");
All concepts covered in one place
This file gives you a clean and clear demonstration of:
• Overloading
• Pass-by-value & object references
• Passing and returning objects
• Recursion
• Static & final
• Access control
• Nested classes
Module 3
Inheritance in Java
1. Inheritance Basics
Inheritance allows one class (child/subclass) to acquire the properties and methods of
another class (parent/superclass).
class Animal {
void eat() { [Link]("Eating..."); }
class Dog extends Animal {
void bark() { [Link]("Barking..."); }
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
[Link](); // Inherited
[Link]();
2. Using super
super is used to access the superclass’s methods, fields, or constructors.
class Animal {
Animal() { [Link]("Animal created"); }
class Dog extends Animal {
Dog() {
super(); // calling parent constructor
[Link]("Dog created");
public class Test {
public static void main(String[] args) {
new Dog();
3. Creating a Multilevel Hierarchy
A class extends another class, which extends another class.
class A { void showA() { [Link]("A"); } }
class B extends A { void showB() { [Link]("B"); } }
class C extends B { void showC() { [Link]("C"); } }
public class Test {
public static void main(String[] args) {
C obj = new C();
[Link]();
[Link]();
[Link]();
4. When Constructors Are Executed
Constructors run top-down, from parent to child.
class A { A() { [Link]("A"); } }
class B extends A { B() { [Link]("B"); } }
public class Test {
public static void main(String[] args) {
new B();
5. Method Overriding
Child class provides its own implementation of a parent method.
class Animal {
void sound() { [Link]("Animal sound"); }
class Dog extends Animal {
@Override
void sound() { [Link]("Dog barks"); }
6. Dynamic Method Dispatch
Runtime polymorphism: overridden method called based on object, not reference type.
Animal a = new Dog();
[Link](); // Calls Dog's overridden method
7. Using Abstract Classes
Abstract classes cannot be instantiated; they may contain abstract methods.
abstract class Animal {
abstract void sound();
class Dog extends Animal {
void sound() { [Link]("Dog barks"); }
8. Using final with Inheritance
• final class → cannot be inherited
• final method → cannot be overridden
final class A { } // cannot extend this class
class B {
final void show() { }
class C extends B {
// void show() {} // ERROR
9. Local Variable Type Inference and Inheritance (var)
var infers type at compile time.
Animal a = new Dog();
var b = new Dog(); // b’s type is Dog
10. The Object Class
Every class in Java implicitly inherits from Object.
Common methods:
• toString()
• equals()
• hashCode()
class A { }
public class Test {
public static void main(String[] args) {
A obj = new A();
[Link]([Link]());
Interfaces in Java
1. Interfaces
Contain abstract methods and constants (before Java 8).
1. What is an Interface?
An interface in Java is a reference type, similar to a class, that can contain:
• Abstract methods (methods without a body)
• Default methods (methods with a default implementation)
• Static methods
• Constants (public static final variables)
Key points:
• Interfaces define a contract: any class that implements the interface must provide
implementations for all abstract methods.
• A class can implement multiple interfaces, allowing multiple inheritance of type
(Java classes can’t extend multiple classes).
2. Syntax of an Interface
// Define an interface
interface InterfaceName
// abstract method
void method1();
// default method (optional)
default void method2()
[Link]("Default implementation");
// static method (optional)
static void method3()
[Link]("Static method in interface");
// constant
int CONSTANT = 100; // implicitly public static final
3. Implementing an Interface
// A class implementing the interface
class MyClass implements InterfaceName
// Must implement all abstract methods
public void method1()
[Link]("Implemented method1");
}
}
4. Using the Interface
public class Main
public static void main(String[] args)
InterfaceName obj = new MyClass();
obj.method1(); // Calls implemented method
obj.method2(); // Calls default method
InterfaceName.method3(); // Calls static method
[Link]([Link]); // Access constant
Key Points in Syntax
1. Use the keyword interface to define an interface.
2. Methods without a body are abstract by default.
3. Use implements in a class to use the interface.
4. Classes must implement all abstract methods, or the class itself must be declared
abstract.
Example
interface Animal
void sound();
class Dog implements Animal
{
public void sound()
[Link]("Dog barks"); }
1. The Animal Interface
interface Animal {
void sound();
• interface defines a contract. Any class that implements Animal must provide an
implementation for the sound() method.
• void sound(); is an abstract method (no body) that classes must implement.
2. The Dog Class
class Dog implements Animal {
public void sound() { [Link]("Dog barks"); }
• class Dog implements Animal → Dog is agreeing to follow the Animal contract.
• public void sound() → The Dog class implements the sound method.
• [Link]("Dog barks"); → Prints "Dog barks" when the method is called.
3. How to Use It
You can create a Dog object and call the method like this:
public class Main
public static void main(String[] args)
Animal myDog = new Dog();
[Link](); // Output: Dog barks
• Animal myDog = new Dog(); → Polymorphism: myDog is declared as Animal but
behaves like a Dog.
2. Default Interface Methods
Provide method implementation inside an interface.
interface MyInterface
// Default method in interface
default void show()
[Link]("Default method");
class MyClass implements MyInterface
// No need to override show() because it's a default method
public class Main
public static void main(String[] args)
MyClass obj = new MyClass();
[Link](); // Calls the default method from MyInterface
Step-by-Step Explanation
1. Interface Definition
interface MyInterface {
default void show() {
[Link]("Default method");
• MyInterface has a default method called show().
• A default method in an interface has a body, so implementing classes do not have to
override it.
• Default methods were introduced in Java 8 to allow interfaces to have concrete
methods.
2. Class Implementation
class MyClass implements MyInterface {
// We did not override show(), so the default method will be used
• MyClass implements MyInterface.
• Since show() has a default implementation, MyClass can simply inherit it.
3. Main Method
MyClass obj = new MyClass();
[Link]();
• We create an object obj of MyClass.
• [Link]() calls the default method in the interface because MyClass did not
override it.
Output
Default method
Key Points
1. Default methods allow interfaces to have concrete methods with a body.
2. Implementing classes may override default methods if needed.
3. Useful for backward compatibility, so adding new methods to interfaces does not
break existing code.
3. Static Methods in an Interface
Static methods belong to the interface itself.
interface Calc
static int add(int a, int b)
return a + b;
public class Test
public static void main(String[] args)
[Link]([Link](5, 3));
Step-by-Step Explanation
1. Interface Definition
interface Calc {
static int add(int a, int b) {
return a + b;
• Calc defines a static method add().
• Static methods in interfaces:
o Belong to the interface itself, not to the implementing class.
o Must be called using the interface name, e.g., [Link](...).
• add(int a, int b) simply returns the sum of a and b.
2. Main Class
public class Test {
public static void main(String[] args) {
[Link]([Link](5, 3));
• We call the static method using [Link](5, 3).
• Important: You cannot call it using an object of a class implementing the interface.
• The method returns 5 + 3 = 8.
Output
Key Points
1. Static methods in interfaces do not require an implementing class.
2. They cannot be overridden by classes.
3. They are useful for utility or helper methods related to the interface.
4. Private Interface Methods
Help reduce code duplication inside default/static methods.
interface Demo {
// Private method in interface
private void helper()
[Link]("Helper");
// Default method
default void show()
helper(); // calling the private method
class Test implements Demo
// No need to override show()
public class Main
public static void main(String[] args)
Test obj = new Test();
[Link](); // Calls the default method
}
1. Private Method in Interface
private void helper() {
[Link]("Helper");
• Private methods in interfaces are allowed from Java 9 onwards.
• They cannot be accessed from outside the interface.
• Their purpose: to share code between default or static methods in the interface.
2. Default Method
default void show() {
helper(); // calls the private method
• show() is a default method, so it can be called by any class implementing the
interface.
• Inside show(), we call the private method helper(). This is allowed, because private
methods can only be called within the interface.
3. Implementing Class
class Test implements Demo {
// No override needed
• Test implements Demo.
• It automatically inherits the show() method.
4. Main Method
Test obj = new Test();
[Link]();
• Calls the show() method of the interface.
• show() internally calls helper(), which prints "Helper".
Output
Helper
Key Points
1. Private methods in interfaces cannot be called from implementing classes.
2. They help avoid code duplication inside default or static methods.
3. Default methods can call private methods to reuse logic.
Below is a single, clean, runnable Java program that demonstrates all the concepts:
• Inheritance Basics
• super
• Multilevel Inheritance
• Constructor Execution Order
• Method Overriding
• Dynamic Method Dispatch
• Abstract Classes
• final with Inheritance
• var (Local Variable Type Inference)
• Object Class Methods
• Interfaces
• Default, Static, Private Interface Methods
Complete Java Program (All Concepts Together from the above module 3)
// ----------------------------------
// 1. Inheritance Basics + super + Constructors
// ----------------------------------
class Animal {
String type = "Generic Animal";
Animal()
[Link]("Animal Constructor");
void eat()
[Link]("Animal eats");
void sound()
[Link]("Animal makes a sound");
class Dog extends Animal
Dog()
super(); // calling parent constructor
[Link]("Dog Constructor");
@Override
void sound()
{
[Link]("Dog barks");
// ----------------------------------
// 2. Multilevel Inheritance
// ----------------------------------
class Puppy extends Dog {
Puppy() {
[Link]("Puppy Constructor");
// ----------------------------------
// 3. Abstract Classes + final
// ----------------------------------
abstract class Shape {
abstract void draw();
final void info() { // final method cannot be overridden
[Link]("This is a shape");
class Circle extends Shape {
void draw() {
[Link]("Drawing Circle");
}
// ----------------------------------
// 4. Interfaces + Default + Static + Private Methods
// ----------------------------------
interface MyInterface {
private void helper() { // private method
[Link]("Private interface helper");
default void show() { // default method
helper(); // calling private method
[Link]("Default show() in interface");
static void utility() { // static method
[Link]("Static method inside interface");
class InterfaceDemo implements MyInterface {}
// ----------------------------------
// 5. Object Class Methods Example
// ----------------------------------
class SampleObject {
int id;
SampleObject(int id) { [Link] = id; }
@Override
public String toString() {
return "SampleObject with id: " + id;
// ----------------------------------
// MAIN CLASS (Runs Everything)
// ----------------------------------
public class Main {
public static void main(String[] args) {
[Link]("\n=== Inheritance Basics + Constructors ===");
Dog d = new Dog();
[Link]();
[Link]();
[Link]("\n=== Multilevel Inheritance ===");
Puppy p = new Puppy(); // constructors of Animal -> Dog -> Puppy
[Link]();
[Link]("\n=== Dynamic Method Dispatch ===");
Animal ref = new Dog(); // ref is Animal, object is Dog
[Link](); // Dog's overridden method runs
[Link]("\n=== Abstract Class ===");
Shape s = new Circle();
[Link]();
[Link](); // final method from abstract class
[Link]("\n=== Interfaces (default, static, private) ===");
InterfaceDemo obj = new InterfaceDemo();
[Link](); // default method
[Link](); // static method
[Link]("\n=== Object Class Example ===");
SampleObject so = new SampleObject(101);
[Link]([Link]());
[Link]("\n=== Local Variable Type Inference (var) ===");
var x = new Dog(); // x type is Dog
[Link]();
What This Program Demonstrates
Inheritance & super
• Dog extends Animal
• super() calls parent constructor
Multilevel Inheritance
• Puppy → Dog → Animal
Constructor Execution Order
Printed automatically:
Animal → Dog → Puppy
Method Overriding & Dynamic Dispatch
• sound() overridden in Dog
• Runtime polymorphism with Animal ref = new Dog();
Abstract Class & final
• Shape is abstract
• info() is final
Interfaces
• default method
• static method
• private helper method
Object Class
• toString() overridden
Local Variable Type Inference (var)
• var x = new Dog();
Module 4
PACKAGES IN JAVA
1. Packages
✓ A package is a collection of related classes and interfaces.
✓ It helps organize code and avoid name conflicts.
1. What is a Package in Java?
A package in Java is a namespace or folder that groups related classes, interfaces, and sub-
packages together.
Think of it like a folder on your computer:
• Inside a folder, you can keep related files together.
• Similarly, in a package, you can keep related Java classes together.
Purpose of packages:
1. Organize code – keeps related classes together.
2. Avoid name conflicts – two classes can have the same name if they are in different
packages.
3. Access control – provides controlled access using access modifiers (public, protected,
default).
2. Types of Packages in Java
1. Built-in Packages
o Java provides many packages ready to use.
o Example: [Link] (for ArrayList, HashMap), [Link] (for file handling), [Link]
(automatically imported).
2. User-defined Packages
o You can create your own packages to organize your code.
3. Syntax for Packages
a) Creating a Package
// File: [Link]
package mypackage; // declare the package
public class MyClass {
public void display() {
[Link]("Hello from mypackage!");
b) Using a Package
// File: [Link]
import [Link]; // import the class from package
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link]();
• package mypackage; → Declares that this class belongs to mypackage.
• import [Link]; → Imports the class to be used in another file.
4. Important Points
1. Package names are usually all lowercase.
2. The directory structure should match the package name.
o Example: mypackage/[Link]
3. [Link] is automatically imported (so you don’t need import [Link]).
4. Packages can contain sub-packages, e.g., [Link].
5. Output Example
[Link]
package mypackage;
public class MyClass {
public void display() {
[Link]("Hello from mypackage!");
[Link]
import [Link];
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link]();
Output
Hello from mypackage!
Summary
• Packages are used to organize Java classes and interfaces.
• They help avoid naming conflicts and manage code better.
• Java has built-in packages and also allows user-defined packages.
2. Packages and Member Access
Access levels with packages:
1. Member Access Modifiers in Java
Java provides four access levels for classes, methods, and variables:
Modifier Within Class Within Package Subclass Outside Package
private Yes No No No
default (no modifier) Yes Yes No No
protected Yes Yes Yes No
public Yes Yes Yes Yes
• private → accessible only within the same class
• default → accessible within the same package
• protected → accessible within package + subclasses
• public → accessible everywhere
2. Package Example with Member Access
Let’s create two packages: package1 and package2.
File: package1/[Link]
package package1;
public class Person {
private String name = "Alice"; // private
int age = 20; // default
protected String city = "London"; // protected
public String country = "UK"; // public
public void show() {
[Link]("Name: " + name);
[Link]("Age: " + age);
[Link]("City: " + city);
[Link]("Country: " + country);
File: package1/[Link]
package package1;
public class Main1 {
public static void main(String[] args) {
Person p = new Person();
// Access within the same package
// [Link]([Link]); // private, not accessible
[Link]([Link]); // default, accessible
[Link]([Link]); // protected, accessible
[Link]([Link]); // public, accessible
Output (from [Link])
20
London
UK
File: package2/[Link]
package package2;
import [Link];
public class Main2 extends Person {
public static void main(String[] args) {
Person p = new Person();
// [Link]([Link]); // private
// [Link]([Link]); // default, different package
// [Link]([Link]); // protected, not via object
[Link]([Link]); // public, accessible everywhere
Main2 obj = new Main2();
[Link]([Link]); // protected, accessible in subclass
Output (from [Link])
UK
London
3. Key Points
1. Private → accessible only in the same class.
2. Default (no modifier) → accessible within the same package.
3. Protected → accessible within package + subclasses.
4. Public → accessible everywhere, including outside packages.
5. To access classes or members from another package, use import.
3. Importing Packages
1. What is Importing Packages?
• In Java, packages group related classes and interfaces together.
• To use classes from other packages, you need to import them using the import
statement.
• Syntax:
import package_name.ClassName; // Import a single class
import package_name.*; // Import all classes from a package
• Some packages like [Link] are imported automatically, e.g., String, Math.
• Importing a class does not copy it, it just tells Java where to find it.
2. Example: Importing Packages
Step 1: Create a package with a class
File: mypackage/[Link]
package mypackage; // Package declaration
public class MyClass {
public void display() {
[Link]("Hello from MyClass in mypackage!");
Step 2: Use the class in another package
File: [Link]
import [Link]; // Import the class
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link]();
Step 3: Output
Hello from MyClass in mypackage!
3. Using Wildcard *
Instead of importing a single class, you can import all classes in a package:
import mypackage.*; // imports all classes in mypackage
• Only imports classes directly inside the package, not sub-packages.
4. Important Points
1. import statements must come after package declaration (if any) and before class
declaration.
2. If you don’t import, you can still use the fully qualified name:
[Link] obj = new [Link]();
3. Java automatically imports [Link].* (like String, Math), so no import is needed for
them.
Summary
• import allows you to use classes from other packages easily.
• You can import specific classes or all classes using *.
• It keeps code organized and avoids naming conflicts.
EXCEPTIONS IN JAVA
1. Exception-Handling Fundamentals
Exceptions are runtime errors.
Handled with:
try – code that might cause an error
catch – handles the error
finally – always runs
1. What is an Exception?
An exception in Java is an event that occurs during the execution of a program that
disrupts the normal flow of instructions.
• In simple words, an exception is an unexpected problem that occurs while the
program is running.
• Examples: dividing by zero, accessing an invalid array index, reading a file that
doesn’t exist, etc.
2. Why Do Exceptions Occur?
Exceptions occur due to:
1. Programmer errors – like dividing by zero or accessing invalid array elements.
2. External factors – like file not found, network error, database connection failure.
3. Exception Hierarchy in Java
All exceptions are subclasses of Throwable in Java.
Throwable
├── Error (serious system errors, not usually handled)
└── Exception
├── IOException (file/network errors)
├── RuntimeException (programming errors)
│ ├── ArithmeticException
│ ├── NullPointerException
│ └── ArrayIndexOutOfBoundsException
└── Other Exceptions
4. Types of Exceptions
a) Checked Exceptions
• Checked at compile-time.
• Must be handled using try-catch or declared using throws.
• Example: IOException, FileNotFoundException.
b) Unchecked Exceptions
• Checked at runtime (not compile-time).
• Usually caused by programming errors.
• Example: ArithmeticException, NullPointerException,
ArrayIndexOutOfBoundsException.
5. Example of an Exception
public class Main {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b; // may throw ArithmeticException
[Link]("Result: " + result);
} catch (ArithmeticException e) {
[Link]("Cannot divide by zero!");
[Link]("Program continues...");
}
Output
Cannot divide by zero!
Program continues...
Explanation:
• The try block contains code that may throw an exception.
• The catch block handles the exception, so the program does not crash.
6. Key Points
1. Exceptions disrupt normal program flow.
2. Handling exceptions keeps programs robust.
3. try-catch-finally is used for handling exceptions.
4. throw is used to throw an exception manually.
5. throws is used in a method declaration to indicate it may throw an exception.
2. Exception Types
1. Two categories:
Checked / When
Type Examples
Unchecked Detected
Checked Must handle Compile-time IOException, SQLException
Runtime
Unchecked Optional to ArithmeticException, NullPointerException,
(program
(Runtime) handle ArrayIndexOutOfBoundsException
execution)
2. Checked Exception Example
Checked exceptions must be handled using try-catch or declared using throws.
import [Link];
import [Link];
import [Link];
public class CheckedExample {
public static void main(String[] args) {
try {
File file = new File("[Link]");
FileReader fr = new FileReader(file); // may throw IOException
[Link]("File opened successfully");
} catch (IOException e) {
[Link]("File not found or cannot be opened!");
[Link]("Program continues...");
Output (if file not found)
File not found or cannot be opened!
Program continues...
Explanation:
• FileReader may throw IOException, which is a checked exception.
• Java forces us to handle it, otherwise the code won’t compile.
3. Unchecked (Runtime) Exception Example
Unchecked exceptions occur during runtime and are optional to handle.
public class UncheckedExample {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b; // may throw ArithmeticException
[Link]("Result: " + result);
} catch (ArithmeticException e) {
[Link]("Cannot divide by zero!");
[Link]("Program continues...");
Output
Cannot divide by zero!
Program continues...
Explanation:
• Dividing by zero causes ArithmeticException, which is an unchecked exception.
• The program would crash if we did not handle it with try-catch.
4. Key Points
1. Checked exceptions → must be handled at compile-time.
2. Unchecked exceptions → occur at runtime, optional to handle.
3. Handling exceptions ensures the program does not terminate unexpectedly.
3. Uncaught Exceptions
If not handled, program stops.
Uncaught Exception means an exception that occurs during program execution but is not
handled (not caught) by any try–catch block. When this happens, the program terminates
abnormally, and the runtime prints an error message and stack trace.
Simple Explanation
• An exception occurs
• There is no matching catch block
• The exception reaches the default exception handler
• Program stops and prints the error
Simple Explanation
• An exception occurs
• There is no matching catch block
• The exception reaches the default exception handler
• Program stops and prints the error
Example in Java (Uncaught Exception)
public class Test
public static void main(String[] args)
int a = 10;
int b = 0;
int result = a / b; // ArithmeticException
[Link](result);
[Link]("This line will not execute");
Output
Exception in thread "main" [Link]: / by zero
at [Link]([Link])
Why is it Uncaught?
• Division by zero causes an ArithmeticException
• There is no try-catch block
• JVM handles it using the default exception handler
• Program stops before executing the last println
Caught vs Uncaught (Quick Comparison)
Caught Exception
try
int x = 10 / 0;
} catch (ArithmeticException e)
[Link]("Exception handled");
Output:
Exception handled
Uncaught Exception
int x = 10 / 0;
Output: Program crashes with stack trace
Key Points
• Uncaught exceptions crash the program
• They are handled by the JVM
• Always use try–catch to prevent abnormal termination
4. Using try and catch
try {
int x = 10 / 0;
} catch (ArithmeticException e)
[Link]("Cannot divide by zero");
What Happens Step by Step
1. The program enters the try block.
2. 10 / 0 causes an ArithmeticException because division by zero is not allowed.
3. The exception is immediately thrown.
4. The JVM looks for a matching catch block.
5. catch (ArithmeticException e) matches the exception.
6. The exception is handled, so the program does not crash.
7. The message inside the catch block is printed.
Output
Cannot divide by zero
Important Points
• The exception is caught, so it is not an uncaught exception.
• The program continues normally after the catch block.
• No error message or stack trace is shown.
Key Difference from Uncaught Exception
Caught Exception Uncaught Exception
Program continues Program terminates
No crash Crash with stack trace
Handled using try–catch Not handled
4. Multiple catch Clauses
Multiple catch clauses allow a program to handle different types of exceptions separately
using more than one catch block after a single try block.
Example with Multiple Catch Clauses
public class MultipleCatchExample
public static void main(String[] args)
try
int a = 10;
int b = 0;
int result = a / b; // ArithmeticException
int[] arr = new int[3];
arr[5] = 100; // ArrayIndexOutOfBoundsException
catch (ArithmeticException e)
[Link]("Cannot divide by zero");
catch (ArrayIndexOutOfBoundsException e)
[Link]("Array index is out of range");
catch (Exception e)
[Link]("Some other exception occurred");
}
[Link]("Program continues...");
Explanation
1. Code inside the try block is executed.
2. 10 / 0 causes an ArithmeticException.
3. JVM checks the catch blocks from top to bottom.
4. The first matching catch block (ArithmeticException) executes.
5. Remaining code in the try block is skipped.
6. Program continues after the try–catch structure.
Output
Cannot divide by zero
Program continues...
Important Rules
• Catch blocks are checked in order
• Specific exceptions first, general exceptions last
• Exception should always be the last catch block
Wrong Order
catch (Exception e) { }
catch (ArithmeticException e) { } // Compile-time error
✔ Correct Order
catch (ArithmeticException e) { }
catch (Exception e) { }
Key Points for Exams
• Multiple catch clauses handle multiple exceptions
• Only one catch block executes per exception
• Improves error handling and program safety
6. Nested try Statements
Nested try statements mean placing one try–catch block inside another try block.
They are used when a part of code inside a try block may cause another exception that
needs separate handling.
Why Use Nested Try Statements?
• To handle different exceptions at different levels
• To give more specific error handling
• Useful when one risky operation is inside another risky operation
Example of Nested Try Statements
public class NestedTryExample
public static void main(String[] args)
try
[Link]("Outer try block");
try
int a = 10;
int b = 0;
int result = a / b; // ArithmeticException
} catch (ArithmeticException e)
[Link]("Inner catch: Cannot divide by zero");
[Link]("After inner try-catch");
} catch (Exception e)
[Link]("Outer catch: Exception handled");
[Link]("Program continues normally");
Explanation
1. The program enters the outer try block.
2. Inside it, the inner try block executes.
3. 10 / 0 causes an ArithmeticException.
4. The inner catch block handles the exception.
5. Control returns to the outer try block.
6. The outer catch block is not executed because the exception is already handled.
7. Program continues normally.
Output
Outer try block
Inner catch: Cannot divide by zero
After inner try-catch
Program continues normally
Important Points
• Exceptions are first checked in the inner catch block
• If not handled inside, they are passed to the outer catch block
• Helps in fine-grained exception handling
Simple Definition (Exam Ready)
Nested try statements are try–catch blocks placed inside another try block to handle
exceptions at different levels.
7. throw
The throw keyword is used to explicitly throw an exception in a program.
It is mainly used when a programmer wants to create and throw an exception manually.
Why throw Is Used
• To handle custom error conditions
• To force an exception based on logic
• To improve program reliability
Syntax
throw new ExceptionType("Error message");
Example Using throw
public class ThrowExample {
public static void main(String[] args) {
int age = 15;
try {
if (age < 18) {
throw new ArithmeticException("Not eligible to vote");
}
[Link]("Eligible to vote");
catch (ArithmeticException e) {
[Link]([Link]());
[Link]("Program continues...");
Explanation
1. The program checks the value of age.
2. If age < 18, the throw statement manually throws an ArithmeticException.
3. Control immediately moves to the catch block.
4. The exception message is printed.
5. Program continues normally after handling the exception.
Output
Not eligible to vote
Program continues...
Important Points About throw
• Used to throw one exception at a time
• Must be followed by an exception object
• Can throw built-in or custom exceptions
• Exception must be caught or declared using throws
throw vs throws (Quick Difference)
throw throws
Used inside method Used in method signature
Throws one exception Declares multiple exceptions
Used to create exception Used to pass exception
Short Exam Definition
The throw keyword in Java is used to explicitly throw an exception from a program.
8. throws
The throws keyword is used in a method declaration to tell the caller that the method may
pass (delegate) an exception and that the caller must handle it.
Why throws Is Used
• To declare exceptions instead of handling them inside the method
• To keep method code clean
• To let the calling method decide how to handle the exception
Syntax
returnType methodName() throws ExceptionType {
// code
Example Using throws
public class ThrowsExample {
static void divide() throws ArithmeticException {
int a = 10;
int b = 0;
int result = a / b; // Exception occurs here
[Link](result);
public static void main(String[] args) {
try {
divide();
catch (ArithmeticException e) {
[Link]("Cannot divide by zero");
[Link]("Program continues...");
Explanation
1. The divide() method declares throws ArithmeticException.
2. The exception is not handled inside divide().
3. The exception is passed to the calling method (main()).
4. main() handles it using a try–catch block.
5. Program continues normally.
Output
Cannot divide by zero
Program continues...
Important Points About throws
• Used in method signature
• Can declare multiple exceptions
• Does not throw the exception itself
• Mainly used for checked exceptions, but can be used with unchecked too
Example with Multiple Exceptions
void readFile() throws IOException, SQLException {
// risky code
Short Exam Definition
The throws keyword is used to declare exceptions that a method may pass to the calling
method for handling.
9. finally
The finally block is used with try–catch to execute important code whether an exception
occurs or not.
It is mainly used for cleanup operations like closing files, releasing resources, etc.
Syntax
try {
// risky code
catch (Exception e) {
// exception handling
finally {
// always executed
Example Using finally
public class FinallyExample
public static void main(String[] args)
try
int a = 10;
int b = 0;
int result = a / b; // ArithmeticException
[Link](result);
catch (ArithmeticException e)
[Link]("Cannot divide by zero");
finally
[Link]("Finally block executed");
[Link]("Program continues...");
}
Explanation
1. Code inside the try block is executed.
2. Division by zero causes an ArithmeticException.
3. The exception is caught in the catch block.
4. The finally block executes regardless of the exception.
5. Program continues normally.
Output
Cannot divide by zero
Finally block executed
Program continues...
Case 2: No Exception Occurs
try {
int x = 10 / 2;
[Link](x);
catch (ArithmeticException e) {
[Link]("Error");
finally {
[Link]("Finally block executed");
Output
Finally block executed
Important Points
• finally always executes (exception or not)
• Used for resource cleanup
• Cannot be skipped (except [Link]())
Exam-Ready Definition
The finally block in Java is used to execute code that must run whether an exception occurs
or not.
10. Java’s Built-in Exceptions
Examples:
• ArithmeticException
• ArrayIndexOutOfBoundsException
• NumberFormatException
• NullPointerException
String s = "abc";
int x = [Link](s); // NumberFormatException
11. Creating Your Own Exception Subclass is also called Custom Exception
A custom exception is an exception created by the programmer by extending the Exception
class (or RuntimeException).
It is used when built-in exceptions are not enough to describe a specific error.
Why Create Your Own Exception?
• To represent application-specific errors
• To make error handling clear and meaningful
• Improves code readability
Steps to Create a Custom Exception
1. Create a class that extends Exception
2. Define a constructor
3. Use throw to raise the exception
4. Handle it using try–catch
Example: Custom Exception
// Step 1: Create custom exception class
class AgeNotValidException extends Exception {
AgeNotValidException(String message) {
super(message);
// Main class
public class CustomExceptionExample {
static void checkAge(int age) throws AgeNotValidException {
if (age < 18) {
throw new AgeNotValidException("Age is not valid for voting");
} else {
[Link]("Eligible to vote");
public static void main(String[] args) {
try {
checkAge(15);
catch (AgeNotValidException e) {
[Link]([Link]());
Explanation
1. AgeNotValidException is a custom exception class.
2. checkAge() checks the age.
3. If age is less than 18, the exception is manually thrown using throw.
4. The method declares the exception using throws.
5. The exception is handled in the catch block.
6. The error message is printed.
Output
Age is not valid for voting
Key Points
• Custom exceptions extend Exception or RuntimeException
• Use throw to raise the exception
• Use throws to declare it
• Makes programs more meaningful and structured
Exam-Ready Definition
A user-defined exception is a custom exception created by extending the Exception class to
handle application-specific errors.
12. Chained Exceptions
Note: One exception caused by another.
Chained exceptions are used when one exception is caused by another exception.
Java allows you to link (chain) the original exception as the cause of a new exception so that
the root problem is not lost.
Why Use Chained Exceptions?
• To preserve the original cause of an error
• To improve debugging
• Common in layered applications (UI → Service → Database)
How Chained Exceptions Work
• One exception is caught
• A new exception is thrown
• The original exception is passed as the cause
Example of Chained Exceptions
class ChainedExceptionExample
static void process() throws Exception
try
int a = 10 / 0; // Original exception
catch (ArithmeticException e)
// Create new exception and attach original cause
throw new Exception("Error in process()", e);
}
}
public static void main(String[] args)
try
process();
catch (Exception e)
[Link]([Link]());
[Link]("Original cause: " + [Link]());
Explanation
1. 10 / 0 causes an ArithmeticException.
2. The exception is caught in process().
3. A new Exception is created.
4. The original exception is passed as the cause.
5. The caller catches the new exception.
6. Both the main error and the original cause are available.
Output
Error in process()
Original cause: [Link]: / by zero
Important Methods Used
• Throwable(Throwable cause)
• Throwable(String message, Throwable cause)
• getCause()
Key Points
• Chained exceptions help trace root cause
• Prevents loss of original exception details
• Widely used in real-world applications
Exam-Ready Definition
Chained exceptions are exceptions where one exception is linked as the cause of another
exception to preserve the original error information.
Combine all package + exception examples into one runnable Java program. Below are it
Folder Structure
src/
├── mypackage/
│ └── [Link]
├── pack1/
│ └── [Link]
├── pack2/
│ └── [Link]
└── exceptionsdemo/
├── [Link]
└── [Link]
1. PACKAGE: mypackage / [Link]
package mypackage;
public class MyClass {
public void show() {
[Link]("Inside MyClass from mypackage");
2. PACKAGE: pack1 / [Link]
package pack1;
public class A {
protected void msg() {
[Link]("Message from class A (protected)");
3. PACKAGE: pack2 / [Link]
package pack2;
import pack1.A; // importing package
public class B extends A {
public void test() {
msg(); // allowed due to protected + subclass
}
4. PACKAGE: exceptionsdemo / [Link]
package exceptionsdemo;
// Custom exception subclass
public class MyCustomException extends Exception {
public MyCustomException(String msg) {
super(msg);
5. PACKAGE: exceptionsdemo / [Link] (ALL EXCEPTIONS DEMO)
package exceptionsdemo;
import [Link];
import pack2.B;
import [Link];
public class Main {
// method with throws
static void testThrows() throws IOException {
throw new IOException("IO error occurred");
// method demonstrating chained exceptions
static void chainedExceptionDemo() {
try {
NumberFormatException nfe = new NumberFormatException("Invalid number");
[Link](new ArithmeticException("Arithmetic cause"));
throw nfe;
} catch (NumberFormatException e) {
[Link]("Caught NumberFormatException: " + [Link]());
[Link]("Cause: " + [Link]());
public static void main(String[] args) {
[Link]("\n=== PACKAGE USAGE ===");
MyClass obj = new MyClass();
[Link]();
B bobj = new B();
[Link]();
[Link]("\n=== EXCEPTION HANDLING FUNDAMENTALS ===");
try {
int x = 10 / 0; // ArithmeticException
} catch (ArithmeticException e) {
[Link]("Caught: " + e);
[Link]("\n=== MULTIPLE CATCH CLAUSES ===");
try {
String s = null;
[Link]([Link]());
} catch (NullPointerException e) {
[Link]("Caught NullPointerException");
} catch (Exception e) {
[Link]("Caught general exception");
[Link]("\n=== NESTED TRY ===");
try {
try {
int arr[] = new int[2];
[Link](arr[5]); // inner exception
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Caught inside inner try");
int y = 10 / 0; // outer exception
} catch (Exception e) {
[Link]("Caught in outer try");
[Link]("\n=== throw KEYWORD ===");
try {
throw new ArithmeticException("Manually thrown exception");
} catch (Exception e) {
[Link]("Caught: " + [Link]());
}
[Link]("\n=== throws KEYWORD ===");
try {
testThrows();
} catch (IOException e) {
[Link]("Handled IOException: " + [Link]());
[Link]("\n=== finally BLOCK ===");
try {
int z = 10 / 0;
} catch (Exception e) {
[Link]("Handled exception");
} finally {
[Link]("finally always runs");
[Link]("\n=== JAVA'S BUILT-IN EXCEPTIONS ===");
try {
int num = [Link]("abc"); // NumberFormatException
} catch (NumberFormatException e) {
[Link]("Caught NumberFormatException");
}
[Link]("\n=== CUSTOM EXCEPTION ===");
try {
throw new MyCustomException("This is a custom exception!");
} catch (MyCustomException e) {
[Link]("Caught custom exception: " + [Link]());
[Link]("\n=== CHAINED EXCEPTIONS ===");
chainedExceptionDemo();
[Link]("\n=== END OF DEMO ===");
This single program demonstrates:
PACKAGES
✔ Creating packages
✔ Importing packages
✔ Protected access across packages
✔ Using classes from other packages
EXCEPTIONS
✔ Exception fundamentals
✔ Exception types (built-in, checked, unchecked)
✔ Uncaught vs caught exceptions
✔ try + catch
✔ Multiple catch
✔ Nested try
✔ throw
✔ throws
✔ finally
✔ Built-in exceptions
✔ Custom exception class
✔ Chained exceptions
Module 5
MULTITHREADED PROGRAMMING
1. The Java Thread Model
Java supports multithreading, allowing multiple tasks to run concurrently.
Two ways to create a thread:
• Extending Thread
• Implementing Runnable
2. The Main Thread
Every Java program starts with the main thread.
public class MainThreadDemo {
public static void main(String[] args) {
Thread t = [Link]();
[Link]("Main thread: " + t);
3. Creating a Thread
Method 1: Extending Thread
class MyThread extends Thread {
public void run() {
[Link]("Thread running");
}
public class Demo {
public static void main(String[] args) {
new MyThread().start();
Method 2: Implementing Runnable
class Task implements Runnable {
public void run() {
[Link]("Runnable running");
public class Demo {
public static void main(String[] args) {
Thread t = new Thread(new Task());
[Link]();
4. Creating Multiple Threads
class Worker extends Thread {
public void run() {
[Link]("Thread " + getName() + " running");
public class Demo {
public static void main(String[] args) {
new Worker().start();
new Worker().start();
new Worker().start();
5. Using isAlive() and join()
class Work extends Thread {
public void run() {
for (int i = 1; i <= 3; i++)
[Link]("Working " + i);
public class Demo {
public static void main(String[] args) throws Exception {
Work w = new Work();
[Link]();
[Link](); // wait for thread to finish
[Link]("Is thread alive? " + [Link]());
6. Thread Priorities
Threads can have priorities (1–10).
Thread t = new Thread(() -> [Link]("Hello"));
[Link](Thread.MAX_PRIORITY);
[Link]();
7. Synchronization
Prevents two or more threads from accessing shared data at the same time.
class Counter {
private int count = 0;
synchronized void increment() { count++; }
int getCount() { return count; }
8. Interthread Communication
Using wait(), notify(), notifyAll().
class Shared {
synchronized void produce() throws Exception {
[Link]("Producing...");
wait(); // waits for notification
synchronized void consume() {
[Link]("Consuming...");
notify(); // wakes producer
9. Suspending, Resuming, and Stopping Threads
These methods (suspend, resume, stop) are deprecated.
We simulate them with flags:
class MyThread extends Thread {
private boolean running = true;
public void run() {
while (running) [Link]("Running...");
public void stopThread() { running = false; }
10. Obtaining a Thread’s State
Thread t = new Thread(() -> {});
[Link]([Link]());
ENUMERATIONS, TYPE WRAPPERS & AUTOBOXING
Enumerations
1. Enumeration Fundamentals
Enums define a fixed set of constants.
enum Level { LOW, MEDIUM, HIGH }
public class Demo {
public static void main(String[] args) {
Level l = [Link];
[Link](l);
}
}
2. The values() and valueOf() Methods
for (Level lv : [Link]())
[Link](lv);
Level x = [Link]("LOW");
Type Wrappers
Java provides wrapper classes for primitive types:
Primitive Wrapper
int Integer
char Character
boolean Boolean
double Double
… …
Examples
Character
Character c = 'A';
[Link]([Link](c));
Boolean
Boolean b = [Link];
Numeric Wrappers
Integer x = [Link](10);
Double y = [Link](5.5);
Autoboxing
1. Autoboxing in Methods
void show(Integer i) {
[Link](i);
show(5); // autoboxes int → Integer
2. Autoboxing/Unboxing in Expressions
Integer a = 5; // autobox
int b = a + 10; // unboxing happens automatically
3. Autoboxing Boolean & Character
Boolean b = true; // autoboxing
boolean x = b; // unboxing
Character ch = 'A';
char c = ch;
Combined all these into ONE complete runnable Java program (multithreading + enums +
wrappers + autoboxing). Below are the example
Multithreaded Programming
Enumerations
Type Wrappers
Autoboxing
Everything is kept simple, clear, and inside one file so you can copy–paste & run easily.
FULL JAVA PROGRAM (ALL CONCEPTS IN ONE FILE)
// =============================================
// MULTITHREADING + ENUMS + TYPE WRAPPERS DEMO
// =============================================
class MultiThreadDemo {
// -------------------------------
// 1. Creating a Thread (Runnable)
// -------------------------------
static class MyThread implements Runnable {
public void run() {
[Link]("Child thread running: " + [Link]().getName());
// ------------------------------------
// 2. Multiple Threads + isAlive + join
// ------------------------------------
static class Worker extends Thread {
public Worker(String name) { super(name); }
public void run() {
for (int i = 1; i <= 3; i++) {
[Link](getName() + " -> step " + i);
try { [Link](100); } catch (Exception ignored) {}
}
}
// --------------------------------------
// 3. Synchronization + Interthread Comm.
// --------------------------------------
static class Shared {
private boolean ready = false;
synchronized void produce() throws Exception {
[Link]("Producer: Producing...");
[Link](300);
ready = true;
notify(); // Notify consumer
synchronized void consume() throws Exception {
while (!ready) {
wait(); // Wait for producer
[Link]("Consumer: Consuming...");
// =============================================
// ENUMERATIONS
// =============================================
enum Level {
LOW, MEDIUM, HIGH
// =============================================
// MAIN PROGRAM
// =============================================
public class Main {
public static void main(String[] args) throws Exception {
// =============================================
// MULTITHREADING
// =============================================
[Link]("\n=== MAIN THREAD ===");
Thread mainThread = [Link]();
[Link]("Main thread: " + [Link]());
[Link]("State: " + [Link]());
[Link]("\n=== CREATING A THREAD (Runnable) ===");
Thread t1 = new Thread(new [Link](), "Child-1");
[Link]();
[Link]("\n=== MULTIPLE THREADS + join() + isAlive() ===");
[Link] w1 = new [Link]("Worker-1");
[Link] w2 = new [Link]("Worker-2");
[Link]();
[Link]();
[Link](); // wait for thread to finish
[Link]();
[Link]("Is Worker-1 alive? " + [Link]());
[Link]("Is Worker-2 alive? " + [Link]());
[Link]("\n=== THREAD PRIORITIES ===");
[Link](Thread.MAX_PRIORITY);
[Link](Thread.MIN_PRIORITY);
[Link]([Link]() + " priority: " + [Link]());
[Link]([Link]() + " priority: " + [Link]());
[Link]("\n=== SYNCHRONIZATION + INTERTHREAD COMMUNICATION ===");
[Link] shared = new [Link]();
Thread producer = new Thread(() -> {
try { [Link](); } catch (Exception ignored) {}
});
Thread consumer = new Thread(() -> {
try { [Link](); } catch (Exception ignored) {}
});
[Link]();
[Link]();
[Link]();
[Link]();
[Link]("\n=== OBTAINING THREAD STATE ===");
Thread temp = new Thread(() -> {});
[Link]("State before start: " + [Link]());
[Link]();
[Link]("State after start: " + [Link]());
// =============================================
// ENUMERATIONS
// =============================================
[Link]("\n=== ENUMERATIONS ===");
Level level = [Link];
[Link]("Selected Level: " + level);
[Link]("All values:");
for (Level l : [Link]()) {
[Link](l);
}
Level lv = [Link]("LOW");
[Link]("valueOf LOW: " + lv);
// =============================================
// TYPE WRAPPERS & AUTOBOXING
// =============================================
[Link]("\n=== TYPE WRAPPERS ===");
Integer intObj = [Link](100);
Double doubleObj = [Link](3.14);
Character charObj = [Link]('A');
Boolean boolObj = [Link];
[Link]("Integer: " + intObj);
[Link]("Double: " + doubleObj);
[Link]("Character: " + charObj);
[Link]("Boolean: " + boolObj);
[Link]("\n=== AUTOBOXING & UNBOXING ===");
Integer a = 10; // autoboxing
int b = a; // unboxing
int c = a + 20; // unboxing in expression
Boolean bb = true; // autobox
boolean cc = bb; // unboxed
Character ch = 'Z'; // autobox
char ch2 = ch; // unbox
[Link]("Autobox int -> " + a);
[Link]("Unboxed int -> " + b);
[Link]("a + 20 = " + c);
[Link]("Boolean: " + cc);
[Link]("Character: " + ch2);
[Link]("\n=== END OF ALL DEMOS ===");
THIS PROGRAM SHOWS EVERYTHING
Multithreading
✔ Java Thread Model
✔ Main Thread
✔ Creating Threads (Runnable + Thread)
✔ Multiple Threads
✔ isAlive() and join()
✔ Thread Priorities
✔ Synchronization (synchronized)
✔ Interthread Communication (wait/notify)
✔ Deprecated operations replaced (safe flags)
✔ Obtaining Thread State
Enumerations
✔ Enum creation
✔ values()
✔ valueOf()
Type Wrappers
✔ Character
✔ Boolean
✔ Numeric wrappers (Integer, Double)
Autoboxing
✔ Autoboxing in methods
✔ Unboxing in expressions
✔ Boolean / Character autoboxing