1. History of Java & JDK, JRE, JVM

1. History of Java

The history of Java starts with the Green Team. Java team members (also known as the Green Team) initiated a revolutionary task to develop a language for digital devices such as set-top boxes, televisions, etc.

For the Green Team members, it was an advanced concept at the time, but it was highly suited for internet programming. Later, Java technology was incorporated by Netscape.

Currently, Java is used in internet programming, mobile devices, games, e-business solutions, etc. The major milestones in the history of Java include:

  • Green Team: James Gosling, Mike Sheridan, and Patrick Naughton initiated the Java language project in June 1991.
  • Initial Design: Originally designed for small, embedded systems in electronic appliances like set-top boxes.
  • "Greentalk": It was first called Greentalk by James Gosling, and the file extension was .gt.
  • Oak: After Greentalk, it was renamed Oak and was developed as a part of the Green project. (It was later renamed Java because Oak was already a trademark of another company).

2. Java Version History

Many Java versions have been released over the years. Here is a brief look at the early version releases:

Version Release Date
JDK Alpha and Beta 1995
JDK 1.0 23rd January, 1996
JDK 1.1 19th February, 1997
J2SE 1.2 8th December, 1998
J2SE 1.3 8th May, 2000
J2SE 1.4 6th February, 2002
J2SE 5.0 30th September, 2004
Java SE 6 11th December, 2006
Java SE 7 28th July, 2011
Java SE 8 18th March, 2014

3. JDK, JRE, and JVM

To write, compile, and run Java programs, you need to understand three interconnected core components of the Java environment:

  • JDK (Java Development Kit): The complete software development environment used to build Java applications. It physically exists and contains development tools (like the compiler javac, archiver jar, debugger, etc.) along with the JRE.
  • JRE (Java Runtime Environment): The minimum environment required to run a Java program. It physically exists and contains the JVM, core libraries, and other components to run applications, but does not contain development tools like a compiler.
  • JVM (Java Virtual Machine): An abstract machine that provides the runtime environment in which Java bytecode is executed. It is platform-dependent (different for Windows, Mac, Linux) and is responsible for making Java "Write Once, Run Anywhere" (platform independent).

Visual Hierarchy:

JDK (Java Development Kit)

Contains everything needed to develop Java apps (Compiler javac, Debugger, etc.) + JRE.

JRE (Java Runtime Environment)

Contains everything needed to run Java apps (Libraries, Class Loader) + JVM.

JVM (Java Virtual Machine)

Executes the bytecode (line-by-line interpretation) and makes Java Platform Independent.

4. Buzzwords in Java

Java has many advanced features. A list of key features is known as Java Buzz Words. The Java team has listed the following terms as Java buzz words.

Java is an object-oriented programming language with syntax and keywords almost identical to C++. Java inherits all the best features from the programming languages like C, C++ and thus makes it easy for any developer. Java has removed many complicated and rarely-used features, such as explicit pointers and operator overloading.

Java does not use pointers, which helps prevent unauthorized memory access.

The JVM verifies Java bytecode before execution, ensuring that it adheres to Javaโ€™s security constraints.

Java applications run in a restricted environment (sandbox) that limits their access to system resources and user data, enhancing security.

Everything in Java revolves around objects and classes.

Java allows you to model real-world entities (like a car or a bank account) as objects in your program, making it easier to manage and build complex applications.

Key Object-Oriented Programming (OOP) concepts include:

  • Object: An instance of a class.
  • Class: A blueprint for creating objects.
  • Inheritance: Allows one class to inherit the properties of another.
  • Polymorphism: The ability of objects to take on multiple forms.
  • Abstraction: Hides the complex details and shows only the essentials.
  • Encapsulation: Keeps the data safe by restricting access to it.

Programs can be executed on any kind of computer containing JVM. When compiled, it generates an intermediate code file called as "bytecode". Bytecode helps java to achieve portability. This bytecode can be taken to any computer and executed directly.

Programming language is robust when it is reliable and strong. Below capabilities make java robust:

  • Garbage Collection: Java has a garbage collector which will automatically clean up unused objects and memory. No need to chase memory corruption.
  • Pointer-Free Security: In java you do not use pointers to access strings, arrays, objects, even files. Nor do you need to worry about memory allocation for them.
  • Exception Handling: Java has exception handling mechanism which is very useful in handling both compile and run time errors. Without handling errors and exceptions, entire application would fail. With exception handling it just stops the current flows even when failed, but rest all flows still runs.

