0% found this document useful (0 votes)
31 views46 pages

Java Notes

Java is a high-level, object-oriented programming language known for its portability, robustness, and security, developed by Sun Microsystems in 1995. It features platform independence through the JVM, strong type-checking, automatic memory management, and supports multithreading and dynamic class loading. The document also covers the Java compilation and execution process, JVM organization, security architecture, data types, and arrays.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views46 pages

Java Notes

Java is a high-level, object-oriented programming language known for its portability, robustness, and security, developed by Sun Microsystems in 1995. It features platform independence through the JVM, strong type-checking, automatic memory management, and supports multithreading and dynamic class loading. The document also covers the Java compilation and execution process, JVM organization, security architecture, data types, and arrays.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

1.

Overview and Characteristics of Java


Java is a high-level, object-oriented programming language designed for portability, robustness, and security.
Developed by Sun Microsystems (now Oracle) in 1995, it’s widely used for web, mobile, enterprise, and embedded
applications.

Key Characteristics

●​ Platform Independence: Java programs run on any device with a JVM, thanks to the "write once, run
anywhere" (WORA) principle. Code is compiled to bytecode, which the JVM interprets or compiles to
machine code.
●​ Object-Oriented: Everything in Java is an object (except primitives). Supports encapsulation, inheritance,
polymorphism, and abstraction.
●​ Robust: Strong type-checking, exception handling, and automatic memory management (garbage collection)
prevent common errors like memory leaks or pointer issues.
●​ Secure: The JVM’s sandbox model, class loader, and bytecode verification ensure safe execution, even for
untrusted code.
●​ Multithreaded: Built-in support for concurrent programming via threads.
●​ Simple: No pointers, operator overloading, or manual memory management, making it easier to learn than
C++.
●​ High Performance: Just-In-Time (JIT) compilation converts bytecode to native code at runtime, boosting
performance.
●​ Distributed: Supports networking and distributed systems (e.g., RMI, JDBC).
●​ Dynamic: Classes can be loaded at runtime, enabling flexibility (e.g., applets, plugins).

Example: A Java program to print "Hello, World!" runs identically on Windows, Linux, or macOS because the JVM
translates bytecode to the platform’s native instructions.

