Java All Unit IPU
Java All Unit IPU
UNIT 1
Overview of Java:
Characteristics of Java:
JVM, JRE, JDK
Parameters used in First Java Program
Basic Java Program Understanding
Java program Compilation and Execution Process
JVM as an interpreter and emulator
Instruction Set
class File Format
Security Promises of the JVM
Class loaders and security aspects
Sandbox model
UNIT 2
Java Fundamentals: Data Types, Literals, and Variables
Operators
Control of Flow
Classes and Instances
Inheritance
Throw and Throws clauses
User defined Exceptions
Applets
UNIT - 3
Threads
Runnable Interface
Thread Communication
AWT Components
Component Class and Container Class:
Layout Manager Interface and Default Layouts:
Insets and Dimensions:
Border Layout:
Flow Layout:
Card Layout:
Grid Bag Layout:
AWT Events:
Event Models:
JAVA 1
Listeners:
Class Listener:
Adapters:
Action Event Methods:
Focus Event Methods:
Key Event Methods:
Mouse Events:
Window Events:
UNIT - 4
Input/Output Streams:
Stream Filters:
Data Input and Output Stream:
Print Stream:
Random Access File:
JDBC (Database connectivity with MS-Access, Oracle, MS-SQL Server)
Object Serialization
Sockets
Development of client Server applications
Design of multithreaded server
Remote Method invocation
Java Native interfaces and Development of a JNI based application
Java Collection API Interfaces
UNIT 1
Overview of Java:
Characteristics of Java:
JAVA 2
1. Platform Independence: One of the key features of Java is its ability to run
on any platform that supports Java Virtual Machine (JVM). This platform
independence is achieved by compiling Java source code into bytecode,
which can be executed on any system with a compatible JVM.
3. Simple and Readable Syntax: Java has a straightforward syntax that is easy
to learn and read. It borrows many syntax conventions from languages like
C and C++, making it familiar to programmers from those backgrounds. The
language promotes clean and organized code through its syntax rules.
5. Rich Standard Library: Java comes with a vast standard library that provides
a wide range of pre-built classes and functions for common programming
tasks. This library includes utilities for input/output operations, data
structures, networking, multithreading, and more. Utilizing the standard
library saves development time and effort.
JAVA 3
8. Community and Ecosystem: Java has a large and active developer
community, which contributes to its rich ecosystem. There are numerous
frameworks, libraries, and tools available for Java development, making it
easier to build complex applications quickly.
Overall, Java is a powerful and versatile programming language known for its
platform independence, object-oriented approach, and robustness. It is widely
used in various domains and provides a solid foundation for building reliable and
scalable applications.
3. JDK: The JDK (Java Development Kit) is a software development kit that
includes tools, libraries, and the JRE. It is used by developers to create,
compile, and debug Java applications. The JDK contains the necessary
components for both development and execution of Java programs.
JAVA 4
public keyword is an access modifier that represents visibility. It means it is
visible to all.
void is the return type of the method. It means it doesn't return any value.
String[] args or String args[] is used for command line argument. We will
discuss it in coming section.
JAVA 5
Let's break down the different components of the program:
1. Import Statements:
The program begins with import statements that specify the classes from
the Java standard library that will be used in the program.
In this example, we import the Scanner class from the java.util package
to facilitate user input.
2. Public Class:
The class name should match the filename (excluding the .java
3. Main Method:
The main method is declared as public , static , and void , with a single
parameter of type String array ( String[] args ).
public indicates that the method can be accessed from outside the
class.
static means the method belongs to the class itself, rather than an
instance of the class.
void specifies that the method does not return any value.
4. Method Body:
Inside the main method, we create a Scanner object to read input from
the user.
5. User Input:
JAVA 6
Then we use the Scanner object's nextLine() method to read the user's
input and store it in the name variable of type String .
6. Output:
7. Scanner Closing:
To begin, you need to write your Java program's source code. This is
done in a plain text file with a .java extension. You can use any text
editor or integrated development environment (IDE) for this purpose.
The next step is to compile the Java source code into bytecode.
Bytecode is a platform-independent representation of your program that
can be executed by the Java Virtual Machine (JVM).
To compile the source code, you use the Java compiler (javac) that
comes with the Java Development Kit (JDK). In the command prompt or
terminal, navigate to the directory where your source code file is located
and execute the following command:
JAVA 7
javac YourProgram.java
If there are no errors in your code, the compiler will generate a bytecode
file with a .class extension. This file contains the compiled version of
your program.
When you run a Java program, you need to have a JVM installed on
your machine. The JVM takes care of loading and executing the
bytecode.
To run the compiled bytecode, you use the java command followed by
the name of the class containing the main method (the entry point of
your program).
java YourProgram
The JVM will start executing the bytecode, and your program will run
accordingly.
The Java Virtual Machine (JVM) is the cornerstone of the Java platform. It
provides a runtime environment for executing Java bytecode and plays a crucial
role in the platform's platform independence and security. Let's explore the
organization of the JVM:
1. Class Loader:
JAVA 8
as locating and loading the necessary class files from the file system,
network, or other sources.
The class loader is divided into three main components: the bootstrap
class loader, extension class loader, and application class loader. These
loaders work together to load classes based on the class's visibility and
dependency requirements.
The JVM defines several runtime data areas that are used during
program execution:
Heap: The heap is a runtime data area where objects are allocated.
It is divided into different regions and is the memory area managed
by the garbage collector for dynamic memory allocation and
deallocation.
Java Stack: Each thread in the JVM has its own Java stack, which is
used for method execution and storing local variables, method
parameters, and partial results. It also keeps track of method
invocations and returns.
Native Method Stack: The native method stack is used for executing
native code (code written in languages other than Java) and
handling interactions with the underlying operating system.
3. Execution Engine:
JAVA 9
performance. It optimizes the execution of the bytecode by
analyzing and translating it into efficient machine instructions.
The garbage collector identifies objects that are no longer reachable and
frees the memory occupied by them, ensuring efficient memory usage
and preventing memory leaks.
The Native Method Interface (JNI) allows Java code to interact with code
written in other programming languages, such as C or C++. It provides a
way to call native methods and exchange data between Java and native
code.
JAVA 10
1. JVM as an Interpreter:
The JVM interprets Java bytecode instructions one by one and executes
them. It reads the bytecode, understands the instruction, and performs
the corresponding operation. This interpretation happens at runtime.
2. JVM as an Emulator:
By providing this emulation layer, the JVM ensures that Java programs
can run consistently across different platforms without being directly
dependent on the underlying hardware and operating system.
It's important to note that the JVM combines interpretation and emulation with
the Just-In-Time (JIT) compilation technique to improve performance. The JIT
compiler dynamically compiles frequently executed bytecode into native machine
code, which can be directly executed by the CPU. This compilation process
optimizes the execution speed of the Java program by eliminating the
interpretation overhead.
So, while the JVM primarily operates as an interpreter, it also incorporates
emulation techniques to provide a consistent runtime environment and platform
independence for Java programs.
JAVA 11
Instruction Set
The instruction set in the context of Java refers to the set of bytecode
instructions that the Java Virtual Machine (JVM) can execute. These instructions
are specified by the Java Virtual Machine Specification and are used to perform
various operations and control flow within a Java program.
Here are some common bytecode instructions found in the Java instruction set:
iand , ior , ixor : Perform bitwise AND, OR, XOR on two integers.
4. Object-oriented Instructions:
JAVA 12
invokevirtual , invokestatic , invokeinterface : Invoke methods on objects
or classes.
5. Array Instructions:
iaload , faload , aaload : Load an element from an array onto the stack.
These are just a few examples of the instructions available in the Java bytecode
instruction set. The JVM executes these instructions in a stack-based manner,
where operands are pushed onto a stack and operations are performed on the
top elements of the stack.
It's worth noting that Java bytecode instructions are designed to be platform-
independent and are executed by the JVM, which is responsible for translating
them into machine code specific to the underlying hardware architecture.
The class file starts with a fixed 4-byte magic number ( 0xCAFEBABE ) that
identifies it as a valid class file.
The version numbers (minor and major) indicate the version of the class
file format being used.
2. Constant Pool:
The constant pool section stores various constant values used by the
class, such as strings, class names, field names, method names, and
more.
JAVA 13
The constant pool is an array-like structure, and each entry has a tag
indicating its type and the actual value.
The access flags represent the access level and properties of the class
(e.g., public, final, abstract).
The class information includes the fully qualified name of the class, the
name of its superclass, and interfaces it implements.
The fields section lists the fields (variables) defined within the class,
along with their access flags, names, types, and any initial values.
5. Attributes:
They can include information such as source file name, line number
tables, exceptions thrown, annotations, and more.
The class file format follows a specific structure and is designed to be platform-
independent. It allows the JVM to interpret and execute the bytecode on any
system that has a compatible JVM implementation.
It's important to note that the class file format is defined in the Java Virtual
Machine Specification and is subject to updates and revisions as new versions
of the JVM are released.
JAVA 14
1. Bytecode Structure: The verification process ensures that the bytecode
conforms to the structural rules defined by the JVM specification. It checks
for valid instructions, correct operand types, proper control flow, and
exception handling.
4. Stack Integrity: The verification process ensures that the bytecode's stack
operations, such as pushing and popping values, are well-formed and don't
violate the stack's integrity.
1. Class Structures: The Class Area stores information about classes and
interfaces loaded by the JVM. This includes the fully qualified names of the
classes, superclass and interface references, field information, method
bytecode, constant pool, and static variables.
3. Method Bytecode: The Class Area holds the bytecode instructions for
methods defined in the loaded classes. These instructions are interpreted or
compiled to machine code for execution.
JAVA 15
4. Static Variables: The Class Area also includes memory space for static
variables, which are shared among all instances of a class. Static variables
are initialized when the class is loaded and can be accessed without
creating an instance of the class.
The Class Area provides a centralized location for class-level information and
allows efficient sharing of data among multiple instances of the same class. It is
managed by the JVM's garbage collector, which handles the allocation and
deallocation of memory within the Class Area.
Java Stack:
The Java Stack is a region of memory used for method execution and storing
local variables and method call information. Here are some key points about the
Java Stack:
1. Stack Frames: Each method invocation creates a new stack frame, also
known as an activation record, on the Java Stack. The stack frame contains
information such as local variables, method parameters, return address, and
intermediate results.
4. Thread-Specific: Each thread in a Java program has its own stack. This
allows multiple threads to execute methods concurrently without interfering
with each other's stack frames.
The Java Stack is efficient for managing method calls and local variables
because of its simple and predictable nature. However, it has limited memory
compared to the Java Heap.
Java Heap:
The Java Heap is a region of memory used for dynamic memory allocation,
JAVA 16
specifically for objects and arrays. Here are some key points about the Java
Heap:
1. Object Storage: The Java Heap is where objects are allocated and
deallocated during the program's execution. Objects are created using the
"new" keyword and reside in the heap until they are no longer referenced.
4. Shared Among Threads: Unlike the Java Stack, the Java Heap is shared
among all threads in a Java program. Multiple threads can access and
modify objects stored in the heap simultaneously.
Garbage Collection:
Garbage Collection is the process of automatically reclaiming memory occupied
by objects that are no longer needed in a Java program. Here are some key
points about Garbage Collection:
2. Mark and Sweep: The most common garbage collection algorithm is the
Mark and Sweep algorithm. It works by traversing objects starting from the
root references (e.g., static variables, method call stacks) and marking
reachable objects. Unmarked objects are then swept and their memory is
reclaimed.
JAVA 17
based on object lifetimes. This allows for more efficient garbage collection by
focusing on short-lived objects in the young generation.
Every object is an instance of exactly one class, which does not change
through the life of the object.
If a field or method is marked private, then the only code that ever accesses
it is found within the class itself.
Fields and methods marked protected are used only by code that
participates in the implementation of the class.
Security Architecture:
The security architecture of the JVM encompasses the design principles,
mechanisms, and features that ensure the security of Java applications. It
JAVA 18
provides a layered approach to protect the integrity, confidentiality, and
availability of resources within the JVM. Here are key aspects of the JVM's
security architecture:
2. Security Providers: The JVM allows the integration of security providers that
offer cryptographic algorithms, secure protocols, and other security-related
services. These providers implement the Java Cryptography Architecture
(JCA) and Java Cryptography Extension (JCE) to provide cryptographic
functionalities such as encryption, digital signatures, and secure random
number generation.
4. Class Loading and Sandboxing: The JVM's class loading mechanism and
sandboxing model contribute to its security architecture. Class loading
ensures that classes are loaded from trusted sources and verified before
execution. The sandboxing model restricts untrusted code by isolating its
execution environment, preventing unauthorized access to resources and
system operations.
Security Policy:
The security policy in the JVM defines the permissions and access controls for
Java applications. It specifies the rules and restrictions that determine what
operations an application can perform and what resources it can access. The
JAVA 19
security policy is typically defined in a security policy file, which is loaded by the
JVM during application startup.
When a class needs to be loaded, the class loader first delegates the
task to its parent. If the parent class loader cannot find the class, the
current class loader attempts to load it.
3. Security Constraints:
The Java Security Manager, along with the security policy, defines the
permissions and restrictions for different code sources. Class loaders
are responsible for implementing these security policies by loading
classes in accordance with the defined constraints.
JAVA 20
The Security Manager, as part of the JVM's security architecture,
interacts with class loaders to enforce security policies and permissions.
Class loaders assist in this process by ensuring that classes and code
sources adhere to the security policies defined by the Security Manager.
Java allows the creation of custom class loaders that can be used to
extend or modify the default class loading behavior.
Sandbox model
The sandbox model is a security mechanism implemented in the Java Virtual
Machine (JVM) to restrict untrusted code from accessing sensitive resources
and performing potentially harmful operations. It creates a controlled execution
environment for untrusted code, ensuring that it operates within predefined
boundaries. Here are the key aspects of the sandbox model:
JAVA 21
2. Access Control: The sandbox model enforces access control policies to
regulate the interactions between the untrusted code and the system
resources. It specifies what resources the code can access, such as the file
system, network, or system properties. By controlling these access rights,
the sandbox model limits the potential damage that untrusted code can
cause.
4. Security Policies: The security policies in the sandbox model define the
permissions and restrictions for untrusted code. These policies are typically
specified in a security policy file, which is loaded by the JVM. The policies
can specify the allowable actions, such as reading or writing files, creating
network connections, or accessing certain system properties. The Security
Manager uses these policies to determine whether the requested actions are
permitted.
JAVA 22
accessing protected resources, or executing native code. By confining the
code within the sandbox, the model provides a layer of protection against
malicious actions.
The sandbox model is particularly useful when executing untrusted code, such
as applets in web browsers or code from unknown sources. It allows for the
execution of potentially risky code while mitigating the risks and maintaining the
overall security of the system.
It's worth noting that the effectiveness of the sandbox model relies on proper
configuration, adherence to security best practices, and regular updates to
address potential vulnerabilities in the JVM.
UNIT 2
Java Fundamentals: Data Types, Literals, and Variables
Java is a statically-typed programming language, which means that you need to
declare the type of a variable before using it. Java provides several built-in data
types to store different kinds of values. Let's explore the fundamentals of data
types, literals, and variables in Java:
Data Types:
Java has two categories of data types: primitive types and reference types.
1. Primitive Types:
JAVA 23
2. Reference Types:
Literals:
Literals are constant values that are directly written into your code. They
represent specific values of different data types.
For example:
Variables:
Variables are named memory locations used to store data. Before using a
variable, you must declare it with its data type. Here's the syntax to declare a
variable:
dataType variableName;
For example:
int age;
double salary;
boolean isStudent;
JAVA 24
For example:
Once a variable is declared, you can assign new values to it using the
assignment operator (=):
variableName = newValue;
For example:
age = 30;
salary = 5500.0;
isStudent = false;
Java supports type inference with the introduction of the var keyword in Java
10. It allows the compiler to infer the data type based on the assigned value.
For example:
Variables can be used in expressions and can be reassigned with new values
throughout the program.
Remember to follow the naming conventions for variables, such as starting with
a lowercase letter and using camel case (e.g., myVariable).
Understanding data types, literals, and variables is crucial for writing Java
programs. It enables you to store and manipulate different kinds of data in your
applications.
Wrapper Classes:
In Java, wrapper classes are used to represent the primitive data types as
JAVA 25
objects. They provide a way to encapsulate primitive values and provide
additional functionality through methods defined in the wrapper class. The
wrapper classes are part of the java.lang package and include the following:
Wrapper classes are commonly used when you need to perform operations such
as converting a primitive type to a string, parsing a string to a primitive type, or
using collections that require objects rather than primitives.
For example, to convert an int to a String, you can use the Integer wrapper
class:
Arrays:
Arrays in Java are used to store multiple elements of the same type. They
provide a way to work with collections of values in a structured manner. Here are
some key points about arrays in Java:
You specify the data type followed by the variable name and square
brackets indicating the array dimensions.
JAVA 26
// Declaration and initialization
int[] numbers = {1, 2, 3, 4, 5};
You can retrieve or modify the value at a specific index using the array
variable and the index in square brackets.
1. Array Length:
1. Multidimensional Arrays:
The enhanced for loop (for-each loop) allows iterating over the elements
of an array without explicitly using the index.
JAVA 27
for (int number : numbers) {
System.out.println(number);
}
Arrays provide a convenient way to work with collections of values in Java. They
allow efficient storage and retrieval of data and are extensively used in various
programming scenarios.
Operators
1. Arithmetic Operators:
JAVA 28
int count = 5;
count++; // count is now 6
count--; // count is now 5
2. Assignment Operators:
Assignment (=): Assigns the value of the right operand to the left
operand.
Compound Assignment Operators (e.g., +=, -=, *=, /=): Performs the
operation and assigns the result to the left operand.
int value = 5;
value += 3; // value is now 8
3. Comparison Operators:
Greater than (>), Less than (<), Greater than or equal to (>=), Less than
or equal to (<=): Compare the values of two operands.
4. Logical Operators:
JAVA 29
boolean result = (true && false); // result is false
Left Shift (<<): Shifts the bits of the left operand to the left by a specified
number of positions.
JAVA 30
Right Shift (>>): Shifts the bits of the left operand to the right by a specified
number of positions.
Control of Flow
Control Flow in Java refers to the order in which statements are executed in a
program. It allows you to make decisions, repeat statements, and break the
normal flow of execution. There are several constructs in Java that help you
control the flow of your program. Here are the main control flow constructs:
1. Conditional Statements:
if (condition) {
// code to be executed if the condition is true
} else {
// code to be executed if the condition is false
}
JAVA 31
switch (expression) {
case value1:
// code to be executed if expression matches value1
break;
case value2:
// code to be executed if expression matches value2
break;
default:
// code to be executed if expression doesn't match any case
}
2. Looping Statements:
while (condition) {
// code to be executed as long as the condition is true
}
Do-while loop: Similar to the while loop, but the condition is evaluated
after executing the block of code, so it always executes at least once.
do {
// code to be executed
} while (condition);
3. Jump Statements:
JAVA 32
Break statement: Terminates the execution of a loop or switch statement
and transfers control to the next statement after the loop or switch.
break;
Continue statement: Skips the remaining code within a loop and moves
to the next iteration.
continue;
return value;
4. Branching Statements:
if (condition1) {
// code to be executed if condition1 is true
} else if (condition2) {
// code to be executed if condition2 is true
} else {
// code to be executed if none of the conditions are true
}
These control flow constructs give you the ability to make decisions, repeat
code, and alter the flow of execution in your Java programs. By using these
constructs effectively, you can create programs that perform different actions
based on various conditions and iterate over data structures efficiently.
JAVA 33
Classes and Instances
In Java, classes and instances are fundamental concepts of object-oriented
programming. Let's understand what they mean:
1. Classes:
It provides the definition of how objects of that class should behave and
interact with each other.
Classes are declared using the class keyword followed by the class
name.
// methods
void sayHello() {
System.out.println("Hello, my name is " + name);
}
}
2. Instances (Objects):
It is created from a class using the new keyword, and each instance has
its own set of attributes (instance variables) and can perform actions
(invoke methods) defined in the class.
Multiple instances of the same class can exist, each with its own state
(values of attributes).
JAVA 34
Instances are created dynamically at runtime when the program needs
them.
person2.name = "Jane";
person2.age = 30;
Each instance has its own set of instance variables, and changes made
to one instance do not affect other instances.
By defining classes and creating instances, you can model and represent real-
world entities or concepts in your Java programs. Classes provide the structure,
and instances allow you to work with individual objects based on that structure.
private : The member can only be accessed within the same class.
JAVA 35
final : The member's value cannot be changed.
Anonymous inner classes are often used for event handling or defining
small, one-time-use classes.
3. Interfaces:
JAVA 36
A class implements an interface using the implements keyword and
provides implementations for all the methods declared in the interface.
interface Shape {
void draw(); // Abstract method declaration
}
4. Abstract Classes:
JAVA 37
In the example above, the Animal class is declared as abstract with an
abstract method sound() . The Cat class extends the Animal class and
provides an implementation for the sound() method.
Inheritance
Inheritance is a fundamental concept in object-oriented programming that allows
you to create new classes based on existing classes. It enables code reuse and
the establishment of hierarchical relationships between classes. Inheritance is
achieved through the process of deriving new classes from existing classes,
where the new classes inherit the properties and behavior of the existing
classes. Let's delve into the details of inheritance:
The superclass is the existing class from which the subclass is derived.
The subclass inherits all the non-private fields and methods from the
superclass and can add its own unique fields and methods.
2. Inheritance Syntax:
Here's an example:
JAVA 38
class Superclass {
// superclass members
}
3. Inherited Members:
The subclass can directly use the inherited members without redefining
them, unless they are overridden.
4. Overriding Methods:
To override a method, the method in the subclass must have the same
signature (name, return type, and parameters) as the method in the
superclass.
class Superclass {
void display() {
System.out.println("Superclass method");
}
}
JAVA 39
5. Access Modifiers in Inheritance:
6. Inheritance Hierarchies:
The subclass inherits both the members of its immediate superclass and
all the members of the superclass hierarchy above it.
In Java, there are several types of inheritance that you can use to establish
relationships between classes. These types include:
1. Single Inheritance:
Example:
JAVA 40
class Superclass {
// superclass members
}
This is done to avoid ambiguity and complexities that can arise from
multiple inheritance.
Example:
interface Interface1 {
// interface1 members
}
interface Interface2 {
// interface2 members
}
3. Multilevel Inheritance:
Each class serves as the superclass for the next class in the hierarchy.
Example:
JAVA 41
class Superclass {
// superclass members
}
4. Hierarchical Inheritance:
Each subclass shares the properties and behavior of the superclass and
can add its own unique features.
Example:
class Superclass {
// superclass members
}
Example:
JAVA 42
class Superclass {
// superclass members
}
interface Interface1 {
// interface1 members
}
interface Interface2 {
// interface2 members
}
It's important to note that Java does not support direct multiple inheritance for
classes, but it allows for implementing multiple interfaces, achieving a similar
effect. The choice of inheritance type depends on the specific requirements and
design of your program.
1. throw Clause:
Syntax:
JAVA 43
throw exception;
Example:
2. throws Clause:
The throws clause is used in the method declaration to indicate that the
method may throw one or more types of exceptions.
When a method with a throws clause calls another method that throws a
checked exception, the calling method must handle or declare the
exception using its own throws clause.
Syntax:
Example:
In the example above, the readFile method declares that it may throw
an IOException . Any method calling readFile must either handle the
JAVA 44
IOException or declare it in its own throws clause.
The throw clause is used to raise exceptions explicitly, while the throws clause
is used to declare the exceptions that a method can throw. Together, they
facilitate exception handling and ensure that exceptions are appropriately caught
and handled in the program.
It's worth noting that checked exceptions (exceptions that are subclasses of
Exception but not subclasses of RuntimeException ) must be declared using the
throws clause or caught using a try-catch block, whereas unchecked exceptions
(subclasses of RuntimeException ) do not need to be declared or caught.
You can add additional fields, constructors, and methods to your custom
exception class as needed.
Example:
Once you have defined your custom exception class, you can throw
instances of that exception when necessary.
JAVA 45
Use the throw keyword followed by an instance of your custom
exception class to throw the exception.
Example:
Example:
try {
someMethod();
} catch (CustomException e) {
// Handle the custom exception
}
Example:
By creating your own exception classes, you can handle specific exceptional
situations in a more tailored and meaningful way. Custom exceptions allow you
JAVA 46
to communicate and handle exceptional conditions specific to your application
domain.
1. Creating a StringBuffer:
Example:
The append() method is used to add characters at the end of the existing
content.
Example:
JAVA 47
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // "Hello World"
sb.insert(5, ","); // "Hello, World"
sb.delete(5, 7); // "Hello World"
sb.replace(6, 11, "Java"); // "Hello Java"
method.
Example:
4. Thread Safety:
However, this thread safety comes at the cost of performance due to the
synchronization overhead.
If you don't require thread safety, you can use the non-thread-safe
alternative, StringBuilder , which provides similar functionality but without
the synchronization.
5. Performance Considerations:
JAVA 48
string and can be used in both single-threaded and multi-threaded scenarios.
Tokenizer
The StringTokenizer class in Java is used to break a string into smaller tokens or
parts, based on a specified delimiter. It provides a simple and convenient way to
tokenize strings. Here's an overview of the StringTokenizer class:
1. Creating a StringTokenizer:
To create a StringTokenizer object, you need to pass the input string and
the delimiter to its constructor.
Example:
2. Retrieving Tokens:
You can use the hasMoreTokens() method to check if there are more
tokens available in the input string.
The nextToken() method is used to retrieve the next token from the input
string.
Example:
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
// Process the token
}
3. Changing Delimiters:
You can change the delimiter by using the overloaded constructor or the
setDelimiter() method.
Example:
JAVA 49
String input = "Hello-World-Java";
StringTokenizer tokenizer = new StringTokenizer(input, "-");
4. Counting Tokens:
You can use the countTokens() method to get the total number of tokens
remaining in the tokenizer.
Example:
Example:
6. Retrieving Delimiters:
Example:
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()) {
String delimiter = tokenizer.nextDelimiter();
// Process the delimiter
}
}
JAVA 50
process delimited data or extract specific parts from a string.
However, note that the StringTokenizer class is considered legacy and has been
largely replaced by the String.split() method and regular expressions ( Pattern
and Matcher classes) for more advanced string parsing and splitting
requirements.
Applets
Applets are small Java programs that are designed to run within a web browser.
They were a popular way to add interactive content to web pages in the past, but
their usage has significantly decreased due to security concerns and the
emergence of alternative technologies. Nevertheless, understanding applets and
their lifecycle can provide insights into the history of web development. Let's
delve into the details of applets, their lifecycle, and security concerns:
1. Applets:
Applets are Java programs that are embedded in HTML web pages and
run in a sandboxed environment within a web browser.
Applets were rendered using the Java Applet Viewer or a web browser
with Java plugin support.
2. Applet Lifecycle:
JAVA 51
another page or closes the browser window.
3. Security Concerns:
JAVA 52
It's important to note that as of Java 11, the Java Plugin and Applet API have
been deprecated and removed from the Java Development Kit (JDK). Therefore,
applets are no longer supported in modern browsers.
Here are a couple of examples to illustrate the usage of applets and their
lifecycle:
import java.applet.Applet;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
JAVA 53
addMouseListener(this);
}
JAVA 54
handle mouse events. The mouseClicked() method is overridden to change the
background color and trigger a repaint of the applet.
UNIT - 3
Threads
Threads are a fundamental concept in Java that allow concurrent execution of
code. They are lightweight units of execution within a program, enabling multiple
tasks to run concurrently. Here are the key aspects of threads:
By default, Java programs have at least one thread, known as the main
thread, which is created automatically when the program starts.
Creating Threads:
In Java, there are two main ways to create threads:
You can create a thread by extending the Thread class and overriding its
run() method, which contains the code to be executed by the thread.
Here's an example:
To start the thread, create an instance of the MyThread class and call its
start() method.
JAVA 55
Alternatively, you can create a thread by implementing the Runnable
interface and passing an instance of it to the Thread constructor.
Here's an example:
Thread Priority:
Threads in Java can have different priorities, ranging from 1 (lowest) to 10
(highest). The default priority is 5. Here are some points to know about thread
priority:
Thread priorities are used by the thread scheduler to determine the order of
execution when multiple threads are ready to run.
You can set the priority of a thread using the setPriority() method, passing
the desired priority as an argument.
Thread priority should be used with caution and should not be solely relied
upon for critical operations.
Blocked States:
Threads can enter into blocked states in certain situations. Here are two
common scenarios:
Waiting: Threads can wait for a specific condition to be met using the wait()
JAVA 56
Extending the Thread Class:
As mentioned earlier, one way to create threads is by extending the Thread
When extending the Thread class, you override the run() method to define
the behavior of the thread.
By extending the Thread class, your class becomes a thread itself and can
be instantiated and started like any other thread.
However, this approach limits the flexibility of your class, as it does not allow
for extending other classes.
If you've created a thread by extending the Thread class, you can simply
create an instance of your class and call the start() method on it.
Example:
javaCopy code
MyThread myThread = new MyThread(); // Assuming MyThread extends Thread
myThread.start();
It's important to note that concurrent programming and managing threads can be
complex, as it involves synchronization, thread safety, and coordination between
threads. It's recommended to study these topics further to write robust and
efficient multi-threaded programs.
Runnable Interface
The Runnable interface in Java provides an alternative way to create threads by
encapsulating the code to be executed within a separate object. Here's an
overview of the Runnable interface:
JAVA 57
Create a class that implements the Runnable interface.
Implement the run() method within the class, which contains the code to be
executed by the thread.
Call the start() method on the Thread object to start the execution of the
thread.
of MyRunnable and pass it to the Thread constructor. Finally, we start the thread by
calling the start() method.
class directly:
object, you can reuse the object and share it among multiple threads if
needed.
JAVA 58
Enhanced Thread Pooling: When utilizing thread pooling techniques, such
as the Executor framework, using Runnable objects allows for more efficient
utilization of thread resources.
By utilizing the Runnable interface, you can design your code to be more flexible,
modular, and scalable when dealing with multi-threaded scenarios.
Thread Synchronization:
In multi-threaded programming, thread synchronization is important to ensure
proper coordination and order of execution between threads. It helps prevent
data inconsistency and race conditions. Java provides synchronization
mechanisms to achieve thread synchronization:
1. Synchronized Methods:
Example:
2. Synchronized Blocks:
You can also synchronize specific blocks of code using the synchronized
The lock ensures that only one thread can execute the synchronized
block at a time.
Example:
synchronized (lockObject) {
// Synchronized block code
}
JAVA 59
Synchronize Threads:
To synchronize threads and ensure proper coordination, you can use methods
like wait() , notify() , and notifyAll() . These methods must be called from
within a synchronized context (synchronized method or synchronized block).
Here's an overview:
wait() : Causes the current thread to release the lock and enter a waiting
state until another thread calls notify() or notifyAll() on the same object. It
should be used within a loop to check the condition that caused the thread to
wait.
: Wakes up one of the threads that are waiting on the same object.
notify()
The awakened thread can then compete for the lock and continue execution.
notifyAll() : Wakes up all the threads that are waiting on the same object.
By using synchronization and the methods mentioned above, you can control the
execution order and synchronization between threads, ensuring proper
concurrency and data consistency.
1. Syntax:
synchronized (object) {
// Synchronized code block
}
2. Object Lock:
The lock can be any object, but it is commonly a shared object that the
threads need to synchronize on.
JAVA 60
Only one thread can hold the lock at a time, and other threads will wait
until the lock is released.
3. Benefits:
Sync code blocks allow you to synchronize only the critical section of
code that needs synchronization, rather than the entire method.
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
JAVA 61
to ensure that only one thread can modify the count variable at a time.
Example:
class SuperClass {
public synchronized void synchronizedMethod() {
// Superclass synchronized method
}
}
In the example above, the SuperClass has a synchronized method. The SubClass
Thread Communication
Thread Communication using wait(), notify(), and notifyAll():
In Java, threads can communicate with each other using the methods wait() ,
notify() , and notifyAll() . These methods are part of the Object class and can
JAVA 62
be used to coordinate the execution of threads. Here's an explanation of how
these methods work:
1. wait():
The wait() method causes the current thread to release the lock on the
object and enter a waiting state until another thread calls notify() or
notifyAll() on the same object.
When a thread calls wait() , it relinquishes the lock and allows other
threads to continue execution. The thread remains in a waiting state until
it receives a notification to resume.
Example:
synchronized (sharedObject) {
while (condition) {
sharedObject.wait(); // Waits until notified
}
// Continue execution after receiving notification
}
2. notify():
The notify() method wakes up one thread that is waiting on the same
object. It allows that thread to continue execution after it regains the
lock.
If multiple threads are waiting, the thread that gets the notification is
arbitrary and depends on the thread scheduler.
Example:
synchronized (sharedObject) {
// Update shared data or perform some task
sharedObject.notify(); // Notifies one waiting thread
}
3. notifyAll():
The notifyAll() method wakes up all threads that are waiting on the
same object. It allows all the waiting threads to continue execution after
they regain the lock.
JAVA 63
Example:
synchronized (sharedObject) {
// Update shared data or perform some task
sharedObject.notifyAll(); // Notifies all waiting threads
}
Call wait() , notify() , and notifyAll() only from within synchronized blocks
or synchronized methods.
Use a loop with wait() to check the condition that caused the thread to wait.
This helps prevent spurious wake-ups.
Make sure the threads involved are accessing the same shared object for
synchronization.
AWT Components
AWT (Abstract Window Toolkit) is a set of classes and components in Java used
for creating graphical user interfaces (GUIs) for desktop applications. AWT
provides a collection of UI components that allow developers to create windows,
buttons, labels, text fields, and other elements to build interactive user
interfaces. Here are some commonly used AWT components:
1. Frame:
The Frame class represents a top-level window with a title bar and
borders.
JAVA 64
Example:
2. Panel:
The Panel class represents a container that can hold other components.
Example:
3. Button:
Example:
4. Label:
Example:
5. TextField:
The TextField class represents a single-line input field where users can
enter text.
JAVA 65
It is used for accepting user input or displaying dynamic text.
Example:
6. TextArea:
The TextArea class represents a multi-line text area where users can
enter or view large amounts of text.
Example:
7. Checkbox:
Example:
These are just a few examples of AWT components. AWT provides many more
components such as List, Choice, Scrollbar, Menu, etc., which you can use to
create rich and interactive GUIs in Java.
To use AWT components, you need to import the relevant classes from the
java.awt package.
JAVA 66
1. Component Class:
The Component class is an abstract class that serves as the base class
for all AWT components.
2. Container Class:
JAVA 67
: Sets the layout manager for the
setLayout(LayoutManager manager)
The Component class and the Container class provide the basic functionality for
creating and managing GUI components in AWT. By subclassing these classes
and utilizing their methods and properties, you can build complex and interactive
user interfaces in Java.
The LayoutManager interface is the base interface for all layout managers
in AWT.
JAVA 68
Dimension minimumLayoutSize(Container parent) : Returns the minimum
size of the layout.
2. Default Layouts:
AWT provides several default layout managers that implement the
LayoutManager interface. These layouts handle the positioning and sizing of
FlowLayout:
Example:
BorderLayout:
Example:
GridLayout:
JAVA 69
Example:
GridBagLayout:
Example:
These are just a few examples of default layouts available in AWT. Each
layout manager has its own set of properties and behavior, allowing you to
choose the most appropriate one for your GUI design.
By utilizing the Layout Manager interface and selecting the appropriate layout
manager, you can create well-structured and responsive user interfaces in Java.
1. Insets:
JAVA 70
int top: Represents the top inset (distance from the top edge of the
container).
int left: Represents the left inset (distance from the left edge of
the container).
int bottom : Represents the bottom inset (distance from the bottom
edge of the container).
int right : Represents the right inset (distance from the right edge of
the container).
2. Dimensions:
It's worth noting that both Insets and Dimension are immutable classes,
meaning their values cannot be changed once set. To modify their values,
you would typically create new instances with the desired values.
These classes are often used in conjunction with layout managers to control the
size, spacing, and positioning of components within containers. They provide a
convenient way to manage the visual aspects of GUI design.
JAVA 71
Border Layout:
The BorderLayout is a default layout manager provided by AWT.
It divides the container into five regions: North, South, East, West, and
Center.
Example usage:
Flow Layout:
The FlowLayout is a default layout manager provided by AWT.
Example usage:
Grid Layout:
Example usage:
JAVA 72
Container container = new Container();
container.setLayout(new GridLayout(rows, columns));
container.add(component1);
container.add(component2);
These layout managers are commonly used in Java GUI applications to organize
components within containers. By selecting the appropriate layout manager and
adding components to the specified regions or grid cells, you can create visually
appealing and responsive user interfaces.
Card Layout:
The CardLayout is a default layout manager provided by AWT.
Components are added to the CardLayout using unique names, and you can
switch between components using methods like next() , previous() , or
show() .
Example usage:
Example usage:
JAVA 73
Container container = new Container();
container.setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
container.add(component1, constraints);
constraints.gridx = 1;
constraints.gridy = 0;
container.add(component2, constraints);
AWT Events:
AWT provides a set of event classes and interfaces to handle user
interactions with GUI components.
To handle AWT events, you need to implement event listener interfaces and
register them with the appropriate components using methods like
addActionListener() , addMouseListener() , or addKeyListener() .
Example usage:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Handle button click event
}
});
These layout managers and event handling mechanisms in AWT allow you to
create dynamic and interactive user interfaces in your Java applications.
Event Models:
In Java, there are different event models that define how events are generated,
dispatched, and handled in graphical user interfaces (GUIs). The two main event
JAVA 74
models used in Java are the AWT event model and the Swing event model. Let's
explore each of them:
The AWT (Abstract Window Toolkit) event model is the original event
model in Java.
In the AWT event model, events are generated by the operating system
and delivered to the appropriate components.
The event handling process involves three main steps: event generation,
event dispatching, and event handling.
The Swing event model is an enhanced version of the AWT event model
and is built on top of it.
The Swing event model introduces the concept of "pluggable look and
feel" (PLAF) and "lightweight" components.
JAVA 75
EventListenerList: A container class to manage Swing event
listeners.
Both event models provide a similar set of event classes and interfaces, but the
Swing event model offers more features and flexibility for GUI development.
To handle events in Java, you need to implement event listener interfaces and
register them with the appropriate components. Common event listener
interfaces include ActionListener, MouseListener, KeyListener, etc. The actual
event handling code is written within the implemented listener methods.
Example usage:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Handle button click event
}
});
textField.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
// Handle key press event
}
By understanding the event models and utilizing event listeners, you can create
interactive and responsive GUI applications in Java.
Listeners:
In Java, listeners are interfaces that define callback methods to handle specific
events. They are used in event-driven programming to capture and respond to
user actions or system events. Here are the key points about listeners:
JAVA 76
Listeners are implemented as interfaces in Java. Each listener interface
defines one or more methods that need to be implemented to handle
specific events.
Listeners follow the Observer design pattern, where the listener objects
register themselves with the event source to receive notifications when the
corresponding events occur.
When an event occurs, the event source invokes the appropriate methods
on the registered listeners, passing relevant information about the event.
Listeners decouple the event source from event handling logic, allowing for
flexible and modular design of event-driven systems.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Handle button click event
}
});
Class Listener:
JAVA 77
The term "Class Listener" refers to a design pattern where a separate class is
created to implement a listener interface. This approach provides better
modularity and separation of concerns. Instead of using anonymous inner
classes or implementing the listener interface in the same class, you create a
separate class dedicated to handling events.
Here's an example of implementing a class listener:
1. Define a listener class that implements the desired listener interface and
overrides the corresponding event handling methods.
1. Instantiate the listener class and register it with the event source.
Using class listeners allows for cleaner code organization, improved reusability,
and easier maintenance, especially when multiple components need to share
the same event handling logic.
Adapters:
In Java, adapters are classes that provide default implementations for listener
interfaces. They allow you to implement only the methods you need, rather than
having to provide empty implementations for all methods in the interface.
Adapters are useful when you want to listen to specific events and avoid writing
unnecessary code. Here are the key points about adapters:
Adapters are classes that implement a listener interface and provide default
implementations for all the methods in the interface.
The adapter class acts as a bridge between the event source and the
listener, allowing you to override only the methods you are interested in.
JAVA 78
By using adapters, you can avoid implementing all methods of the listener
interface, which can save time and reduce code clutter.
1. Define an adapter class that extends the appropriate adapter class for the
listener interface you want to use. For example, if you want to handle mouse
events, you can extend the MouseAdapter class, which provides empty
implementations for all methods in the MouseListener interface.
1. Instantiate the adapter class and register it with the event source.
Using adapters simplifies event handling code, especially when you are
interested in handling a specific subset of events provided by a listener interface.
It allows you to focus on the events that matter to you without having to
implement unnecessary methods.
1. getSource(): Returns the object that generated the event. Useful when
multiple components share the same ActionListener.
JAVA 79
Object source = event.getSource();
1. getModifiers(): Returns the modifiers associated with the event, such as Ctrl,
Shift, or Alt keys.
1. getKeyCode(): Returns the unique code for the key that triggered the event.
JAVA 80
int keyCode = event.getKeyCode();
Mouse Events:
Mouse events in Java are triggered by user interactions with the mouse, such as
clicking, moving, or scrolling. There are several types of mouse events available
in Java, including:
JAVA 81
mouseExited(MouseEvent e): Invoked when the mouse exits a
component.
JAVA 82
Window Events:
Window events are related to the state and behavior of windows, such as
opening, closing, resizing, or moving windows. In Java, you can handle window
events using the WindowListener interface. Some commonly used methods in
the WindowListener interface include:
JAVA 83
}
You can then attach the window listener to a window object using the add
WindowListener() method.
frame.addWindowListener(new MyWindowListener());
By implementing the appropriate listener interfaces and their methods, you can
respond to user interactions with the mouse and handle various window-related
events in your Java programs.
UNIT - 4
Input/Output Streams:
In Java, input and output streams are used to handle the flow of data between a
program and an external source or destination, such as files, network
connections, or standard input/output. Streams provide a convenient way to read
data from and write data to these sources or destinations. Here are the key
points about input and output streams:
Input Streams: Input streams are used to read data from a source. They
provide methods to read different types of data, such as bytes, characters, or
objects, from the source. Some commonly used input stream classes include:
JAVA 84
Example of reading from a file using FileInputStream:
Output Streams: Output streams are used to write data to a destination. They
provide methods to write different types of data to the destination. Some
commonly used output stream classes include:
Byte Streams vs. Character Streams: Byte streams are used for reading and
writing binary data, while character streams are used for reading and writing
textual data. Character streams automatically handle character encoding and
decoding, making them suitable for working with text files.
JAVA 85
e.printStackTrace();
}
These are some of the basic concepts and classes related to input and output
streams in Java. They provide a flexible and efficient way to handle data input
and output in various scenarios.
Stream Filters:
Stream filters in Java provide a way to transform data as it passes through an
input or output stream. They are used to perform operations such as
compression, encryption, or data manipulation on the data being read from or
written to a stream. Stream filters are implemented using the decorator design
pattern, where a filter class wraps around an existing stream and modifies its
behavior.
The java.io package provides several classes for stream filters, including:
JAVA 86
Data Input and Output Stream:
DataInputStream and DataOutputStream classes are used for reading and
writing primitive data types from/to a stream. They provide methods to read and
write data in a machine-independent format. These classes are particularly
useful when you need to exchange data between different platforms or systems.
These are some of the concepts and classes related to stream filters, buffered
streams, and data input/output streams in Java. They provide additional
functionalities and enhancements to the basic input/output stream operations.
Print Stream:
PrintStream is a class in Java that provides methods for printing formatted
representations of data to an output stream. It is commonly used to write text
data to the console or to a file. PrintStream extends the OutputStream class and
provides additional print and println methods for convenient printing.
JAVA 87
Example of using PrintStream to write to console:
import java.io.PrintStream;
import java.io.IOException;
import java.io.RandomAccessFile;
// Reading data
int intValue = file.readInt();
double doubleValue = file.readDouble();
JAVA 88
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example, we create a RandomAccessFile object file with the file name
"data.txt" and mode "rw" (read-write). We write an integer value and a double
value to the file using the writeInt and writeDouble methods. Then, we seek to
the beginning of the file using the seek method. Finally, we read the values back
from the file using the readInt and readDouble methods.
RandomAccessFile provides flexibility in accessing specific parts of a file,
making it useful for scenarios where you need to read or modify data at arbitrary
positions within a file.
1. JDBC Architecture:
JAVA 89
database vendor provides its own JDBC driver that you need to include
in your project.
Process the results: If executing a query, retrieve the results using the
ResultSet object and process the data as needed.
import java.sql.*;
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
1. Database-specific Drivers:
JAVA 90
MS-Access: To connect to an MS-Access database, you need to use the
JDBC-ODBC Bridge driver. This driver acts as a bridge between the
JDBC API and the ODBC API. You'll need to set up the ODBC data
source for your MS-Access database and use it in the JDBC URL.
Note: The specific details of connecting to each database may vary, so refer to
the documentation and JDBC driver documentation provided by the respective
database vendor for the exact configurations and usage.
These are some of the concepts and steps involved in using JDBC for database
connectivity in Java, including connecting to different databases such as MS-
Access, Oracle, and MS-SQL Server.
Object Serialization
Object serialization in Java refers to the process of converting an object into a
stream of bytes, which can be written to a file or transmitted over a network.
Serialization allows objects to be saved or transmitted and later deserialized
back into objects. This is useful for scenarios such as persisting object state,
sending objects over a network, or storing objects in a database.
import java.io.*;
JAVA 91
try (FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(person);
System.out.println("Object serialized successfully.");
} catch (IOException e) {
e.printStackTrace();
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
In this example, the Person class implements the Serializable interface, which
allows instances of the class to be serialized and deserialized. The Person object
is serialized by writing it to a file using ObjectOutputStream , and then it is
deserialized by reading from the file using ObjectInputStream . The deserialized
object is cast back to the Person type.
Sockets
Sockets in Java provide a way to establish communication channels between
two different programs running on the same machine or over a network. They
facilitate client-server communication by allowing data to be sent and received
JAVA 92
across network connections. Java provides the Socket and ServerSocket classes
to handle network communication using sockets.
Client Socket: The Socket class represents a client-side socket that initiates
a connection to a server. It provides methods to establish a connection, send
data to the server, and receive data from the server.
// Server code
import java.io.*;
import java.net.*;
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server: Received from client: " + inputLine);
out.println
// Client code
import java.io.*;
import java.net.*;
JAVA 93
try (Socket socket = new Socket("localhost", 1234);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.g
etInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(Syste
m.in))) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("Client: Sent to server: " + userInput);
String response = in.readLine();
System.out.println("Client: Received from server: " + response);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In this example, the server listens on port 1234 using a ServerSocket . When a
client connects, it accepts the connection and creates input and output streams
to communicate with the client. The server receives messages from the client,
prints them, and sends a response back.
The client creates a Socket object to connect to the server's IP address and port.
It also creates input and output streams to communicate with the server. The
client reads input from the user, sends it to the server, and displays the response
received from the server.
Use the ServerSocket class from the java.net package to listen for
incoming client connections.
JAVA 94
Accept client connections by calling the accept() method of the
ServerSocket class, which returns a Socket object representing the client
connection.
Spawn a new thread or use a thread pool to handle each client request
separately, allowing multiple clients to connect concurrently.
Receive and parse requests from clients by reading from the input
stream of the Socket object.
Send requests to the server by writing to the output stream of the Socket
object.
Wait for the server's response by reading from the input stream of the
Socket object.
Process the response received from the server and take appropriate
action based on the application logic.
Run both the server-side and client-side applications and verify that they
can communicate properly.
Debug any issues or errors that arise during testing, such as incorrect
data transmission or unexpected behavior.
JAVA 95
Add additional functionality to the client and server applications as
needed.
Use the ServerSocket class from the java.net package to create a server
socket that listens for incoming client connections on a specific port.
JAVA 96
Choose an appropriate port number for your server.
For each client connection, create a new thread or use a thread pool to
handle the client's requests separately.
For each client connection, create a new thread or task to handle the
client's requests.
Inside the thread or task, use the Socket object representing the client
connection to communicate with the client.
Read data from the input stream of the Socket to receive client requests.
Send responses back to the client by writing data to the output stream of
the Socket .
Provide a way to gracefully stop the server, which includes stopping new
client connections and waiting for existing client threads to finish their
JAVA 97
work before exiting.
JAVA 98
1. Define Remote Interface:
Register the remote object with the RMI registry using the rebind()
Obtain a reference to the remote object from the RMI registry using the
lookup() method of the java.rmi.Naming class.
JAVA 99
7. Handle Exceptions:
Both the remote interface and the remote object implementation should
throw java.rmi.RemoteException to handle communication-related
exceptions that may occur during remote method invocation.
8. Security Considerations:
Note: RMI has been part of the Java platform for many years, but there are
alternative technologies available today for distributed computing in Java, such
as Java Remote Method Invocation over Internet Inter-ORB Protocol (RMI-IIOP),
Java Message Service (JMS), and web services.
Java classes can define native methods, which are declared using the
native keyword and implemented in native code.
The Java Native Interface allows for passing data and invoking native
functions from Java code and vice versa.
JAVA 100
2. Write Native Code:
The native code should match the function signatures declared in the
native methods of the corresponding Java classes.
Include the necessary header files, such as jni.h , which provide the
JNI function prototypes and macros.
Create a Java class that serves as a wrapper for the native code. This
class will contain the native method declarations.
Load the native library that contains the native code using the
System.loadLibrary() method.
Use the Java javac command with the h option to generate the C/C++
header file for the Java class that contains native method declarations.
Implement the native methods in the native code file (.c or .cpp) using
the function signatures defined in the generated header file.
Use the JNI function calls to interact with Java objects, invoke Java
methods, get/set field values, and handle exceptions.
Compile the native code file (.c or .cpp) using a C/C++ compiler and
generate a shared library file (e.g., a DLL on Windows or a shared
object on Unix-like systems).
JAVA 101
Ensure that the necessary JNI library files are included during
compilation and linking.
Load the native library using the System.loadLibrary() method in the Java
code before invoking the native methods.
The JVM will load the shared library and make the native methods
available for invocation.
Run the Java application and test the functionality of the JNI-based
code.
Debug any issues that arise during execution, such as incorrect data
handling or compatibility problems between Java and native code.
JNI allows you to leverage existing native code libraries or access platform-
specific functionality from your Java applications. It provides a bridge between
Java and native code, enabling you to combine the portability of Java with the
power and
JAVA 102
Note: When working with JNI, it's important to exercise caution as it involves
direct interaction with native code, which can introduce potential security risks
and compatibility issues.
2. List Interface:
3. Set Interface:
4. Queue Interface:
5. Map Interface:
Synchronized (thread-safe).
2. Stack Class:
JAVA 103
Methods for stack operations like push, pop, and peek.
3. Hashtable Class:
Synchronized (thread-safe).
4. Enumerations:
5. Set Interface:
6. List Interface:
7. Map Interface:
8. Iterators:
These concepts and classes form the foundation for working with collections in
Java, allowing you to store, manipulate, and iterate over groups of elements
efficiently.
JAVA 104