Java has invented to archive "write once; run anywhere, anytime, forever". It provides JVM (Java Virtual Machine) to archive architectural-neutral or platform-independent. The JVM allows the java program created using one operating system can be executed on any other operating system.

Java supports multi-threading programming, which allows us to write programs that do multiple operations simultaneously.

Java provides high performance with the help of features like JVM, interpretation, and its simplicity.

Java enables the creation of cross-platform programs by compiling into an intermediate representation called Java bytecode. The byte code is interpreted to any machine code so that it runs on the native machine.

Java programming language supports Transmission Control protocol/Internet Protocol (TCP/IP) which enable the java to support the distributed environment of the Internet. It also supports Remote Method Invocation (RMI), this feature enables a program to invoke methods across a network.

Java is said to be dynamic because the java byte code may be dynamically updated on a running system and it has a dynamic memory allocation and deallocation (objects and garbage collector).

5. Creating a Stand-Alone Java Application

To compile and run a stand-alone Java application using the JDK on your local machine, follow these steps:

  1. Write the Code: Create a Java class with a main method. Save it as Main.java.
    Main.java
    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello, Java World!");
        }
    }
  2. Set the Environment Path (Windows):
    • Go to C:\Program Files\Java\, look inside and open the JDK folder, then open the bin folder (e.g., C:\Program Files\Java\jdk-xx\bin). Copy this path.
    • Right-click "This PC" (or "My Computer"), select Properties, click Advanced system settings, and click Environment Variables.
    • Under System Variables, find and select the Path variable, click Edit, and click New. Paste the copied path and save.
  3. Compile the Program: Open the Command Prompt (cmd), navigate to the folder containing your Main.java file, and run:
    javac Main.java
    This compiles the source code into bytecode, producing a Main.class file.
  4. Run the Program: Execute the compiled bytecode by running:
    java Main
    This runs the JVM and executes the class, displaying Hello, Java World! in the console.

6. Java Comments

The Java comments are statements that are not executed by the compiler and interpreter. Comments can be used to provide information or explanation about the variable, method, class, or any statement. It can also be used to hide program code for a specific time.

There are 3 types of comments in Java:

  • Single Line Comment: Used to comment only one line of code. It starts with two forward slashes //.
  • Multi Line Comment: Used to comment multiple lines of code. It starts with /* and ends with */.
  • Documentation Comment: Used to create documentation API. It starts with /** and ends with */. The javadoc tool is used to generate HTML documentation from these comments.
Java Comments Examples
/** 
   3. Documentation Comment Example:
   The CommentDemo class demonstrates different types of Java comments.
*/
public class CommentDemo {
    public static void main(String[] args) {
        // 1. Single Line Comment Example
        int i = 10; // Here, i is a variable

        /* 
           2. Multi Line Comment Example
           This is a comment that
           spans across multiple lines
        */
        int j = 20;

        int sum = i + j;
        System.out.println("Sum: " + sum);
    }
}

2. Principles of OOP (Object-Oriented Programming)

Object-Oriented Programming (OOP) is a programming paradigm centered around objects rather than just functions and logic. An object is a data field that has unique attributes and behavior. The main goal of OOP is to bind together the data and the functions that operate on them so that no other part of the code can access this data except that function.

1. POP vs. OOP Paradigm Comparison

Before diving into OOP principles, it is important to understand the difference between Procedural Oriented Programming (POP) and Object-Oriented Programming (OOP) paradigms:

Features Procedural Oriented Programming (POP) Object-Oriented Programming (OOP)
Divided into Program is divided into smaller parts called functions. Program is divided into parts known as objects.
Importance Importance is given to sequence of actions/functions rather than data. Importance is given to data rather than procedures or functions because it models the real world.
Approach Follows a Top-Down approach. Follows a Bottom-Up approach.
Access Specifiers Does not have any access specifiers. Has access specifiers (e.g., public, private, protected).
Data Moving Data can move freely from function to function in the system. Objects can move and communicate with each other through member functions.
Data Access Most functions use global data that can be accessed freely throughout the system. Data cannot move easily. It is protected and access is controlled via public/private specifiers.
Data Hiding No proper way for hiding data, making it less secure. Provides data hiding, making it more secure.
Overloading Overloading is not possible. Overloading is possible (Function Overloading and Operator Overloading).
Examples C, Visual Basic, FORTRAN, Pascal. C++, Java, VB.NET, C#.NET.