public class HelloWorld {


public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

Exam Tip: Memorize key characteristics (e.g., platform independence, security, multithreading) and be ready to
explain WORA with an example.

2. Java Program Compilation and Execution Process


Java’s compilation and execution process ensures portability and performance.

Compilation

1.​ Source Code: Write code in a .java file (e.g., HelloWorld.java).


2.​ Compiler (javac): The Java compiler (javac) translates the .java file into bytecode, stored in a .class file
(e.g., HelloWorld.class). Bytecode is platform-independent.
○​ Syntax errors are caught here (e.g., missing semicolon).
Execution

1.​ JVM Loading: The JVM loads the .class file.


2.​ Bytecode Verification: The JVM verifies bytecode for safety (e.g., no invalid operations).
3.​ Interpretation/Compilation:
○​ Interpreter: Executes bytecode line-by-line (slower).
○​ Just-In-Time (JIT) Compiler: Converts bytecode to native machine code for faster execution.
4.​ Runtime: The JVM manages memory, threads, and system resources, interacting with the OS.

Example:

●​ Write HelloWorld.java.
●​ Compile: javac HelloWorld.java → produces HelloWorld.class.
●​ Run: java HelloWorld → JVM loads, verifies, and executes, printing "Hello, World!".

Diagram:

Source Code (.java) → [javac] → Bytecode (.class) → [JVM: Verify, Interpret/JIT Compile] →
Native Code → Execution

Exam Tip: Be ready to explain the role of javac vs. JVM and how JIT compilation improves performance. Practice
drawing the compilation-execution flow.

3. Organization of the Java Virtual Machine


The JVM is a virtual machine that runs Java bytecode, acting as an intermediary between the bytecode and the host
OS. It provides portability, security, and memory management.

JVM Components

●​ Class Loader: Loads, links, and initializes .class files.


●​ Runtime Data Areas: Memory areas used during execution:
○​ Method Area: Stores class structures (code, metadata).
○​ Heap: Stores objects and arrays (shared across threads).
○​ Java Stack: Stores method call frames (local variables, operands).
○​ Program Counter (PC) Register: Tracks the current instruction for each thread.
○​ Native Method Stack: Supports native methods (e.g., C/C++ code).
●​ Execution Engine:
○​ Interpreter: Executes bytecode directly.
○​ JIT Compiler: Converts bytecode to native code.
○​ Garbage Collector: Reclaims unused memory.
●​ Native Interface: Connects Java to native libraries (JNI).

Example: When running HelloWorld, the class loader loads HelloWorld.class, the method area stores its code, the
heap stores the String object for "Hello, World!", and the Java stack tracks the main method’s execution.

Exam Tip: Understand the role of each JVM component. Be ready to describe how memory areas interact during
program execution.
4. JVM as an Interpreter and Emulator
●​ Interpreter: The JVM interprets bytecode by translating each instruction to native code at runtime. This is
slower but ensures portability.
○​ Example: The instruction iload_1 (load integer from variable 1) is interpreted for the specific CPU.
●​ Emulator: The JVM emulates a standardized machine, executing bytecode consistently across platforms. It
abstracts hardware differences (e.g., CPU, OS).
○​ Example: A Java program runs identically on x86 (Windows) and ARM (Linux) because the JVM
emulates the same instruction set.

Key Advantage: Interpretation allows immediate execution, while JIT compilation (emulation + optimization) boosts
performance.

Exam Tip: Explain the trade-offs of interpretation (portability, slower) vs. JIT compilation (faster, platform-specific).
Be ready to define emulation in the JVM context.

5. Instruction Set
The JVM uses a stack-based instruction set, where operations manipulate a stack of operands. Instructions
(opcodes) are compact, typically 1 byte, ensuring portability.

●​ Types of Instructions:
○​ Load/Store: Move data between stack and local variables (e.g., iload_1, istore_2).
○​ Arithmetic: Perform operations (e.g., iadd for integer addition).
○​ Control: Manage flow (e.g., if_icmpeq for conditional branching).
○​ Object Operations: Create objects, access fields (e.g., new, getfield).
○​ Method Invocation: Call methods (e.g., invokevirtual).

Example: Bytecode for int c = a + b;:

iload_1 // Push a to stack


iload_2 // Push b to stack
iadd // Pop a, b, push a + b
istore_3 // Store result in c

Exam Tip: Understand stack-based execution and common opcodes. Practice translating simple Java code to
bytecode (e.g., arithmetic or method calls).

6. Class File Format, Verification, Class Area, Java Stack, Heap,


Garbage Collection
Class File Format

A .class file contains bytecode and metadata in a platform-independent format.

●​ Structure:
○​ Magic Number: 0xCAFEBABE (identifies class file).
○​ Version: Compiler and JVM version.
○​ Constant Pool: Literals, class names, method references.
○​ Access Flags: Public, final, etc.
○​ Fields and Methods: Definitions and bytecode.
●​ Example: HelloWorld.class stores the main method’s bytecode and the string "Hello, World!" in the constant
pool.

Verification

The bytecode verifier checks .class files for safety before execution:

●​ Ensures valid opcodes, stack consistency, and type safety.


●​ Prevents issues like stack overflow, illegal casts, or accessing uninitialized objects.
●​ Example: Verifier rejects bytecode trying to pop an empty stack.

Class Area (Method Area)

●​ Stores per-class data: bytecode, constant pool, method tables, and static variables.
●​ Shared across threads but thread-safe for access.
●​ Example: The System.out object’s metadata resides here.

Java Stack

●​ Stores method call frames, each containing:


○​ Local variables (e.g., method parameters).
○​ Operand stack (for computations).
○​ Frame data (e.g., return address).
●​ Each thread has its own stack.
●​ Example: In main, a frame stores args and the operand stack for System.out.println.

Heap

●​ Stores all objects and arrays, shared across threads.


●​ Divided into:
○​ Young Generation: New objects (Eden, Survivor spaces).
○​ Old Generation: Long-lived objects.
○​ Permanent Generation/Metaspace (pre-Java 8/8+): Class metadata.
●​ Example: The String object "Hello, World!" is allocated in the heap.

Garbage Collection (GC)

●​ Automatically reclaims memory from objects no longer referenced.


●​ Process:
○​ Mark: Identify reachable objects (from roots like stack, static variables).
○​ Sweep: Reclaim unreachable objects.
○​ Compact (optional): Defragment memory.
●​ Algorithms:
○​ Generational GC: Separates young and old objects for efficiency.
○​ Stop-the-World: Pauses execution during GC.
○​ Concurrent GC: Minimizes pauses.
●​ Example: If a String object is no longer referenced, GC reclaims its memory.
Practice Problem: Trace the memory allocation for:

String s = new String("Hello");


s = null;

●​ new String("Hello") allocates a String object in the heap.


●​ s = null makes the object unreachable, eligible for GC.

Exam Tip: Understand the class file structure, verification process, and memory areas. Be ready to explain GC steps
and why the heap is shared but the stack is thread-specific.

7. Security Promises of the JVM


The JVM ensures a secure execution environment, especially for untrusted code (e.g., applets).

●​ Key Promises:
○​ Type Safety: Prevents illegal operations (e.g., casting String to int).
○​ Memory Safety: No direct memory access (no pointers).
○​ Sandboxing: Restricts untrusted code to a controlled environment.
○​ Verification: Ensures bytecode is safe before execution.
○​ Access Control: Enforces permissions via security policies.

Example: An applet cannot access the local file system unless explicitly permitted, thanks to the JVM’s sandbox.

Exam Tip: List JVM security features and explain how they protect against malicious code.

8. Security Architecture and Security Policy


Security Architecture

●​ Bytecode Verifier: Checks bytecode for illegal operations.


●​ Class Loader: Enforces namespace separation and loading policies.
●​ Security Manager: Enforces runtime permissions (e.g., file access, network connections).
●​ Access Controller: Checks permissions based on the security policy.
●​ Cryptographic Services: Supports encryption, digital signatures.

Example: A Java program trying to read a file triggers the Security Manager, which checks the policy file for
permission.

Security Policy

●​ A configuration file (java.policy) defines permissions for code based on its source, signer, or class.
●​ Permissions: File read/write, network access, etc.

Example Policy:​

grant codeBase "file:/trusted/" {
permission java.io.FilePermission "/data/*", "read,write";
};​
Grants file access to code from the trusted directory.

Exam Tip: Understand the roles of the Security Manager and policy file. Be ready to write a simple policy or explain
permission checks.

9. Class Loaders and Security Aspects, Sandbox Model


Class Loaders

●​ Load, link, and initialize .class files.


●​ Types:
○​ Bootstrap Class Loader: Loads core Java classes (e.g., java.lang.*).
○​ Extension Class Loader: Loads extension classes (e.g., javax.*).
○​ Application Class Loader: Loads user-defined classes.
●​ Security Role:
○​ Namespace separation prevents malicious code from overriding trusted classes.
○​ Delegation model: Child loaders delegate to parent (Bootstrap → Extension → Application).
●​ Example: A malicious class cannot redefine java.lang.String because the Bootstrap loader has priority.

Sandbox Model

●​ Restricts untrusted code (e.g., applets) to a controlled environment.


●​ Mechanisms:
○​ Limited permissions (e.g., no file access).
○​ Security Manager enforces restrictions.
○​ Bytecode verification prevents illegal operations.
●​ Example: An applet can draw on the screen but cannot write to the user’s disk.

Practice Problem: Explain how the class loader delegation model prevents a malicious class from impersonating
java.lang.System.

Exam Tip: Understand the delegation model and sandbox restrictions. Be ready to explain how class loaders
enhance security.

Exam-Focused Tips
●​ Common Questions:
○​ Explain WORA and the JVM’s role in portability.
○​ Describe the compilation-execution process with a diagram.
○​ List JVM memory areas and their purposes.
○​ Translate Java code to bytecode.
○​ Explain GC or security mechanisms (e.g., sandbox, class loaders).
●​ Key Examples to Master:
○​ Compilation-execution flow for a program.
○​ Bytecode for arithmetic or method calls.
○​ GC process for a program with objects.
○​ Security policy for file access.
1. Java Fundamentals: Data Types & Literals, Variables
Data Types

Java is a strongly typed language, meaning every variable has a specific type. Data types are divided into
primitive and reference types.

●​ Primitive Types (8 types, stored directly in memory):


○​ byte: 8-bit integer (-128 to 127). Example: byte b = 100;
○​ short: 16-bit integer (-32,768 to 32,767). Example: short s = 1000;
○​ int: 32-bit integer (-2^31 to 2^31-1). Example: int i = 100000;
○​ long: 64-bit integer (-2^63 to 2^63-1). Example: long l = 100000L;
○​ float: 32-bit floating-point (IEEE 754). Example: float f = 3.14f;
○​ double: 64-bit floating-point. Example: double d = 3.14159;
○​ char: 16-bit Unicode character. Example: char c = 'A';
○​ boolean: true or false. Example: boolean flag = true;
●​ Reference Types: Objects (e.g., String, arrays, user-defined classes) stored as references to heap memory.
Example: String name = "Alice";

Literals

Literals are fixed values in code:

●​ Integer: 123, 0x7B (hex), 0173 (octal), 123L (long).


●​ Floating-Point: 3.14, 3.14f (float), 3.14e-2 (scientific).
●​ Character: 'A', '\u0041' (Unicode).
●​ String: "Hello".
●​ Boolean: true, false.
●​ Null: null (for reference types).

Variables

●​ Declaration: Specify type and name (e.g., int age;).


●​ Initialization: Assign a value (e.g., age = 25;).
●​ Scope: Variables are local (method), instance (class), or static (class-wide).

Example:​

int age = 25; // Local variable

String name = "Bob"; // Reference type

static double PI = 3.14159; // Static variable​

Practice Problem: Declare variables for a student’s ID (int), name (String), and GPA (double), and initialize them.

Exam Tip: Memorize primitive type ranges and literal formats. Be ready to spot invalid literals (e.g., int x = 3.14; //
Error).
2. Wrapper Classes
Wrapper classes provide object representations for primitive types, enabling their use in collections (e.g., ArrayList)
and methods requiring objects.

●​ Wrapper Classes:
○​ Byte, Short, Integer, Long, Float, Double, Character, Boolean.
●​ Autoboxing: Automatic conversion from primitive to wrapper (e.g., Integer i = 5; converts int to Integer).
●​ Unboxing: Wrapper to primitive (e.g., int j = i;).
●​ Methods: Provide utilities (e.g., Integer.parseInt("123") converts String to int).

Example:

Integer num = 10; // Autoboxing

int value = num; // Unboxing

String str = "42";

int parsed = Integer.parseInt(str); // Converts to 42

Practice Problem: Write code to convert a String "3.14" to a double using a wrapper class.

Exam Tip: Understand autoboxing/unboxing and common wrapper methods (e.g., valueOf, parseXxx). Expect
questions like “What is the output of Integer x = 5; x += 10;?”

3. Arrays
Arrays are fixed-size, ordered collections of elements of the same type.

●​ Declaration: int[] numbers; or int numbers[];.


●​ Initialization: numbers = new int[5]; or int[] numbers = {1, 2, 3, 4, 5};.
●​ Access: Use index (0-based). Example: numbers[0] = 1;.
●​ Multidimensional Arrays: int[][] matrix = new int[3][3];.

Example:

int[] scores = new int[3];

scores[0] = 90;

scores[1] = 85;

scores[2] = 88;

for (int i = 0; i < scores.length; i++) {

System.out.println(scores[i]);

Practice Problem: Create a 2x3 matrix and initialize it with values.


Exam Tip: Know array bounds (0 to length-1) and how to avoid ArrayIndexOutOfBoundsException. Practice iterating
over arrays.

4. Arithmetic Operators
Perform mathematical operations:

●​ + (addition), - (subtraction), * (multiplication), / (division), % (modulus).


●​ Increment/Decrement: ++, --.
●​ Compound Assignment: +=, -=, *=, /=, %=.

Example:

int a = 10, b = 3;

int sum = a + b; // 13

int div = a / b; // 3 (integer division)

int mod = a % b; // 1

a += 5; // a = 15

Exam Tip: Understand integer vs. floating-point division (e.g., 5 / 2 = 2, 5.0 / 2 = 2.5). Practice operator precedence.

5. Logical Operators
Evaluate boolean expressions:

●​ Relational: ==, !=, <, >, <=, >=.


●​ Logical: && (AND), || (OR), ! (NOT).
●​ Bitwise: &, |, ^ (XOR), ~ (complement), <<, >>, >>> (shifts).
●​ Conditional: ?: (ternary, e.g., max = a > b ? a : b;).
●​ Short-Circuit: && and || skip evaluation if the result is determined.

Example:

int x = 5, y = 10;

boolean result = (x < y) && (y > 0); // true

if (x > 0 || y < 0) {

System.out.println("At least one condition is true");

Practice Problem: Write code to check if a number is positive and even.


Exam Tip: Understand short-circuit evaluation (e.g., if (false && someMethod()), someMethod isn’t called). Practice
combining operators.

6. Control of Flow
Control flow directs program execution using conditionals and loops.

●​ Conditionals:
○​ if-else: if (condition) { ... } else { ... }.

switch: Matches a value to cases (supports int, String, enum in Java 7+).​

int day = 2;

switch (day) {

case 1: System.out.println("Monday"); break;

case 2: System.out.println("Tuesday"); break;

default: System.out.println("Invalid");

}​

●​ Loops:
○​ for: for (int i = 0; i < 5; i++) { ... }.
○​ while: while (condition) { ... }.
○​ do-while: do { ... } while (condition);.
○​ Enhanced for: for (int num : array) { ... }.
●​ Control Statements:
○​ break: Exits a loop or switch.
○​ continue: Skips to the next iteration.
○​ return: Exits a method.

Example:

for (int i = 1; i <= 10; i++) {

if (i % 2 == 0) {

continue; // Skip even numbers

System.out.println(i);

Practice Problem: Write a program to print the first 10 Fibonacci numbers using a loop.
Exam Tip: Practice nested loops and switch statements. Be ready to debug flow control errors (e.g., missing break in
switch).

7. Classes and Instances


Java is object-oriented, with classes defining blueprints and instances (objects) as realizations.

Class Declaration:​

public class Student {

String name; // Instance variable

int id;

void study() { // Method

System.out.println(name + " is studying.");

}​

Instance Creation: Use new.​



Student s1 = new Student();

s1.name = "Alice";

s1.id = 101;

s1.study(); // Alice is studying.​

Constructors: Initialize objects.​



public Student(String name, int id) {

this.name = name;

this.id = id;

}​

Practice Problem: Create a Car class with fields model and speed, a constructor, and a method accelerate.

Exam Tip: Understand the difference between class (blueprint) and object (instance). Practice constructor
overloading.
8. Class Member Modifiers
Modifiers control access and behavior of class members (fields, methods, constructors).

●​ Access Modifiers:
○​ public: Accessible everywhere.
○​ protected: Accessible in the same package or subclasses.
○​ default (package-private): Accessible in the same package (no modifier).
○​ private: Accessible only within the class.
●​ Non-Access Modifiers:
○​ static: Belongs to the class, not instances (e.g., static int count;).
○​ final: Cannot be modified (e.g., final double PI = 3.14;).
○​ abstract: Cannot be instantiated; used for abstract classes/methods.
○​ synchronized: Thread-safe method.
○​ transient: Excluded from serialization.
○​ volatile: Ensures visibility in multithreading.

Example:

public class Counter {

private static int count = 0; // Shared across instances

public final String NAME = "MyCounter"; // Constant

public static void increment() {

count++;

Exam Tip: Know the scope of each modifier. Expect questions like “What happens if a method is private?” or “Why
use static?”

9. Anonymous Inner Class


An anonymous inner class is a nameless class defined inline, often for one-time use, typically to implement an
interface or extend a class.

Syntax:​

interface Action {

void perform();
}

Action action = new Action() {

public void perform() {

System.out.println("Action performed!");

};

action.perform();​

●​ Use Case: Event handling, lambda expressions (Java 8+ often replace anonymous classes).

Example:

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

System.out.println("Button clicked!");

});

Practice Problem: Create an anonymous inner class to implement a Runnable interface.

Exam Tip: Understand when to use anonymous classes vs. named classes. Be ready to write simple examples for
interfaces.

10. Interfaces and Abstract Classes


●​ Interface: A contract defining methods without implementations (all methods implicitly public abstract
pre-Java 8).
○​ Can include default methods (with implementation) and static methods (Java 8+).

Example:​

interface Vehicle {

void start();

default void stop() {

System.out.println("Vehicle stopped.");
}

class Car implements Vehicle {

public void start() {

System.out.println("Car started.");

}​

●​ Abstract Class: A class that cannot be instantiated, may contain abstract methods (no implementation) and
concrete methods.

Example:​

abstract class Animal {

abstract void makeSound();

void sleep() {

System.out.println("Sleeping...");

class Dog extends Animal {

void makeSound() {

System.out.println("Woof!");

}​

Practice Problem: Create an interface Shape with a method area(), implemented by classes Circle and Rectangle.

Exam Tip: Compare interfaces (multiple inheritance) vs. abstract classes (single inheritance). Know default methods
in interfaces.

11. Inheritance, throw and throws Clauses, User-Defined Exceptions


Inheritance

●​ Allows a class (subclass) to inherit fields and methods from another (superclass) using extends.
●​ super: Access superclass methods/constructors.
●​ Method Overriding: Subclass redefines a superclass method (same signature, @Override annotation
recommended).

Example:​

class Animal {

void eat() {

System.out.println("Eating...");

class Cat extends Animal {

@Override

void eat() {

System.out.println("Cat eats fish.");

}​

throw and throws

●​ throw: Throws an exception explicitly.


○​ Example: throw new IOException("File not found");
●​ throws: Declares exceptions a method may throw.
○​ Example: void readFile() throws IOException { ... }

User-Defined Exceptions

●​ Create custom exceptions by extending Exception (checked) or RuntimeException (unchecked).

Example:​

class InvalidAgeException extends Exception {

public InvalidAgeException(String message) {

super(message);

}
}

class Person {

void setAge(int age) throws InvalidAgeException {

if (age < 0) {

throw new InvalidAgeException("Age cannot be negative");

}​

Practice Problem: Create a user-defined exception InsufficientBalanceException for a banking system.

Exam Tip: Understand checked vs. unchecked exceptions and overriding rules (subclass methods can’t throw
broader exceptions). Practice writing custom exceptions.

12. The StringBuffer Class


StringBuffer is a mutable sequence of characters, unlike the immutable String. It’s thread-safe (synchronized
methods).

●​ Key Methods:
○​ append(): Adds data.
○​ insert(): Inserts data at a position.
○​ delete(): Removes characters.
○​ reverse(): Reverses the string.

Example:​

StringBuffer sb = new StringBuffer("Hello");

sb.append(" World"); // Hello World

sb.insert(5, ","); // Hello, World

sb.reverse(); // dlroW ,olleH​

Note: Use StringBuilder (non-synchronized) for single-threaded applications for better performance.

Practice Problem: Write code to reverse a string using StringBuffer.

Exam Tip: Compare String, StringBuffer, and StringBuilder. Know when to use each.
13. StringTokenizer
StringTokenizer breaks a string into tokens based on delimiters (e.g., spaces, commas).

●​ Key Methods:
○​ hasMoreTokens(): Checks for more tokens.
○​ nextToken(): Returns the next token.

Example:​

StringTokenizer st = new StringTokenizer("apple,banana,orange", ",");

while (st.hasMoreTokens()) {

System.out.println(st.nextToken());

// Output: apple, banana, orange​

Note: String.split() (Java 5+) is often preferred for simple tokenization.

Practice Problem: Tokenize a string "1:2:3" using : as the delimiter.

Exam Tip: Know StringTokenizer methods and when to use split() instead.

14. Applets, Life Cycle of Applet, and Security Concerns


Applets

Applets are small Java programs embedded in web pages, executed by a browser’s JVM.

Structure:​

import java.applet.Applet;

import java.awt.Graphics;

public class MyApplet extends Applet {

public void paint(Graphics g) {

g.drawString("Hello, Applet!", 20, 20);

}​
●​ HTML Embedding:​

<applet code="MyApplet.class" width="200" height="200"></applet>​

Life Cycle of an Applet

●​ init(): Called once to initialize the applet.


●​ start(): Called to start or resume execution (e.g., when the page is loaded).
●​ stop(): Called when the applet is paused (e.g., page minimized).
●​ destroy(): Called when the applet is unloaded (e.g., browser closed).
●​ paint(Graphics g): Called to redraw the applet (from java.awt.Applet).

Example:

public class LifeCycleApplet extends Applet {

public void init() {

System.out.println("Applet initialized");

public void start() {

System.out.println("Applet started");

public void stop() {

System.out.println("Applet stopped");

public void destroy() {

System.out.println("Applet destroyed");

Security Concerns

●​ Applets run in a sandbox by default, restricting access to:


○​ File system, network, system properties.
●​ Signed Applets: Can request additional permissions if digitally signed and trusted by the user.
●​ Risks: Malicious applets could exploit vulnerabilities (e.g., older browsers). Modern browsers have
deprecated applets for security reasons.

Practice Problem: Write an applet to draw a rectangle and display its life cycle methods.
import java.applet.Applet;

import java.awt.Graphics;

public class SimpleApplet extends Applet {

public void init() {

System.out"'Applet initialized");

public void start() {

System.out.println("Applet started");

public void stop() {

System.out.println("Applet stopped");

public void destroy() {

System.out.println("Applet destroyed");

public void paint(Graphics g) {

g.drawRect(20, 20, 100, 50);

g.drawString("Simple Applet", 20, 80);

Exam Tip: Memorize the applet life cycle and sandbox restrictions. Be ready to write a simple applet or explain
security concerns.

Exam-Focused Tips
●​ Common Questions:
○​ Write code for a class with inheritance and overridden methods.
○​ Create a user-defined exception and handle it.
○​ Explain the applet life cycle or write a simple applet.
○​ Compare String vs. StringBuffer vs. StringBuilder.
○​ Debug control flow or operator errors.
●​ Key Examples to Master:
○​ Class with constructor, methods, and inheritance.
○​ Custom exception handling.
○​ Applet with life cycle methods.
○​ String manipulation with StringBuffer.
1. Threads: Creating Threads, Thread Priority, Blocked States,
Extending Thread Class, Runnable Interface
Threads Overview

A thread is a lightweight unit of execution within a process, enabling concurrent task execution. Java’s
java.lang.Thread class and multithreading APIs support thread creation and management.

Creating Threads

Threads can be created in two ways:

1.​ Extending Thread Class:


○​ Subclass Thread and override the run() method.

Example:​

class MyThread extends Thread {

public void run() {

System.out.println("Thread running: " + Thread.currentThread().getName());

}​

2.​ Implementing Runnable Interface:


○​ Implement Runnable’s run() method and pass to a Thread object.
○​ Preferred for flexibility (allows class to extend another class).

Example:​

class MyRunnable implements Runnable {

public void run() {

System.out.println("Runnable running: " + Thread.currentThread().getName());

}​

Starting Threads

●​ Call start() to schedule the thread (invokes run()). Direct run() calls execute in the current thread, not a new
one.

Example:​

MyThread t1 = new MyThread();
t1.start(); // Starts thread

MyRunnable r = new MyRunnable();

Thread t2 = new Thread(r);

t2.start();​

Thread Priority

●​ Threads have priorities (1 to 10, default 5) that influence scheduling.


○​ Constants: Thread.MIN_PRIORITY (1), Thread.NORM_PRIORITY (5), Thread.MAX_PRIORITY (10).

Example:​

t1.setPriority(Thread.MAX_PRIORITY); // Priority 10

t2.setPriority(3); // Custom priority​

Blocked States

A thread can be in various states:

●​ New: Created but not started.


●​ Runnable: Ready to run or running.
●​ Blocked: Waiting for a monitor lock (e.g., in a synchronized block).
●​ Waiting: Waiting indefinitely (e.g., wait()).
●​ Timed Waiting: Waiting with a timeout (e.g., sleep(1000), wait(1000)).
●​ Terminated: Completed or stopped.

Example: A thread calling Thread.sleep(1000) enters Timed Waiting.

Practice Problem: Create a thread using Runnable to print numbers 1 to 5 with a 1-second delay between each.

class NumberPrinter implements Runnable {

public void run() {

for (int i = 1; i <= 5; i++) {

System.out.println(i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}
}

public static void main(String[] args) {

Thread t = new Thread(new NumberPrinter());

t.start();

Show in sidebar

Exam Tip: Understand the differences between extending Thread vs. implementing Runnable. Be ready to explain
thread states and priorities with examples.

2. Thread Synchronization, Synchronize Threads, Sync Code Block,


Overriding Synced Methods, Thread Communication, wait, notify,
notifyAll
Thread Synchronization

Multiple threads accessing shared resources can cause race conditions (inconsistent data). Synchronization
ensures thread-safe access.

●​ Synchronized Methods: Use the synchronized keyword to lock the object’s monitor.

Example:​

class Counter {

private int count = 0;

public synchronized void increment() {

count++;

public int getCount() {

return count;
}

}​

●​ Synchronized Block: Locks a specific object for finer control.

Example:​
java​
Copy​
public void increment() {

synchronized(this) {

count++;

}​

Overriding Synced Methods

●​ A subclass can override a synchronized method, but synchronization isn’t inherited. Explicitly use
synchronized in the subclass if needed.

Example:​

class Parent {

public synchronized void doWork() { ... }

class Child extends Parent {

public void doWork() { // Not synchronized unless specified

synchronized(this) { ... }

}​

Thread Communication

Threads communicate using wait(), notify(), and notifyAll() within synchronized blocks:

●​ wait(): Releases the monitor and waits until notified.


●​ notify(): Wakes one waiting thread.
●​ notifyAll(): Wakes all waiting threads.
Example: Producer-Consumer problem:

class Buffer {

private int data;

private boolean empty = true;

public synchronized void produce(int value) throws InterruptedException {

while (!empty) {

wait(); // Wait if buffer is full

data = value;

empty = false;

notify(); // Notify consumer

public synchronized int consume() throws InterruptedException {

while (empty) {

wait(); // Wait if buffer is empty

empty = true;

notify(); // Notify producer

return data;

Practice Problem: Write a program with two threads: one producing numbers (1 to 5) and another consuming them
using wait and notify.

Exam Tip: Understand race conditions and how synchronization prevents them. Practice producer-consumer
scenarios and know the difference between notify and notifyAll.
3. AWT Components, Component Class, Container Class, Layout
Manager Interface, Default Layouts, Insets, and Dimensions
AWT Components

AWT (Abstract Window Toolkit) provides GUI components for building cross-platform interfaces.

●​ Component Class: Base class for all visual components (e.g., Button, Label, TextField).
○​ Methods: setSize(), setLocation(), setVisible(), addMouseListener().
○​ Example: Button btn = new Button("Click Me");
●​ Container Class: A component that can hold other components (e.g., Frame, Panel).
○​ Methods: add(Component), setLayout(LayoutManager).

Example:​

Frame frame = new Frame("My Window");

frame.add(new Button("OK"));​

Layout Manager Interface

Layout managers control component placement and sizing:

●​ Default Layouts:
○​ Frame: BorderLayout.
○​ Panel: FlowLayout.
●​ Common Layouts:
○​ FlowLayout: Arranges components left-to-right, wraps to next line.
○​ BorderLayout: Divides container into North, South, East, West, Center.
○​ GridLayout: Arranges components in a grid (equal-sized cells).
○​ CardLayout: Stacks components, showing one at a time.
○​ GridBagLayout: Flexible grid with customizable cell sizes and spans.

Insets and Dimensions

●​ Insets: Margins around a container (top, bottom, left, right).


○​ Example: public Insets getInsets() { return new Insets(10, 10, 10, 10); }
●​ Dimensions: Component size (width, height).
○​ Example: btn.setSize(new Dimension(100, 30));

Example: A frame with a button using BorderLayout:

import java.awt.*;

public class MyFrame extends Frame {

public MyFrame() {

setLayout(new BorderLayout());
add(new Button("Click"), BorderLayout.CENTER);

setSize(300, 200);

setVisible(true);

public static void main(String[] args) {

new MyFrame();

Practice Problem: Create a frame with three buttons arranged using GridLayout (1 row, 3 columns).

Exam Tip: Memorize default layouts and practice creating GUIs with different layout managers. Understand how
Insets affect component placement.

4. Border Layout, Flow Layout, Grid Layout, Card Layout,


GridBagLayout
Border Layout

●​ Divides container into five regions: North, South, East, West, Center.
●​ Components stretch to fill their region.

Example:​

Frame f = new Frame();

f.setLayout(new BorderLayout());

f.add(new Button("North"), BorderLayout.NORTH);

f.add(new Button("Center"), BorderLayout.CENTER);​

Flow Layout

●​ Arranges components in a row, wrapping to the next line if needed.


●​ Alignment: FlowLayout.LEFT, CENTER, RIGHT.

Example:​

Panel p = new Panel();
p.setLayout(new FlowLayout(FlowLayout.CENTER));

p.add(new Button("One"));

p.add(new Button("Two"));​

Grid Layout

●​ Arranges components in a grid with equal-sized cells.

Example:​

Frame f = new Frame();

f.setLayout(new GridLayout(2, 2));

f.add(new Button("1"));

f.add(new Button("2"));

f.add(new Button("3"));

f.add(new Button("4"));​

Card Layout

●​ Stacks components like cards, showing one at a time.


●​ Methods: next(), previous(), show().

Example:​

Panel cards = new Panel();

CardLayout cl = new CardLayout();

cards.setLayout(cl);

cards.add("Card1", new Button("First"));

cards.add("Card2", new Button("Second"));

cl.next(cards); // Switch to next card​

GridBagLayout

●​ Flexible grid where components can span multiple cells and have custom weights.
●​ Uses GridBagConstraints to specify position (gridx, gridy), size (gridwidth, gridheight), and weight (weightx,
weighty).
Example:​

Frame f = new Frame();

f.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;

gbc.gridy = 0;

f.add(new Button("Button 1"), gbc);

gbc.gridx = 1;

f.add(new Button("Button 2"), gbc);​

Practice Problem: Create a frame with a GridBagLayout containing two buttons spanning different cells.

import java.awt.*;

public class GridBagExample extends Frame {

public GridBagExample() {

setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;

gbc.gridy = 0;

gbc.gridwidth = 2; // Span 2 columns

add(new Button("Wide Button"), gbc);

gbc.gridx = 0;

gbc.gridy = 1;

gbc.gridwidth = 1;

add(new Button("Small Button"), gbc);

setSize(300, 200);
setVisible(true);

public static void main(String[] args) {

new GridBagExample();

Exam Tip: Practice creating layouts and know the unique features of each (e.g., GridBagLayout’s flexibility). Be
ready to write code for a specific layout.

5. AWT Events, Event Models, Listeners, Class Listener, Adapters,


Action Event Methods, Focus Event, Key Event, Mouse Events,
Window Event
AWT Events

Events represent user interactions (e.g., mouse clicks, key presses) or system actions (e.g., window closing).

●​ Event Classes: Defined in java.awt.event (e.g., ActionEvent, MouseEvent).


●​ Event Sources: Components generating events (e.g., Button, Frame).
●​ Event Listeners: Objects that handle events by implementing listener interfaces.

Event Models

Java uses the Delegation Event Model:

●​ Listeners register with components to receive events.


●​ When an event occurs, the component notifies registered listeners.
●​ Example: A button notifies an ActionListener when clicked.

Listeners and Adapters

●​ Listener Interfaces: Define methods to handle events.


○​ ActionListener: For button clicks, menu selections (actionPerformed(ActionEvent e)).
○​ MouseListener: For mouse clicks, enter/exit (mouseClicked, mouseEntered, etc.).
○​ KeyListener: For key presses (keyPressed, keyReleased, keyTyped).
○​ FocusListener: For focus gain/loss (focusGained, focusLost).
○​ WindowListener: For window events (windowOpened, windowClosing, etc.).
●​ Adapter Classes: Provide empty implementations for listeners with multiple methods (e.g., MouseAdapter,
WindowAdapter).
○​ Example: Extend WindowAdapter to handle only windowClosing.
Event Handling Example

import java.awt.*;

import java.awt.event.*;

public class EventDemo extends Frame {

public EventDemo() {

setLayout(new FlowLayout());

Button btn = new Button("Click Me");

btn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

System.out.println("Button clicked!");

});

add(btn);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

});

setSize(200, 100);

setVisible(true);

public static void main(String[] args) {

new EventDemo();

}
Specific Events

●​ Action Event: Triggered by buttons, menus (ActionListener).


●​ Focus Event: Component gains/loses focus (FocusListener).
●​ Key Event: Key pressed/released/typed (KeyListener).
○​ Example: if (e.getKeyCode() == KeyEvent.VK_ENTER) { ... }
●​ Mouse Events:
○​ MouseListener: Click, enter, exit.
○​ MouseMotionListener: Drag, move.
○​ Example: mouseClicked(MouseEvent e) gets click coordinates (e.getX(), e.getY()).
●​ Window Event: Window opened, closed, minimized (WindowListener).

Practice Problem: Create a frame with a button that changes its label to “Clicked” when pressed, and closes the
window on window close.

import java.awt.*;

import java.awt.event.*;

public class ButtonEventDemo extends Frame {

private Button btn;

public ButtonEventDemo() {

setLayout(new FlowLayout());

btn = new Button("Click Me");

btn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

btn.setLabel("Clicked");

});

add(btn);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

});
setSize(200, 100);

setVisible(true);

public static void main(String[] args) {

new ButtonEventDemo();

Exam Tip: Memorize key listener interfaces and their methods. Practice writing event handlers for buttons, mouse
clicks, and window events.

○​

Exam-Focused Tips
●​ Common Questions:
○​ Write code to create and synchronize threads.
○​ Explain wait, notify, and thread states.
○​ Create a GUI with a specific layout and event handling.
○​ Compare layout managers or implement event listeners.

1. Input/Output Stream, Stream Filters, Buffered Streams, Data Input


and Output Stream, Print Stream, Random Access File
Input/Output Streams
Java’s I/O operations are handled via streams, which are sequences of data. The java.io package provides classes
for reading (input) and writing (output).

●​ Byte Streams: Handle raw binary data (e.g., InputStream, OutputStream).


○​ Example: FileInputStream, FileOutputStream.
●​ Character Streams: Handle Unicode characters (e.g., Reader, Writer).
○​ Example: FileReader, FileWriter.

Stream Filters

Filter streams wrap other streams to add functionality (e.g., buffering, data conversion).

●​ Examples: BufferedInputStream, DataInputStream, PrintStream.

Buffered Streams

●​ BufferedInputStream/BufferedOutputStream: Reduce direct disk access by buffering data.


●​ BufferedReader/BufferedWriter: Buffer character data, with methods like readLine().

Example:​

import java.io.*;

public class BufferedExample {

public static void main(String[] args) throws IOException {

BufferedReader reader = new BufferedReader(new FileReader("input.txt"));

BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));

String line;

while ((line = reader.readLine()) != null) {

writer.write(line + "\n");

reader.close();

writer.close();

}​

Data Input and Output Streams

●​ DataInputStream/DataOutputStream: Read/write primitive data types (e.g., int, double).

Example:

DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"));

dos.writeInt(42);

dos.writeDouble(3.14);

dos.close();

DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"));

System.out.println(dis.readInt()); // 42

System.out.println(dis.readDouble()); // 3.14

dis.close();​

Print Stream

●​ PrintStream: Writes formatted data (e.g., System.out).


●​ Methods: print(), println(), printf().

Example:​

PrintStream ps = new PrintStream(new FileOutputStream("log.txt"));

ps.println("Error occurred at: " + System.currentTimeMillis());

ps.close();​

Random Access File

●​ RandomAccessFile: Supports reading/writing at any file position using a file pointer.


●​ Modes: "r" (read), "rw" (read/write).
●​ Methods: seek(long pos), readInt(), writeInt().

Example:​
]​
RandomAccessFile raf = new RandomAccessFile("data.dat", "rw");

raf.writeInt(100); // Write at position 0

raf.seek(0); // Move to start

System.out.println(raf.readInt()); // 100

raf.close();​

Practice Problem: Write a program to read a text file using BufferedReader and write its contents to another file in
reverse order.
Exam Tip: Understand the hierarchy of stream classes (byte vs. character, buffered vs. unbuffered). Practice
combining streams (e.g., DataInputStream with BufferedInputStream).

2. JDBC (Database Connectivity with MS-Access, Oracle, MS-SQL


Server)
JDBC (Java Database Connectivity) is an API for connecting Java applications to relational databases. It uses
drivers to interact with databases like MS-Access, Oracle, and MS-SQL Server.

JDBC Steps

1.​ Load Driver: Load the database-specific driver.


○​ Oracle: Class.forName("oracle.jdbc.driver.OracleDriver");
○​ MS-SQL Server: Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
○​ MS-Access: Use JDBC-ODBC bridge (deprecated in Java 8+).
2.​ Establish Connection: Use DriverManager.getConnection(url, user, password).
○​ Example URLs:
■​ Oracle: jdbc:oracle:thin:@localhost:1521:xe
■​ MS-SQL: jdbc:sqlserver://localhost:1433;databaseName=mydb
3.​ Create Statement: Use Connection.createStatement() or PreparedStatement for parameterized queries.
4.​ Execute Query: Use executeQuery() (SELECT) or executeUpdate() (INSERT/UPDATE/DELETE).
5.​ Process Results: Use ResultSet for query results.
6.​ Close Resources: Close ResultSet, Statement, and Connection.

Example: Connect to Oracle and retrieve employee data.

import java.sql.*;

public class JDBCExample {

public static void main(String[] args) {

try {

// Load driver

Class.forName("oracle.jdbc.driver.OracleDriver");

// Connect

Connection conn = DriverManager.getConnection(

"jdbc:oracle:thin:@localhost:1521:xe", "username", "password");

// Create statement

Statement stmt = conn.createStatement();

// Execute query
ResultSet rs = stmt.executeQuery("SELECT id, name FROM employees");

// Process results

while (rs.next()) {

System.out.println(rs.getInt("id") + ": " + rs.getString("name"));

// Close resources

rs.close();

stmt.close();

conn.close();

} catch (Exception e) {

e.printStackTrace();

Notes:

●​ PreparedStatement: Prevents SQL injection (e.g., PreparedStatement ps =


conn.prepareStatement("SELECT * FROM employees WHERE id = ?");).
●​ MS-Access: Requires ODBC setup (e.g., jdbc:odbc:accessDB).
●​ Dependencies: Include database drivers (e.g., ojdbc.jar for Oracle).

Practice Problem: Write a JDBC program to insert a record into a students table using PreparedStatement.

Exam Tip: Memorize the JDBC steps and know driver classes/URLs for Oracle and MS-SQL. Practice writing
queries with PreparedStatement and handling SQLException.

3. Object Serialization
Object serialization converts an object’s state to a byte stream for storage or transmission, and deserialization
reconstructs the object.

●​ Classes: ObjectOutputStream, ObjectInputStream.


●​ Requirements: Class must implement Serializable (marker interface).
●​ Transient Fields: Excluded from serialization (e.g., transient int temp;).

Example:​

import java.io.*;
class Person implements Serializable {

String name;

int age;

Person(String name, int age) {

this.name = name;

this.age = age;

public class SerializationExample {

public static void main(String[] args) throws IOException, ClassNotFoundException {

// Serialize

Person p = new Person("Alice", 25);

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"));

oos.writeObject(p);

oos.close();

// Deserialize

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"));

Person deserialized = (Person) ois.readObject();

System.out.println(deserialized.name + ", " + deserialized.age);

ois.close();

}​

Practice Problem: Serialize a Student object with fields id, name, and grade (make grade transient).

Exam Tip: Understand Serializable and transient. Be ready to explain why serialization is useful for networking or
persistence.
4. Sockets
Sockets enable network communication between client and server using TCP or UDP.

●​ TCP Sockets:
○​ ServerSocket: Listens for client connections.
○​ Socket: Represents a client or server connection.
●​ UDP Sockets: Use DatagramSocket and DatagramPacket (connectionless).

Example (TCP Client-Server):​



// Server

import java.io.*;

import java.net.*;

public class Server {

public static void main(String[] args) throws IOException {

ServerSocket server = new ServerSocket(1234);

Socket client = server.accept();

PrintWriter out = new PrintWriter(client.getOutputStream(), true);

out.println("Hello, Client!");

client.close();

server.close();

// Client

public class Client {

public static void main(String[] args) throws IOException {

Socket socket = new Socket("localhost", 1234);

BufferedReader in = new BufferedReader(new


InputStreamReader(socket.getInputStream()));

System.out.println(in.readLine());
socket.close();

}​

Practice Problem: Modify the server to echo back client messages until the client sends “exit”.

Exam Tip: Understand TCP socket setup (client connects, server accepts). Practice simple client-server
communication.

5. Development of Client-Server Applications, Design of Multithreaded


Server
Client-Server Applications

●​ Client: Initiates connection, sends requests, receives responses.


●​ Server: Listens for connections, processes requests, sends responses.
●​ Multithreaded Server: Handles multiple clients concurrently by assigning each client to a thread.

Example (Multithreaded Server):

import java.io.*;

import java.net.*;

public class MultiThreadedServer {

public static void main(String[] args) throws IOException {

ServerSocket server = new ServerSocket(1234);

while (true) {

Socket client = server.accept();

new Thread(new ClientHandler(client)).start();

class ClientHandler implements Runnable {

private Socket client;


public ClientHandler(Socket client) {

this.client = client;

public void run() {

try {

BufferedReader in = new BufferedReader(new


InputStreamReader(client.getInputStream()));

PrintWriter out = new PrintWriter(client.getOutputStream(), true);

String input;

while ((input = in.readLine()) != null) {

out.println("Echo: " + input);

if (input.equals("exit")) break;

client.close();

} catch (IOException e) {

e.printStackTrace();

Practice Problem: Extend the multithreaded server to count active clients.

Exam Tip: Practice writing a multithreaded server with proper synchronization if shared resources are involved.
Understand client-server interaction.

6. Remote Method Invocation (RMI)


RMI enables Java objects to invoke methods on remote objects as if they were local.

●​ Components:
○​ Remote Interface: Extends java.rmi.Remote, declares methods with throws RemoteException.
○​ Server: Implements the interface, registers with RMI registry.
○​ Client: Looks up the remote object and invokes methods.

Example:​

// Remote Interface

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface Hello extends Remote {

String sayHello() throws RemoteException;

// Server Implementation

import java.rmi.registry.*;

import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements Hello {

protected HelloImpl() throws RemoteException {}

public String sayHello() { return "Hello, RMI!"; }

public static void main(String[] args) throws Exception {

HelloImpl obj = new HelloImpl();

Registry registry = LocateRegistry.createRegistry(1099);

registry.bind("Hello", obj);

// Client

import java.rmi.registry.*;

public class Client {


public static void main(String[] args) throws Exception {

Registry registry = LocateRegistry.getRegistry("localhost", 1099);

Hello stub = (Hello) registry.lookup("Hello");

System.out.println(stub.sayHello());

}​

Practice Problem: Create an RMI application for a calculator service with add and subtract methods.

Exam Tip: Understand RMI setup (interface, server, client, registry). Be ready to write a simple RMI program or
explain the role of the registry.

7. Java Native Interface (JNI), Development of a JNI-Based Application


JNI allows Java code to call native code (C/C++) and vice versa.

●​ Steps:
1.​ Write Java class with native methods.
2.​ Compile to generate header file (javah or javac -h).
3.​ Implement native methods in C/C++.
4.​ Compile native code into a shared library (e.g., .dll, .so).
5.​ Load library in Java using System.loadLibrary().

Example:

// Java

public class NativeExample {

static {

System.loadLibrary("NativeLib");

public native void sayHello();

public static void main(String[] args) {

new NativeExample().sayHello();

}
// C (NativeLib.c)

#include <jni.h>

#include <stdio.h>

#include "NativeExample.h"

JNIEXPORT void JNICALL Java_NativeExample_sayHello(JNIEnv *env, jobject obj) {

printf("Hello from C!\n");

●​ Compile: gcc -shared -I$JAVA_HOME/include -o libNativeLib.so NativeLib.c.


●​ Run: Set LD_LIBRARY_PATH or use java -Djava.library.path=. NativeExample.

Practice Problem: Write a JNI program to call a C function that returns the square of a number.

Exam Tip: Understand JNI’s purpose (e.g., accessing hardware, performance). Be ready to outline the steps or write
a simple JNI declaration.

8. Collection API Interfaces, Vector, Stack, Hashtable Classes,


Enumerations, Set, List, Map, Iterators
Collection API Overview

The java.util package provides the Collections Framework for managing groups of objects.

●​ Core Interfaces:
○​ Collection: Root interface (e.g., Set, List).
○​ Set: No duplicates (e.g., HashSet, TreeSet).
○​ List: Ordered, allows duplicates (e.g., ArrayList, LinkedList).
○​ Map: Key-value pairs (e.g., HashMap, TreeMap).
○​ Iterator: Traverses collections (hasNext(), next()).
○​ ListIterator: Bidirectional traversal for List.

Legacy Classes

●​ Vector: Synchronized List (similar to ArrayList but thread-safe).


○​ Example: Vector<String> v = new Vector<>(); v.add("A");
●​ Stack: Extends Vector, implements LIFO (push, pop).
○​ Example: Stack<Integer> s = new Stack<>(); s.push(1); s.pop();
●​ Hashtable: Synchronized Map (no null keys/values).
○​ Example: Hashtable<String, Integer> ht = new Hashtable<>(); ht.put("Alice", 25);
Enumerations

●​ Enumeration: Legacy iterator for Vector, Hashtable.


○​ Methods: hasMoreElements(), nextElement().

Example:​

Vector<String> v = new Vector<>();

v.add("A");

v.add("B");

Enumeration<String> e = v.elements();

while (e.hasMoreElements()) {

System.out.println(e.nextElement());

}​

Modern Collections

●​ Set: HashSet (unordered), TreeSet (sorted).


●​ List: ArrayList (fast access), LinkedList (fast insertion/deletion).
●​ Map: HashMap (unordered), TreeMap (sorted by keys).

Example:​

List<String> list = new ArrayList<>();

list.add("Apple");

list.add("Banana");

Set<Integer> set = new HashSet<>();

set.add(1);

set.add(2);

Map<String, Integer> map = new HashMap<>();

map.put("Alice", 25);

map.put("Bob", 30);

Iterator<String> it = list.iterator();
while (it.hasNext()) {

System.out.println(it.next());

}​

Practice Problem: Write a program to store student names and scores in a HashMap and iterate over it using an
Iterator.

Exam Tip: Compare legacy (Vector, Hashtable) vs. modern (ArrayList, HashMap) collections. Practice iterating with
Iterator and for-each.

Exam-Focused Tips
●​ Common Questions:
○​ Write code for file I/O using buffered streams or RandomAccessFile.
○​ Implement a JDBC program with PreparedStatement.
○​ Create a client-server application or RMI service.
○​ Use collections to solve a problem (e.g., remove duplicates with HashSet).
○​ Explain JNI steps or serialization.
●​ Key Examples to Master:
○​ File copy with BufferedInputStream.
○​ JDBC query with error handling.
○​ Multithreaded echo server.
○​ RMI calculator service.
○​ Collection iteration with HashMap.

You might also like