Java Programming Fundamentals and Core Features

Introduction to Java and Its Key Features

Java is a high-level, object-oriented programming language developed by Sun Microsystems in 1995 (now owned by Oracle Corporation). It is designed to be simple, secure, portable, and platform-independent.

The main idea behind Java is “Write Once, Run Anywhere (WORA)”, meaning a Java program can run on any device that has a Java Virtual Machine (JVM). Java is widely used for:

  • Web applications
  • Mobile applications (especially Android)
  • Desktop software
  • Enterprise systems
  • Games and embedded systems

Core Features of Java

  1. Simple: Java has a clean and easy-to-understand syntax similar to C++. It removes complex features like pointers and operator overloading, making it easier to learn.
  2. Object-Oriented: Java follows Object-Oriented Programming (OOP) concepts such as:
    • Class and Object
    • Inheritance
    • Polymorphism
    • Encapsulation
    • Abstraction
  3. Platform Independent: Java programs are compiled into bytecode, which runs on the Java Virtual Machine (JVM). So, Java can run on any platform (Windows, Linux, Mac) without modification.
  4. Secure: Java provides strong security features:
    • No use of pointers
    • Bytecode verification
    • Security manager
    This makes Java suitable for internet-based applications.
  5. Robust: Java is strong and reliable because:
    • It uses automatic memory management (Garbage Collection).
    • It has strong error handling (Exception Handling).
  6. Multithreaded: Java supports multithreading, allowing multiple tasks to run simultaneously, improving performance.
  7. High Performance: Although slower than languages like C++, Java is faster than many interpreted languages due to:
    • Just-In-Time (JIT) compiler
    • Optimized bytecode execution
  8. Distributed: Java is designed for network-based applications and supports distributed computing using APIs like RMI (Remote Method Invocation).
  9. Dynamic: Java can adapt to changing environments. It supports:
    • Dynamic memory allocation
    • Runtime class loading
  10. Portable: Java programs can be easily transferred from one system to another due to platform independence.

Java vs. C++: Key Differences

FeatureC++Java
NatureProcedural + Object-orientedPure object-oriented language
Platform DependencyPlatform dependentPlatform independent (WORA)
PointersSupports pointersDoes not support pointers (More secure)
Memory ManagementManual (new/delete)Automatic garbage collection
Multiple InheritanceSupported through classesSupported only through interfaces
Compilation & ExecutionSource → Compiler → Machine code (.exe)Source → Compiler → Bytecode (.class) → JVM
Operator OverloadingSupportedNot supported
SpeedFaster (Direct machine code)Slower (Bytecode interpretation)
Structure vs. ClassSupports both struct and classOnly supports class

JDK, JRE, and JVM Architecture

1. JDK – Java Development Kit

JDK is a software development kit used for developing Java applications.

Formula: JDK = JRE + Development Tools

Components: Compiler (javac), Interpreter (java), Debugger (jdb), Archiver (jar), JRE, and other tools.

Purpose: Used by programmers to write, compile, and debug Java programs.

2. JRE – Java Runtime Environment

JRE provides the environment to run Java programs. It does not contain development tools.

Formula: JRE = JVM + Java Class Libraries + Supporting Files

Components: JVM, rt.jar (runtime class libraries), and deployment technologies.

Purpose: Used by end-users to run Java applications.

3. JVM – Java Virtual Machine

JVM is the core part of Java. It provides platform independence.

Function: Converts bytecode (.class) into machine code and executes it.

  • Class Loader Subsystem: Loads .class files into memory and performs linking and initialization.
  • Runtime Data Area / Memory Area:
    • Method Area: Stores class structure and method data.
    • Heap Area: Stores all objects and arrays.
    • Java Stack: Stores method calls and local variables.
    • PC Register: Holds the address of the current execution instruction.
    • Native Method Stack: Stores native method info.
  • Execution Engine:
    • Interpreter: Executes bytecode line by line.
    • JIT Compiler: Converts bytecode to native machine code for speed.
    • Garbage Collector: Automatically deletes unused objects from the heap.

Classes and Objects in Java

In Java, classes and objects are the basic concepts of object-oriented programming.

A class can be understood as a blueprint or design. It defines what kind of data an object will have and what actions it can perform. For example, if we think about a Student, the class will contain details like name, roll number, and methods like display or study.

An object, on the other hand, is a real instance of a class. It represents an actual entity. So, if Student is a class, then a specific student like Rahul or Priya will be an object. Each object has its own values but follows the structure defined by the class.

Syntax:

class ClassName {
    int age;
    String name;
    void display() {
        System.out.println(name + " " + age);
    }
}
ClassName obj = new ClassName();

Constructors and Object Initialization

In Java, when we create an object, it needs to be properly set up with initial values. This process is called object initialization, and it is mainly done using constructors.

A constructor is a special type of method used to initialize an object. It has the same name as the class and is automatically called when an object is created. Unlike normal methods, constructors do not have a return type.

For example: If we create a class called Student, we can use a constructor to assign values like name and roll number at the time of object creation. This makes the program cleaner and avoids writing extra code later.

There are different types of constructors in Java:

  • Default constructor: Takes no arguments and assigns default values.
  • Parameterized constructor: Takes values as parameters to initialize the object.

Object initialization can also be done in other ways, like assigning values directly or using methods, but using constructors is the most efficient and commonly used approach.

Access Modifiers in Java