2. Core Pillars of OOP

The four core pillars of OOP are:

graph TD; A[Object-Oriented Programming] --> B(Encapsulation); A --> C(Inheritance); A --> D(Polymorphism); A --> E(Abstraction); style A fill:#2563eb,stroke:#1e40af,stroke-width:2px,color:#fff,font-weight:bold,rx:10,ry:10; style B fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff,rx:5,ry:5; style C fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff,rx:5,ry:5; style D fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff,rx:5,ry:5; style E fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff,rx:5,ry:5;
๐Ÿ’Š

1. Encapsulation

Definition: Encapsulation is the mechanism of wrapping code (methods) and the data it manipulates (variables) together into a single unit, known as a class.

Why it's used: It helps in data hiding. By making class variables private and providing public getter and setter methods, we can protect the internal state of an object from unintended modification by external code.

Real-world Analogy: A medical capsule. The medicine (data) is safely enclosed inside the capsule shell (methods), protecting it from external contamination.

classDiagram class Person{ -String name +getName() String +setName(String newName) void }
Encapsulation Example
class Person {
    // private variable = restricted access
    private String name;

    // Getter method to access private variable
    public String getName() {
        return name;
    }

    // Setter method to modify private variable
    public void setName(String newName) {
        this.name = newName;
    }
}
๐ŸŒณ

2. Inheritance

Definition: Inheritance is the process where one class (subclass) acquires the properties (fields) and behaviors (methods) of another class (superclass).

Why it's used: It provides code reusability. Instead of writing the same methods repeatedly, a child class simply extends the parent class.

Real-world Analogy: A child inherits physical traits (e.g., eye color, height) and behaviors from their parents.

classDiagram direction BT Dog --|> Animal : extends class Animal{ +eat() void } class Dog{ +bark() void }
Inheritance Example
class Animal {
    void eat() {
        System.out.println("This animal eats food.");
    }
}

// Dog extends Animal (IS-A relationship)
class Dog extends Animal {
    void bark() {
        System.out.println("The dog barks.");
    }
}
๐ŸŽญ

3. Polymorphism

Definition: Polymorphism translates to "many forms". It allows methods to do different things based on the object it is acting upon.

Types in Java:

  • Compile-time (Static): Achieved through Method Overloading (same method name, different parameters).
  • Runtime (Dynamic): Achieved through Method Overriding (same method name and signature in subclass).

Real-world Analogy: A person at the same time can have different roles. A man is simultaneously a father, a husband, and an employee. His behavior changes depending on the situation he is in.

graph TD A["MathOperations"] --- B("add(int, int)") --> C["Returns int"] A --- D("add(double, double)") --> E["Returns double"]
Polymorphism Example (Overloading)
class MathOperations {
    // Method with 2 int parameters
    int add(int a, int b) {
        return a + b;
    }
    
    // Overloaded method with 2 double parameters
    double add(double a, double b) {
        return a + b;
    }
}
โ˜๏ธ

4. Abstraction

Definition: Abstraction is the process of hiding the complex implementation details and showing only the essential features to the user.

Why it's used: It reduces complexity and allows developers to focus on what the object does rather than how it does it. In Java, this is achieved using abstract classes and interfaces.

Real-world Analogy: Driving a car. You know that pressing the accelerator speeds up the car, but you don't need to know the complex inner mechanics of the engine or fuel injection to drive.

graph TD A["Shape (Abstract Class)"] -.-> B("draw() method (Abstract)") C["Circle (Concrete Subclass)"] --> A style A fill:#4b5563,color:#fff,stroke-dasharray: 5 5 style B fill:#3b82f6,color:#fff style C fill:#3b82f6,color:#fff
Abstraction Example
// Abstract class hides implementation details
abstract class Shape {
    abstract void draw(); // No body
}

