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: 4charAt(int index)– Returns character at the given index.String s = "Java"; System.out.println(s.charAt(2)); // Output: vsubstring(int start)– Returns substring from index.String s = "Java"; System.out.println(s.substring(1)); // Output: avaequals(String another)– Compares two strings.String s = "Java"; System.out.println(s.equals("Java")); // Output: truetoUpperCase()– Converts string to uppercase.String s = "Java"; System.out.println(s.toUpperCase()); // Output: JAVAreplace(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 constructorTo 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→Integerchar→Characterdouble→Doubleboolean→Booleanfloat→Floatbyte→Byteshort→Shortlong→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
.classfiles 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.javaandpackage2/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