In Java, access modifiers are used to control the visibility of classes, variables, methods, and constructors. They decide who can use or access a particular part of the program.

  1. Public: When a member is declared as public, it can be accessed from anywhere in the program, even from different packages. It has the maximum accessibility.
  2. Private: A private member can be accessed only within the same class. It cannot be accessed from outside the class, which helps in keeping data safe.
  3. Protected: A protected member can be accessed within the same package and also by subclasses (even if they are in different packages).
  4. Default (No Modifier): If no access modifier is specified, it is called default. It can be accessed only within the same package.

Simple Understanding:

  • Public: Accessible everywhere
  • Private: Accessible only within the class
  • Protected: Accessible in same package + subclass
  • Default: Accessible only in same package

Packages and Package Creation

In Java, a package is a way to organize classes and interfaces into groups. Just like we keep files in folders, Java uses packages to keep related classes together. Packages help in making programs more organized, easy to manage, and avoid name conflicts. They also provide better security and access control.

For example: Java already provides built-in packages like java.util, java.lang, etc., which contain useful classes.

Types of Packages:

  1. Built-in Packages: These are already provided by Java, such as java.util and java.io.
  2. User-defined Packages: These are created by the programmer according to the needs of the program.

How to Create a Package: We can create a package using the package keyword. It should be written at the top of the program.

package mypack;
class Test {
    public static void main(String[] args) {
        System.out.println("This is my package");
    }
}

Interfaces and Abstract Classes

In Java, both interface and abstract class are used to achieve abstraction, which means hiding implementation details and showing only important features.

An abstract class is a class that cannot be instantiated (we cannot create its object directly). It can contain both abstract methods (without a body) and normal methods (with a body). It is used when we want to provide some common functionality to different classes.

On the other hand, an interface is like a completely abstract blueprint. It contains only method declarations (by default) and no implementation. A class that implements an interface must provide the definition of all its methods.

Key Differences:

  • An abstract class can have both complete and incomplete methods.
  • An interface mostly has only incomplete methods.
  • A class can extend only one abstract class, but it can implement multiple interfaces.
  • Abstract classes are used when classes are closely related, while interfaces are used when different classes share common behavior.

Example Idea:

  • Abstract class: Can define common things like speed, fuel, etc.
  • Interface: Can define actions like start() and stop() which every vehicle must implement.

Inheritance in Java

Inheritance in Java is a concept where one class acquires the properties and behaviors of another class. It helps in reusing code and makes the program more organized.

In simple words, inheritance means creating a new class from an existing class. The existing class is called the parent (or superclass), and the new class is called the child (or subclass). The child class can use the variables and methods of the parent class and can also add its own features.

Example Idea:

  • Parent class: Animal
  • Child class: Dog

Here, the Dog can use properties of Animal like eating and breathing, and also have its own behavior like barking.

Types of Inheritance in Java:

  • Single Inheritance: One class inherits from one class.
  • Multilevel Inheritance: A class inherits from another class, which itself inherits from another.
  • Hierarchical Inheritance: Multiple classes inherit from one parent.

Note: Java does not support multiple inheritance using classes, but it can be achieved using interfaces.

Polymorphism and Its Types

Polymorphism in Java means “one thing, many forms.” It allows a single method or object to behave in different ways depending on the situation.

Example: A person can behave differently as a student in class or as a friend with others. Similarly, in Java, one method can act differently in different cases.

Types of Polymorphism in Java:

  1. Compile-Time Polymorphism (Method Overloading): This is achieved when multiple methods have the same name but different parameters. The method call is decided at compile time.
  2. Runtime Polymorphism (Method Overriding): This occurs when a child class provides a different implementation of a method already defined in the parent class. The method call is decided at runtime.

Method Overloading vs. Method Overriding

1. Method Overloading: Defining multiple methods with the same name but different parameters in the same class. Also called: Compile-time polymorphism / Static binding.

Rules for Overloading:

  • Number of parameters must be different, OR
  • Type of parameters must be different, OR
  • Order of parameters must be different.
  • Return type alone cannot be used for overloading.

2. Method Overriding: If a subclass defines a method with the same name, same parameters, and same return type as a parent class method, it is overriding. Also called: Run-time polymorphism / Dynamic binding / Late binding.

Rules for Overriding:

  • Method name, parameter list, and return type must be the same.
  • Access modifier cannot be more restrictive (e.g., public to protected is not allowed).
  • Final and static methods cannot be overridden.
  • The super keyword is used to call the parent class method.
FeatureMethod OverloadingMethod Overriding
DefinitionSame method name, different parametersSame method name, same parameters
ClassSame classDifferent classes (parent-child)
Polymorphism TypeCompile-timeRuntime
Inheritance RequiredNoYes
Exampleadd(int, int) & add(int, int, int)Parent sound() → Child sound()

The ‘this’ Keyword in Java

In Java, this is a reference variable that refers to the current object (the object that is calling the method or constructor).

Uses of this Keyword:

  1. To refer to current class instance variables: When local variables and instance variables have the same name, this is used to avoid confusion.
    class Student {
        int id;
        Student(int id) {
            this.id = id; // this.id refers to instance variable
        }
    }
  2. To call current class method: You can call one method from another using this.
    class Demo {
        void show() {
            System.out.println("Hello");
        }
        void display() {
            this.show(); // calling method
        }
    }
  3. To call current class constructor: this() is used to call another constructor of the same class.
    class Demo {
        Demo() {
            this(10); // calls parameterized constructor
            System.out.println("Default constructor");
        }
        Demo(int x) {
            System.out.println("Value: " + x);
        }
    }

The ‘super’ Keyword in Java

Definition: super is a reference variable in Java that refers to the immediate parent class object. It is used to access parent class members from a child class.

Main Uses of super Keyword:

(1) To refer to immediate parent class instance variable. Used when child and