class Circle extends Shape {
    // Subclass provides the implementation
    void draw() {
        System.out.println("Drawing a circle...");
    }
}

3. Data Types, Variables and Arrays

This section covers how data is stored and manipulated in Java memory.

1. Variables

A variable is a container that holds data while the Java program is executed. A variable is assigned a data type, which dictates what kind of data it can hold.

  • Local Variables: Declared inside a method and destroyed when the method exits.
  • Instance Variables: Declared inside a class but outside methods. They belong to the object.
  • Static Variables: Declared with the static keyword. They belong to the class, not the object.
Variables Example
public class VariablesDemo {
    // 1. Static Variable (Class Variable) - declared with static keyword
    static String college = "MIT";

    // 2. Instance Variable - declared inside the class but outside any method
    // (Accessing it requires creating an object, which is covered in Chapter 6)
    String studentName = "Alice";

    public static void main(String[] args) {
        // 3. Local Variable - declared inside a method
        int studyHours = 5;

        System.out.println("College Name (Static Variable): " + college);
        System.out.println("Study Hours (Local Variable): " + studyHours);
    }
}

2. Data Types

Data types specify the different sizes and values that can be stored in the variable. Java is a statically typed language, meaning all variables must first be declared before they can be used.

There are two major categories:

  • Primitive Data Types: Predefined by Java (int, char, boolean, etc.).
  • Non-Primitive (Reference) Data Types: Created by the programmer (Classes, Arrays, Strings, Interfaces).
Category Type Size Range Default Value
Integer byte 1 byte -128 to 127 0
short 2 bytes -32,768 to 32,767 0
int 4 bytes -2,147,483,648 to 2,147,483,647 0
long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 0L
Floating-Point float 4 bytes 1.4e-45 to 3.4e+38 (approx. 6-7 significant digits) 0.0f
double 8 bytes 4.9e-324 to 1.7e+308 (approx. 15 significant digits) 0.0d
Character char 2 bytes 0 to 65,535 ('\u0000' to '\uffff') '\u0000'
Boolean boolean 1 bit (logically) true or false false
Primitive Data Types Example
public class DataTypesDemo {
    public static void main(String[] args) {
        int age = 21;                  // Integer
        double salary = 55000.50;      // Decimal number
        char grade = 'A';              // Single character
        boolean isPassed = true;       // True or false

        System.out.println("Age: " + age);
        System.out.println("Salary: " + salary);
        System.out.println("Grade: " + grade);
        System.out.println("Passed: " + isPassed);
    }
}

3. Arrays

Java provides a data structure, the array, which stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.

Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], ..., and numbers[99] to represent individual variables.

Declaring Array Variables

To use an array in a program, you must declare a variable to reference the array, and you must specify the type of array the variable can reference. There are two syntaxes for declaring an array variable:

  • dataType[] arrayRefVar; (Preferred way)
  • dataType arrayRefVar[]; (Works, but not preferred. Adopted in Java to accommodate C/C++ programmers)

Creating Arrays

You can create an array by using the new operator with the following syntax:

arrayRefVar = new dataType[arraySize];

The above statement does two things:

  • It creates an array using new dataType[arraySize];
  • It assigns the reference of the newly created array to the variable arrayRefVar.

Declaring and creating can be combined in one statement:

dataType[] arrayRefVar = new dataType[arraySize];

Alternatively, you can initialize arrays directly with values:

dataType[] arrayRefVar = {value0, value1, ..., valuek};

Accessing Array Elements

Array elements are accessed through the index. Array indices are 0-based, meaning they start from 0 up to arrayRefVar.length - 1.

Processing Arrays

When processing array elements, we often use either a for loop or a for-each loop because all elements are of the same type and the size of the array is known.

Processing Arrays Example
public class TestArray {
    public static void main(String[] args) {
        double[] myList = {1.9, 2.9, 3.4, 3.5};

        // Print all the array elements using standard for loop
        System.out.println("Array elements:");
        for (int i = 0; i < myList.length; i++) {
            System.out.print(myList[i] + " ");
        }
        System.out.println();

        // Print elements using for-each loop
        System.out.println("Array elements (for-each):");
        for (double element : myList) {
            System.out.print(element + " ");
        }
        System.out.println();

        // Summing all elements
        double total = 0;
        for (int i = 0; i < myList.length; i++) {
            total += myList[i];
        }
        System.out.println("Total is " + total);

        // Finding the largest element
        double max = myList[0];
        for (int i = 1; i < myList.length; i++) {
            if (myList[i] > max) {
                max = myList[i];
            }
        }
        System.out.println("Max is " + max);
    }
}

