Java Programming Concepts: Constructors, Strings, Inheritance, and Features
Java Program to Demonstrate Parameterized Constructor
A parameterized constructor is used to initialize an object with user-defined values.
class Employee {
String name;
int id;
// Parameterized constructor
Employee(String empName, int empId) {
name = empName;
id = empId;
}
void display() {
System.out.println("Employee Name: " + name);
System.out.println("Employee ID: " + id);
}
public static void main(String[] args) {
Employee e1 = new Employee("John", 101);
e1.display();
}
}
Explain Any 6 String Functions with Suitable Code Snippets
length()
– Returns the length of the string.String s = "Java"; System.out.println(s.length()); // Output: 4
charAt(int index)
– Returns character at the given index.String s = "Java"; System.out.println(s.charAt(2)); // Output: v
substring(int start)
– Returns substring from index.String s = "Java"; System.out.println(s.substring(1)); // Output: ava
equals(String another)
– Compares two strings.String s = "Java"; System.out.println(s.equals("Java")); // Output: true
toUpperCase()
– Converts string to uppercase.String s = "Java"; System.out.println(s.toUpperCase()); // Output: JAVA
replace(char oldChar, char newChar)
– Replaces characters.String s = "Java"; System.out.println(s.replace('a', 'x')); // Output: Jxvx
What is Inheritance? Types in Java
Inheritance is a mechanism in Java where one class (child class) inherits the fields and methods of another class (parent class). It promotes code reusability.
Types of Inheritance in Java:
- Single Inheritance: One class inherits from another.
- Multilevel Inheritance: A class inherits from a class, which itself inherits from another class.
- Hierarchical Inheritance: Multiple classes inherit from a single parent class.
- Multiple Inheritance (via Interface): A class implements multiple interfaces.
Note: Java doesn’t support multiple inheritance through classes to avoid ambiguity.
Features of Java
- Simple
- Object-Oriented
- Platform Independent
- Secure
- Robust
- Multithreaded
- Portable
- High Performance
- Distributed
- Dynamic
Explanation of Any 3 Features
Platform Independent:
Java programs are compiled into bytecode, which can run on any machine using the Java Virtual Machine (JVM). This makes Java a “write once, run anywhere” language.Object-Oriented:
Java follows object-oriented programming concepts such as inheritance, encapsulation, abstraction, and polymorphism. This makes it modular, reusable, and easier to maintain.Secure:
Java provides a secure environment by eliminating the use of pointers, using a bytecode verifier, and having a security manager that defines access rules for classes.
Difference Between Abstract Class and Interface in Java
Example:
abstract class Animal {
abstract void sound();
void eat() {
System.out.println("Animals eat food.");
}
}
interface Bird {
void fly();
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
class Sparrow implements Bird {
public void fly() {
System.out.println("Sparrow flies");
}
}
Usage of super
Keyword in Java
The super
keyword is used to refer to the immediate parent class. It is used in three main ways:
To call the parent class constructor:
super(); // Calls default constructor of parent super(args); // Calls parameterized constructor
To access parent class methods:
super.methodName();
To access parent class fields:
super.fieldName;
Example:
class Animal {
void display() {
System.out.println("This is an animal.");
}
}
class Dog extends Animal {
void display() {
super.display(); // Calls Animal's method
System.out.println("This is a dog.");
}
}
Java Program with Overloaded Constructors and super
// Base class Shape
class Shape {
double length, breadth, height;
// Constructor for 2D shape
Shape(double l, double b) {
length = l;
breadth = b;
height = 0; // default for 2D
}
// Constructor for 3D shape
Shape(double l, double b, double h) {
length = l;
breadth = b;
height = h;
}
void calculate() {
System.out.println("Calculating in Shape class.");
}
}
// Derived class Test
class Test extends Shape {
// Constructor for 2D shape
Test(double l, double b) {
super(l, b); // calls Shape(double, double)
}
// Constructor for 3D shape
Test(double l, double b, double h) {
super(l, b, h); // calls Shape(double, double, double)
}
// Override method to calculate volume
@Override
void calculate() {
double volume = length * breadth * height;
System.out.println("Volume of the shape: " + volume);
}
}
// Main class
public class Main {
public static void main(String[] args) {
Test obj1 = new Test(2, 3); // 2D shape
obj1.calculate(); // Volume: 0.0
Test obj2 = new Test(2, 3, 4); // 3D shape
obj2.calculate(); // Volume: 24.0
}
}
Java Program to Represent an Account
class Account {
String name;
int accNumber;
String accType;
double balance;
// Constructor to assign initial values
Account(String n, int num, String type, double bal) {
name = n;
accNumber = num;
accType = type;
balance = bal;
}
// Method to deposit amount after checking minimum balance
void deposit(double amount) {
if (balance < 1000) {
System.out.println("Minimum balance of Rs.1000 required to deposit.");
} else {
balance += amount;
System.out.println("Amount deposited successfully.");
}
}
// Method to display name and balance
void display() {
System.out.println("Depositor Name: " + name);
System.out.println("Current Balance: Rs." + balance);
}
public static void main(String[] args) {
Account a1 = new Account("Ravi Kumar", 123456, "Savings", 1500);
a1.deposit(500);
a1.display();
Account a2 = new Account("Sita Sharma", 987654, "Current", 800);
a2.deposit(300); // Should not allow
a2.display();
}
}
Type Casting in Java
Type casting is the process of converting one data type into another. Java supports two types of casting:
i. Implicit (Widening) Casting
- Done automatically
- Converts a smaller type to a larger type
- No data loss
Example:
int a = 10;
double b = a; // Implicit casting
System.out.println(b); // Output: 10.0
ii. Explicit (Narrowing) Casting
- Must be done manually
- Converts a larger type to a smaller type
- May lead to data loss
Example:
double x = 10.75;
int y = (int) x; // Explicit casting
System.out.println(y); // Output: 10
Wrapper Classes in Java
Wrapper classes in Java are used to convert primitive data types into objects. This is especially useful when working with collections (like ArrayList
, HashMap
) which can only store objects, not primitive types.
For each primitive data type in Java, there is a corresponding wrapper class:
int
→Integer
char
→Character
double
→Double
boolean
→Boolean
float
→Float
byte
→Byte
short
→Short
long
→Long
Wrapper classes also provide many utility methods for type conversion, parsing, and comparison.
Example:
int num = 10;
// Manual Boxing (Converting int to Integer object)
Integer obj = Integer.valueOf(num);
// Manual Unboxing (Converting Integer object to int)
int value = obj.intValue();
// Auto Boxing and Auto Unboxing (Java automatically handles it)
Integer autoObj = num; // Auto boxing
int autoVal = autoObj; // Auto unboxing
System.out.println(autoVal); // Output: 10
Wrapper classes are also useful when you want to:
- Use primitive types in generic classes like
ArrayList<Integer>
- Convert between strings and numbers
- Allow null assignment to primitive-like types
JVM Architecture
The Java Virtual Machine (JVM) is an engine that provides a runtime environment to execute Java bytecode. It is platform-independent and converts bytecode into machine-specific code.
Main Components of JVM:
- Class Loader: Loads
.class
files into JVM memory. - Method Area: Stores class-level information like methods, static variables, and constants.
- Heap: Stores all objects and their instance variables.
- Stack: Stores method calls and local variables for each thread.
- Program Counter (PC) Register: Keeps track of the address of the JVM instruction currently being executed.
- Native Method Stack: Holds native methods used in the application.
- Execution Engine: Executes bytecode using:
- Interpreter (line-by-line)
- Just-In-Time (JIT) Compiler (compiles hotspots to native code)
- Native Interface & Libraries: Enables communication with native libraries written in C/C++.
Diagram of JVM Architecture:
┌────────────────────────────┐
│ Class Loader │
└────────────┬───────────────┘
↓
┌────────────────────────────┐
│ Method Area │◄────────┐
└────────────────────────────┘ │
┌────────────────────────────┐ │
│ Heap │ │
└────────────────────────────┘ │
┌────────┐ ┌────────┐ ┌────────┐ │
│ Stack │ │ Stack │ │ Stack │ │
└────────┘ └────────┘ └────────┘│
┌────────────────────────────┐ │
│ Native Method Stack │ │
└────────────────────────────┘ │
┌────────────────────────────┐ │
│ PC Register │ │
└────────────────────────────┘ │
┌────────────────────────────┐ │
│ Execution Engine │◄─────────┘
└────────────────────────────┘
┌────────────────────────────┐
│ Native Interface & Libs │
└────────────────────────────┘
Access Control Modifiers in Java
Java provides four access control levels to set visibility of classes, methods, and variables:
- Private – Accessible only within the same class.
- Default (no modifier) – Accessible within the same package.
- Protected – Accessible within the same package and by subclasses.
- Public – Accessible from anywhere in the program.
Example:
public class Test {
private int a; // accessible only in Test
int b; // default access
protected int c; // accessible in subclasses
public int d; // accessible everywhere
}
Multiple Catch Blocks in Java
Java allows multiple catch blocks to handle different exceptions separately. Each block is checked in order, and only the first matching one executes.
Example:
public class MultipleCatchExample {
public static void main(String[] args) {
try {
int[] arr = new int[3];
arr[5] = 100; // ArrayIndexOutOfBoundsException
int a = 5 / 0; // ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception caught: " + e);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array Index Exception caught: " + e);
} catch (Exception e) {
System.out.println("General Exception caught: " + e);
}
}
}
Note: The most specific exceptions should come first, followed by more general ones like Exception
.
Exception Hierarchy in Java
In Java, all exceptions are derived from the Throwable
class, which has two main subclasses:
Exception
– For recoverable conditions (e.g.,IOException
,SQLException
)Error
– For serious errors that applications usually do not handle (e.g.,OutOfMemoryError
)
The Exception
class is further divided into:
- Checked Exceptions – Must be handled using try-catch or declared with
throws
. (e.g.,IOException
) - Unchecked Exceptions – Runtime exceptions; not required to be caught. (e.g.,
ArithmeticException
,NullPointerException
)
Hierarchy:
Object
└── Throwable
├── Exception
│ ├── IOException
│ ├── SQLException
│ └── RuntimeException
│ ├── ArithmeticException
│ └── NullPointerException
└── Error
├── OutOfMemoryError
└── StackOverflowError
DataInputStream and DataOutputStream with Example
DataInputStream
: Allows you to read Java primitive data types (int, float, etc.) from an input stream in a machine-independent way.DataOutputStream
: Allows you to write Java primitive data types to an output stream.
Example:
import java.io.*;
public class DataStreamExample {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("data.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(100);
dos.writeDouble(99.99);
dos.close();
FileInputStream fis = new FileInputStream("data.txt");
DataInputStream dis = new DataInputStream(fis);
int i = dis.readInt();
double d = dis.readDouble();
dis.close();
System.out.println("Int: " + i + ", Double: " + d);
}
}
What is an ArrayList? Explain with Example and Methods
ArrayList is a class in Java that implements the List interface and provides a resizable array. Unlike arrays, the size of an ArrayList
can grow or shrink dynamically.
Example:
import java.util.*;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<String> list= new ArrayList<>();
// add()
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// get()
System.out.println("Element at index 1: " + list.get(1)); // Banana
// set()
list.set(1, "Blueberry");
// size()
System.out.println("Size: " + list.size());
// remove()
list.remove("Apple");
// contains()
System.out.println("Contains Cherry? " + list.contains("Cherry"));
// isEmpty()
System.out.println("Is list empty? " + list.isEmpty());
// for-each loop
for (String fruit : list) {
System.out.println(fruit);
}
}
}
Common Methods:
add(element)
,add(index, element)
remove(index or element)
get(index)
set(index, element)
size()
clear()
isEmpty()
contains(element)
Java Program with Three Threads and Different Sleep Intervals
class ThreadOne extends Thread {
public void run() {
try {
while (true) {
System.out.println("Thread-I");
Thread.sleep(2500);
}
} catch (InterruptedException e) {
System.out.println("Thread-I Interrupted");
}
}
}
class ThreadTwo extends Thread {
public void run() {
try {
while (true) {
System.out.println("Thread-II");
Thread.sleep(5000);
}
} catch (InterruptedException e) {
System.out.println("Thread-II Interrupted");
}
}
}
class ThreadThree extends Thread {
public void run() {
try {
while (true) {
System.out.println("Thread-III");
Thread.sleep(7500);
}
} catch (InterruptedException e) {
System.out.println("Thread-III Interrupted");
}
}
}
public class MultiThreadExample {
public static void main(String[] args) {
new ThreadOne().start();
new ThreadTwo().start();
new ThreadThree().start();
}
}
Java Program Demonstrating Multiple Inheritance using Interface
interface A {
void methodA();
}
interface B {
void methodB();
}
// Class implements both interfaces (Multiple Inheritance)
class C implements A, B {
public void methodA() {
System.out.println("Method from Interface A");
}
public void methodB() {
System.out.println("Method from Interface B");
}
}
public class MultipleInheritanceDemo {
public static void main(String[] args) {
C obj = new C();
obj.methodA();
obj.methodB();
}
}
Method Overriding in Different Packages
File: package1/Base.java
package package1;
public class Base {
public void display() {
System.out.println("Display method in Base class (package1)");
}
}
File: package2/Derived.java
package package2;
import package1.Base;
public class Derived extends Base {
@Override
public void display() {
System.out.println("Display method in Derived class (package2)");
}
}
File: MainApp.java
import package2.Derived;
public class MainApp {
public static void main(String[] args) {
Derived obj = new Derived();
obj.display(); // Method in Derived overrides Base
}
}
Ensure your folder structure matches the package names (e.g.,
package1/Base.java
andpackage2/Derived.java
).
Primitive Data Types: Size and Default Values
1. boolean
- Size: 1 bit (though the exact size is JVM-dependent, generally treated as 1 byte)
- Default value:
false
2. char
- Size: 2 bytes (16 bits)
- Default value:
'\u0000'
(null character)
3. short
- Size: 2 bytes (16 bits)
- Default value:
0
4. double
- Size: 8 bytes (64 bits)
- Default value:
0.0d