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
- 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.
- Object-Oriented: Java follows Object-Oriented Programming (OOP) concepts such as:
- Class and Object
- Inheritance
- Polymorphism
- Encapsulation
- Abstraction
- 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.
- Secure: Java provides strong security features:
- No use of pointers
- Bytecode verification
- Security manager
- Robust: Java is strong and reliable because:
- It uses automatic memory management (Garbage Collection).
- It has strong error handling (Exception Handling).
- Multithreaded: Java supports multithreading, allowing multiple tasks to run simultaneously, improving performance.
- 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
- Distributed: Java is designed for network-based applications and supports distributed computing using APIs like RMI (Remote Method Invocation).
- Dynamic: Java can adapt to changing environments. It supports:
- Dynamic memory allocation
- Runtime class loading
- Portable: Java programs can be easily transferred from one system to another due to platform independence.
Java vs. C++: Key Differences
| Feature | C++ | Java |
|---|---|---|
| Nature | Procedural + Object-oriented | Pure object-oriented language |
| Platform Dependency | Platform dependent | Platform independent (WORA) |
| Pointers | Supports pointers | Does not support pointers (More secure) |
| Memory Management | Manual (new/delete) | Automatic garbage collection |
| Multiple Inheritance | Supported through classes | Supported only through interfaces |
| Compilation & Execution | Source → Compiler → Machine code (.exe) | Source → Compiler → Bytecode (.class) → JVM |
| Operator Overloading | Supported | Not supported |
| Speed | Faster (Direct machine code) | Slower (Bytecode interpretation) |
| Structure vs. Class | Supports both struct and class | Only 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.
- 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.
- 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.
- Protected: A protected member can be accessed within the same package and also by subclasses (even if they are in different packages).
- 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:
- Built-in Packages: These are already provided by Java, such as java.util and java.io.
- 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:
- 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.
- 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
superkeyword is used to call the parent class method.
| Feature | Method Overloading | Method Overriding |
|---|---|---|
| Definition | Same method name, different parameters | Same method name, same parameters |
| Class | Same class | Different classes (parent-child) |
| Polymorphism Type | Compile-time | Runtime |
| Inheritance Required | No | Yes |
| Example | add(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:
- To refer to current class instance variables: When local variables and instance variables have the same name,
thisis used to avoid confusion.class Student { int id; Student(int id) { this.id = id; // this.id refers to instance variable } } - 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 } } - 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