Multi-Dimensional Arrays (2D Arrays)

Multi-dimensional arrays are arrays of arrays, commonly used to represent grids or matrices.

2D Array Example
public class TwoDArrayExample {
    public static void main(String[] args) {
        // Declaring and initializing a 2D Array
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6}
        };

        // Accessing an element (row 1, column 2)
        System.out.println(matrix[1][2]); // Outputs 6
    }
}

4. Operators

Operator in java is a symbol that is used to perform operations. For example: +, -, *, / etc.

Types of operators in java:

  • Unary: expr++, expr--, ++expr, --expr, +expr, -expr, ~, !
  • Arithmetic: +, -, *, /, %
  • Shift: <<, >>, >>>
  • Relational: ==, !=, >, <, >=, <=, instanceof
  • Logical: && (AND), || (OR)
  • Bitwise: &, |, ^
  • Ternary: ? :
  • Assignment: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=

Operators Hierarchy (Precedence)

Operators Precedence
postfix expr++ expr--
unary ++expr --expr +expr -expr ~ !
multiplicative * / %
additive + -
shift << >> >>>
relational < > <= >= instanceof
equality == !=
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
ternary ? :
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=

5. Control Statements

The control flow statements in Java allow you to run or skip blocks of code when special conditions are met.

graph TD A["Control Statement"] --> B("Branching statement
(Decision making)") A --> C("Looping statement") A --> D("Jumping statement") B --> B1["if"] B --> B2["if-else"] B --> B3["elseif"] B --> B4["switch"] C --> C1["for loop"] C --> C2["while loop"] C --> C3["do while loop"] D --> D1["break"] D --> D2["continue"] style A fill:#2563eb,color:#fff style B fill:#3b82f6,color:#fff style C fill:#3b82f6,color:#fff style D fill:#3b82f6,color:#fff

1. Decision-Making (Branching) Statements

Decision-making statements decide which statement or block of statements to execute based on a boolean condition.

A. Simple if Statement

It evaluates a single condition. If the condition is true, the block of code inside the if statement is executed.

Simple if Example
public class IfExample {
    public static void main(String[] args) {
        int age = 20;
        if (age >= 18) {
            System.out.println("You are eligible to vote.");
        }
    }
}

B. if-else Statement

It evaluates a condition. If the condition is true, the if block is executed; otherwise, the else block is executed.

if-else Example
public class IfElseExample {
    public static void main(String[] args) {
        int number = 13;
        if (number % 2 == 0) {
            System.out.println("Even number.");
        } else {
            System.out.println("Odd number.");
        }
    }
}

C. if-else-if Ladder

It allows executing one block of code from multiple choices by testing a series of conditions sequentially.

if-else-if Ladder Example
public class IfElseIfExample {
    public static void main(String[] args) {
        int score = 85;
        if (score >= 90) {
            System.out.println("Grade: A");
        } else if (score >= 80) {
            System.out.println("Grade: B");
        } else if (score >= 70) {
            System.out.println("Grade: C");
        } else {
            System.out.println("Grade: F");
        }
    }
}

D. Nested if Statement

An if statement inside another if statement is called a nested if. It is executed only when the outer condition is true.

Nested if Example
public class NestedIfExample {
    public static void main(String[] args) {
        int age = 25;
        int weight = 55;
        if (age >= 18) {
            if (weight >= 50) {
                System.out.println("You are eligible to donate blood.");
            }
        }
    }
}

E. switch Statement

It executes one statement from multiple conditions. It is similar to an if-else-if ladder but operates on byte, short, int, char, String, or enums, and offers better readability.

switch Example
public class SwitchExample {
    public static void main(String[] args) {
        int day = 3;
        switch (day) {
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                break;
            case 3:
                System.out.println("Wednesday");
                break;
            default:
                System.out.println("Invalid Day");
                break;
        }
    }
}

2. Looping (Iteration) Statements

Looping statements execute a block of code repeatedly as long as a specified condition remains true.

A. for Loop

The standard for loop is used when the number of iterations is known in advance. It contains initialization, condition, and increment/decrement in a single line.

for Loop Example
public class ForLoopExample {
    public static void main(String[] args) {
        // Print numbers from 1 to 5
        for (int i = 1; i <= 5; i++) {
            System.out.println("i = " + i);
        }
    }
}

B. Enhanced for (For-Each) Loop

Used specifically to iterate through arrays or collections without using index counters.

For-Each Loop Example
public class ForEachExample {
    public static void main(String[] args) {
        int[] numbers = {10, 20, 30, 40};
        for (int num : numbers) {
            System.out.println("Number: " + num);
        }
    }
}

C. while Loop

Used when the number of iterations is not fixed beforehand. It checks the condition first, and if true, executes the body.

while Loop Example
public class WhileLoopExample {
    public static void main(String[] args) {
        int count = 1;
        while (count <= 3) {
            System.out.println("Count is: " + count);
            count++;
        }
    }
}

D. do-while Loop

Similar to the while loop, but it evaluates the condition at the end of the loop. Thus, the loop body is guaranteed to run at least once.

do-while Loop Example
public class DoWhileExample {
    public static void main(String[] args) {
        int i = 10;
        do {
            System.out.println("Executed once: i = " + i);
            i++;
        } while (i < 10);
    }
}

3. Jumping Statements

Jumping statements transfer control of program execution from one point to another within the program.

A. break Statement

Used to terminate a loop or a switch block immediately, skipping the remaining iterations or cases.

break Statement Example
public class BreakExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            if (i == 5) {
                break; // exits loop when i is 5
            }
            System.out.println("i = " + i);
        }
    }
}

B. continue Statement

Skips the remaining statements in the current iteration of the loop and moves to the next iteration.

continue Statement Example
public class ContinueExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            if (i == 3) {
                continue; // skips printing 3
            }
            System.out.println("i = " + i);
        }
    }
}

C. return Statement

Used to explicitly return from a method. It terminates the method execution and can return a value to the caller.

return Statement Example
public class ReturnExample {
    public static int multiply(int x, int y) {
        return x * y; // Returns product and exits method
    }

    public static void main(String[] args) {
        int result = multiply(5, 4);
        System.out.println("Result: " + result);
    }
}

6. Classes & Objects

Java is an object-oriented programming language. The core concept of the object-oriented approach is to break complex problems into smaller objects.

An object is any entity that has a state and behavior. For example, a bicycle is an object. It has:

  • States: idle, first gear, etc.
  • Behaviors: braking, accelerating, etc.

Before we learn about objects, let's first know about classes in Java.

Java Class

A class is a blueprint for the object. Before we create an object, we first need to define the class.

We can think of the class as a sketch (prototype) of a house. It contains all the details about the floors, doors, windows, etc. Based on these descriptions we build the house. The house is the object.

Since many houses can be made from the same description, we can create many objects from a class.

Create a Class in Java

We can create a class in Java using the class keyword. For example:

Java Class Structure Template
class ClassName {
    // fields (state)
    // methods (behavior)
}

Here, fields (variables) and methods represent the state and behavior of the object respectively:

  • fields: used to store data
  • methods: used to perform some operations

For our bicycle object, we can create the class as:

Bicycle.java
class Bicycle {
    // state or field
    private int gear = 5;

    // behavior or method
    public void braking() {
        System.out.println("Working of Braking");
    }
}

In the above example, we have created a class named Bicycle. It contains a field named gear and a method named braking().

Here, Bicycle is a prototype/sketch. Now, we can create any number of bicycles using this prototype, and all the bicycles will share the fields and methods of the prototype.

Note: We have used keywords private and public. These are known as access modifiers. To learn more, visit Java access modifiers.

Java Objects

An object is called an instance of a class. For example, suppose Bicycle is a class, then MountainBicycle, SportsBicycle, TouringBicycle, etc. can be considered as objects of the class.

Creating an Object in Java

Here is how we can create an object of a class:

Object Creation Syntax
className objectName = new className();

// For Bicycle class:
Bicycle sportsBicycle = new Bicycle();
Bicycle touringBicycle = new Bicycle();

We have used the new keyword along with the constructor of the class to create an object. Constructors are similar to methods and have the same name as the class. For example, Bicycle() is the constructor of the Bicycle class.

Here, sportsBicycle and touringBicycle are the names of objects. We can use them to access fields and methods of the class. As you can see, we can create multiple objects of a single class in Java.

Note: Fields and methods of a class are also called members of the class.

Access Members of a Class

We can use the name of objects along with the dot . operator to access members of a class. For example:

Accessing Members Example
class Bicycle {
    // field of class
    int gear = 5;

    // method of class
    void braking() {
        System.out.println("Braking...");
    }
}

public class Main {
    public static void main(String[] args) {
        // create object
        Bicycle sportsBicycle = new Bicycle();

        // access field and method
        int currentGear = sportsBicycle.gear;
        sportsBicycle.braking();
    }
}

Here, we have created an object of Bicycle named sportsBicycle. We then use the object to access the field and method of the class:

  • sportsBicycle.gear - access the field gear
  • sportsBicycle.braking() - access the method braking()

Example: Java Class and Objects

Let's see a fully working example with a Lamp class:

LampExample.java
class Lamp {
    // stores the value for light
    // true if light is on, false if light is off
    boolean isOn;

    // method to turn on the light
    void turnOn() {
        isOn = true;
        System.out.println("Light on? " + isOn);
    }

    // method to turn off the light
    void turnOff() {
        isOn = false;
        System.out.println("Light on? " + isOn);
    }
}

public class Main {
    public static void main(String[] args) {
        // create objects led and halogen
        Lamp led = new Lamp();
        Lamp halogen = new Lamp();

        // turn on the light by calling method turnOn()
        led.turnOn();

        // turn off the light by calling method turnOff()
        halogen.turnOff();
    }
}
Console Output
Light on? true
Light on? false

In the above program, we have created a class named Lamp. It contains a variable isOn and two methods: turnOn() and turnOff().

Inside the Main class, we have created two objects: led and halogen of the Lamp class. We then used the objects to call the methods of the class.

  • led.turnOn() - Sets the isOn variable to true and prints the output.
  • halogen.turnOff() - Sets the isOn variable to false and prints the output.

The variable isOn defined inside the class is also called an instance variable. It is because when we create an object of the class, it is called an instance of the class. And, each instance will have its own copy of the variable (i.e., led and halogen objects will have their own copy of the isOn variable).

Example: Create Objects Inside the Same Class

Note that in the previous example, we created objects inside another class (Main) and accessed the members from that class. However, we can also create objects inside the same class:

LampInside.java
class Lamp {
    // stores the value for light
    // true if light is on, false if light is off
    boolean isOn;

    // method to turn on the light
    void turnOn() {
        isOn = true;
        System.out.println("Light on? " + isOn);
    }

    public static void main(String[] args) {
        // create an object of Lamp inside the main() method of same class
        Lamp led = new Lamp();

        // access method using object
        led.turnOn();
    }
}
Console Output
Light on? true

Here, we are creating the object inside the main() method of the same class.

7. Constructors

Constructor in java is a special type of method that is used to initialize the object. Java constructor is invoked at the time of object creation.

Rules:

  • Constructor name must be same as its class name.
  • Constructor must have no explicit return type.

Types of java constructors:

  • Default constructor (no-arg constructor): A constructor that have no parameter is known as default constructor. The java compiler provides a default constructor if you don't have any.
  • Parameterized constructor: A constructor which has a specific number of parameters.

Difference between Constructor and Method

Java Constructor Java Method
Constructor is used to initialize the state of an object. Method is used to expose behaviour of an object.
Constructor must not have return type. Method must have return type.
Constructor is invoked implicitly. Method is invoked explicitly.
The java compiler provides a default constructor if you don't have any constructor. Method is not provided by compiler in any case.
Constructor name must be same as the class name. Method name may or may not be same as class name.

8. Method Overriding

If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in java.

Usage

  • Method overriding is used to provide specific implementation of a method that is already provided by its super class.
  • Method overriding is used for runtime polymorphism.

Rules for Java Method Overriding

  • Method must have same name as in the parent class.
  • Method must have same parameter as in the parent class.
  • Must be IS-A relationship (inheritance).
Method Overriding Example
class Vehicle {
    void run() {
        System.out.println("Vehicle is running");
    }
}

class Bike extends Vehicle {
    void run() {
        System.out.println("Bike is running safely");
    }

    public static void main(String args[]) {
        Bike obj = new Bike();
        obj.run(); // Calls the overridden method in Bike
    }
}

9. Access Specifiers (Modifiers)

There are two types of modifiers in java: access modifiers and non-access modifiers. The access modifiers in java specifies accessibility (scope) of a data member, method, constructor or class.

  • private: The private access modifier is accessible only within class.
  • default: If you don't use any modifier, it is treated as default by default. The default modifier is accessible only within package.
  • protected: The protected access modifier is accessible within package and outside the package but through inheritance only.
  • public: The public access modifier is accessible everywhere. It has the widest scope among all other modifiers.

Understanding all java access modifiers

Access Modifier within class within package outside package by subclass only outside package
Private Y N N N
Default Y Y N N
Protected Y Y Y N
Public Y Y Y Y

10. Static Fields and Methods

The static keyword in java is used for memory management mainly. We can apply java static keyword with variables, methods, blocks and nested class. The static keyword belongs to the class than instance of the class.

Advantage of static variable: It makes your program memory efficient (i.e it saves memory).

  • Static Variable (class variable): The static variable can be used to refer the common property of all objects (e.g. company name of employees). It gets memory only once in class area at the time of class loading.
  • Static Method (class method): A static method belongs to the class rather than object of a class. It can be invoked without the need for creating an instance of a class.
  • Static Block: Is used to initialize the static data member. It is executed before main method at the time of class loading.

11. Inheritance in Java

Inheritance in java is a mechanism in which one object acquires all the properties and behaviors of parent object. Inheritance represents the IS-A relationship, also known as parent-child relationship.

Why use inheritance in java

  • For Method Overriding (so runtime polymorphism can be achieved).
  • For Code Reusability.

Syntax of Java Inheritance

class Subclass-name extends Superclass-name {
    // methods and fields
}

The extends keyword indicates that you are making a new class that derives from an existing class. The meaning of "extends" is to increase the functionality.

super keyword in java

The super keyword in java is a reference variable which is used to refer immediate parent class object. It can be used to refer immediate parent class instance variable, invoke immediate parent class method, or invoke immediate parent class constructor using super().

Single

Class B extends Class A.

Multilevel

Class C extends Class B, which extends Class A.

Hierarchical

Classes B and C both extend Class A.

Note: Multiple inheritance (Class C extends A, B) is not supported in Java via classes, only via Interfaces.


๐Ÿ’ป Lab Practicals

Practical 1: Constructors and Static Members

Aim: Write a Java program to demonstrate default/parameterized constructors and static variables/methods.

Employee.java
class Employee {
    int empId;
    String name;
    static String company = "TechCorp"; // Static variable

    // Default Constructor
    Employee() {
        this.empId = 0;
        this.name = "Unknown";
    }

    // Parameterized Constructor
    Employee(int empId, String name) {
        this.empId = empId;
        this.name = name;
    }

    // Static Method
    static void changeCompany() {
        company = "GlobalTech";
    }

    void display() {
        System.out.println(empId + " - " + name + " (" + company + ")");
    }
}

public class Main {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee(101, "John");
        
        e1.display();
        e2.display();
        
        Employee.changeCompany(); // Calling static method
        
        System.out.println("\nAfter changing company name:");
        e1.display();
        e2.display();
    }
}

Practical 2: Inheritance and Method Overriding

Aim: Write a Java program to demonstrate inheritance, method overriding, and the use of the super keyword.

VehicleSystem.java
class Vehicle {
    int speed = 100;

    void run() {
        System.out.println("Vehicle is running...");
    }
}

class Bike extends Vehicle {
    int speed = 60;

    // Method Overriding
    @Override
    void run() {
        System.out.println("Bike is running safely at " + speed + " km/h");
        
        // Accessing parent class variable using super
        System.out.println("Max Vehicle Speed: " + super.speed + " km/h");
        
        // Accessing parent class method using super
        super.run();
    }
}

public class InheritanceTest {
    public static void main(String[] args) {
        Bike b = new Bike();
        b.run();
    }
}