0% found this document useful (0 votes)
17 views96 pages

Java Unit 3 PPT - Final

The document outlines the syllabus for a Java Programming course focusing on multithreading, I/O, and generic programming. It covers concepts such as multitasking, thread creation, synchronization, and inter-thread communication, along with examples and explanations of thread life cycles and priorities. Additionally, it discusses the advantages of multithreading and provides code examples to illustrate key concepts.

Uploaded by

dhakhilsk19
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)
17 views96 pages

Java Unit 3 PPT - Final

The document outlines the syllabus for a Java Programming course focusing on multithreading, I/O, and generic programming. It covers concepts such as multitasking, thread creation, synchronization, and inter-thread communication, along with examples and explanations of thread life cycles and priorities. Additionally, it discusses the advantages of multithreading and provides code examples to illustrate key concepts.

Uploaded by

dhakhilsk19
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

R.M.D.

Engineering College

24CS202

JAVA PROGRAMMING

UNIT III

MULTITHREADING, I/O AND GENERIC PROGRAMMING


SYLLABUS
Multithreaded Programming: Creating a Thread, Thread Priorities,
Synchronization, Interthread Communication
I/O: I/O Basics, Reading Console Input, Writing Console Output,
Reading and Writing Files
Generics: Introduction, Generic class, Bounded Types, Generic
Methods, Generic Interfaces, Generic Restrictions.
Multitasking

• Multitasking is a process of executing multiple tasks simultaneously.


Multitasking is when multiple processes share common processing
resources such as a CPU.
• Multitasking can be achieved in two ways:
 Process-based Multitasking (Multiprocessing)
 Thread-based Multitasking (Multithreading)
Process-based multi-tasking (Multiprocessing)

• A process is an instance of a program that is being executed by the operating system.

• Executing various process together where each process is a separate independent

operation is called process-based multi-tasking.

• Each process has a separate address in memory and switching from one process to

another requires some time for saving and loading registers and updating lists.

• A process is heavy weight and cost of communication between the process is high.
Thread-based multi-tasking (Multithreading)
• A thread is the smallest unit of a process.
• A process can have multiple threads, each executing different tasks.
• Threads share the same address space.
• A thread is light weight and cost of communication between the thread is
low.
• Executing several tasks simultaneously where each task is a separate
independent part of the same program is called Thread-based multitasking
and each independent part is called Thread.
MULTIPROCESSING

MULTITHREADING
Different between Multitasking and Multithreading
Multithreading

• The process of executing multiple threads simultaneously is known


as multithreading.

• Multithreading is a programming concept where a program (process)


is divided into two or more subprograms (process), which can be
implemented at the same time in parallel

• Each thread defines a separate path of execution.


CREATION OF THREAD
Example 2:
class Odd extends Thread class Test
class Even extends Thread
{ {
{
public void run() public static void main(String args[])
public void run()
{
{ { Output:
Even t1=new Even(); 1
for(int i=0; i<=20;i=i+2) for(int i=1; i<=19;i++) 3
Odd t2=new Odd(); 5
{ { 7
[Link](); 9
[Link](i); [Link](i); 0
[Link]();
2
} }
} 4
6
} } } 8
} 10
} 12
14
11
13
15
17
19
16
18
20
Example 2:
class Even implements Runnable class Odd implements Runnable class Test
{ { {
public void run() public void run() public static void main(String args[])

{ { Output:
{ 1
Even t1=new Even(); 3
for(int i=0; i<=20;i=i+2) for(int i=1; i<=19;i=i+2) 5
Odd t2=new Odd(); 7
{ {
Thread ob1=new Thread(t1); 9
[Link](i); [Link](i); 0
Thread ob2=new Thread(t2); 2
} } 4
[Link](); 6
} } 8
[Link](); 10
} } } 12
14
} 11
13
15
17
19
16
18
20
Advantages of Java Multithreading

• Improved Performance & CPU Utilization

• Faster Execution & Reduced Response Time

• Enhanced Responsiveness in GUI Applications

• Better Resource Sharing

• Cost-Effective Compared to Multiprocessing


LIFE CYCLE OF A THREAD
A thread can be in any of the following states:
 New

 Runnable

 Running

 Blocked

 Waiting

 Timed Waiting

 Terminated
THREAD-LIFE CYCLE
Explanation
• New: A newly created thread that has not yet started the execution. It remains
in this state until the program starts the thread using start() method.
• It is also referred to as a born thread.
• Runnable: If a thread is in this state it means that the thread is ready for
execution and waiting for the availability of the processor.

• If all threads in queue are of same priority then they are given time slots for
execution in round robin fashion.
• Running: It means that the processor has given its time to the thread for execution. A
thread keeps running until the following conditions occurs:

(a)Thread give up its control on its own and it can happen in the following situations:
• A thread gets suspended using suspend() method which can only be revived using
resume() method.

• A thread is made to sleep for a specified period of time using sleep(time)


method, where time is specified in milliseconds.
• A thread is made to wait for some event to occur using wait() method. In this case
a thread can be scheduled to run again using notify() method.

(b)A thread is pre-empted by a higher priority thread.


• Blocked: If a thread is prevented from entering into runnable state or waiting for I/O to
complete, then a thread is said to be in Blocked state. A thread in this state cannot continue its
execution until it is moved to runnable state.

• Any thread in these states does not consume any CPU cycle.
• Waiting: A thread waits indefinitely for another thread to perform a task. A thread transitions back
to the runnable state only when another thread signals the waiting thread to continue executing.

• Timed Waiting: A thread that is waiting for another thread to perform a task for a specified
interval of time. A thread in this state transitions back to the runnable state when that time interval
expires or when the event it is waiting for occurs.

• Terminated: A runnable thread enters the dead or terminated state when it successfully completes
its task or otherwise terminated due to any error or even forcefully killed.
The Main() thread
• When we run any java program, the program begins to execute its code starting from the
main method.

• Therefore, the JVM creates a thread to start executing the code present in main method.
This thread is called as main thread.

•Although the main thread is automatically created, it can be controlled by obtaining a


reference to it by calling currentThread() method.

Two important things to know about main thread are,


• It is the thread from which other threads will be produced.

• main thread must be always the last thread to finish execution.


THREAD PRIORITIES
• Thread priorities are integers which decide how one thread should be treated with respect to the others.
•Thread priority decides when to switch from one running thread to another, and the process is called context
switching.
• A thread can voluntarily release control and the highest priority thread that is ready to run is given the CPU.

• A thread can be preempted by a higher priority thread no matter what the lower priority thread is doing.
Whenever a higher priority thread wants to run it does.
Understanding Thread Priority in Java
• Java defines three priority constants in the Thread class:
Get and Set Thread Priority

• int getPriority(): [Link]() method returns priority of given


thread.

• void setPriority(int newPriority): [Link]() method changes the


priority of thread to the value new Priority.
• This method throws IllegalArgumentException if value of parameter
new Priority goes beyond minimum(1) and maximum(10) limit.
Example 1:
class Test
Thread Priority/Thread {
Methods
public static void main(String args[])
{
class Even extends Thread class Odd extends Thread Even t1=new Even();
{ Odd t2=new Odd();
{
public void run() public void run()
[Link]("Priority of Odd Thread: " + [Link]());
{ { [Link](10);
for(int i=0; i<=20;i=i+2) for(int i=1; i<=19;i++) [Link]("New priority of Odd Thread: " + [Link]());
{ {
[Link]("Name of the Even Thread:" + [Link]());
[Link](i); [Link](i); [Link]("Even Thread");
} } [Link]("New Name of the Even Thread:" + [Link]());
} }
[Link]();
} }
[Link]();
}
}
OUTPUT:
Example 2: Thread Priority
class MyThread extends Thread
{
public void run()
{
[Link]("Thread ID: " + [Link]().threadId( ));
[Link]("Thread Name: " + [Link]().getName( ));
[Link]("New Priority: " + [Link]().getPriority( ));
}
}
class Test
{
OUTPUT:
public static void main(String[] args)
{ Priority : 5
MyThread t = new MyThread(); Thread Name: Thread-0
[Link]("Thread One"); Thread ID: 21
[Link]("Priority : " + [Link]());
New Priority: 10
[Link](10);
[Link]();
}
}
class Test
Example – Thread Methods
{
class Even extends Thread class Odd extends Thread
{ public static void main(String arg[])
{ {
public void run()
{ public void run() Even t1=new Even(); Output:
2
for(int i=2; i<=20;i=i+2) { Odd t2=new Odd(); 4
{ 6
for(int i=1; i<=19;i=i+2) 8
[Link](i); [Link]();
{ 10
try 12
try [Link](i); { 14
{ 16
} [Link](); 18
sleep(1000); } 20
}
} 1
} catch(InterruptedException e) 3
catch(InterruptedException e)
{ 5
{ 7
[Link](e); [Link](e); 9
} } 11
13
[Link]();
15
} } 17
} } 19

} OUTPUT EXPLANATION:
•The even thread t1 is started first. It will keep printing even numbers with sleep for 1000 milliseconds for every iteration.
•Since, [Link]() is called, the current thread (which called [Link]()) main thread is paused and waits until t1 completes its execution.
Thread Synchronization
• There are two types of thread synchronization namely mutual exclusive
and inter- thread communication.
• Mutual Exclusive
 Synchronized method.

 Synchronized block.

 Static synchronization.

• Cooperation (Inter-thread communication in java)


1. Mutual Exclusive helps keeping threads from interfering with one another while
sharing data. This can be done by three ways in java:

 by synchronized method

 by synchronized block

 by static synchronization

Synchronized method:
• If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
• When a thread invokes a synchronized method, it automatically acquires the lock
for that object and releases it when the thread completes its task.
Example : WITHOUT SYNCHRONIZATION public void run()
class Sample {
{ [Link]();
void show() }
{ }
for(int i=0;i<5;i++) class Test
{ {
[Link]([Link]().getName() + ":" + i); public static void main(String args[])
} {
} Sample s=new Sample();
} MyThread t1=new MyThread(s);
class MyThread extends Thread MyThread t2=new MyThread(s);
{ [Link]();
Sample s; [Link](); OUTPUT
MyThread(Sample s) }
{ }
this.s=s;
}
Example: Synchronized Method public void run()
class Sample {
{ [Link]();
synchronized void show() }
{ }
for(int i=0;i<5;i++) class Test
{ {
[Link]([Link]().getName() + ":" + i); public static void main(String args[])
} {
} Sample s=new Sample();
} MyThread t1=new MyThread(s);
class MyThread extends Thread MyThread t2=new MyThread(s);
{ [Link]();
Sample s; [Link]();
MyThread(Sample s) } OUTPUT
{ }
this.s=s;
}
Synchronized Block

Syntax for synchronized block


synchronized (object reference expression)
{
//code block
}
Example: Synchronized Block public void run()
class Sample {
{ [Link]();
void show() }
{ }
synchronized (this) class Test
{ {
for(int i=0;i<5;i++) public static void main(String args[])
{ {
[Link]([Link]().getName() + ":" + i); Sample s=new Sample();
} MyThread t1=new MyThread(s);
} MyThread t2=new MyThread(s);
} [Link]();
} [Link](); OUTPUT
class MyThread extends Thread }
{ }
Sample s;
MyThread(Sample s)
{
this.s=s;
}
C

Example: Static Synchronization class Test


class Sample {
{ public static void main(String args[])
static synchronized void show() {
{ MyThread t1=new MyThread();
for(int i=0;i<5;i++) MyThread t2=new MyThread();
{ [Link]();
[Link]([Link]().getName() + ":" + i); [Link]();
} }
} }
} OUTPUT
}
class MyThread extends Thread
{
public void run()
{
[Link](); //invoking the static show()
}
}
INTER-THREAD COMMUNICATION

Definition
• Inter-Thread communication or Co-operation is defined as the
process of allowing synchronized threads to communicate with each
other.
Methods of Object class used to implement Inter-Thread
Communication

Inter-Thread Communication can be implemented by following


methods of Object class

 wait()
 notify()
 notifyAll()
• wait() Method causes current thread to release the lock and wait until
either another thread invokes the notify() method or the notifyAll()
method for this object, or a specified amount of time has elapsed.

Syntax:
public final void wait()throws InterruptedException
public final void wait(long timeout)throws InterruptedException
• notify() method wakes up a single thread that is waiting on this
object's monitor. If any threads are waiting on this object, one of them
is chosen to be awakened.
Syntax: public final void notify()

 notifyAll() wakes up all the threads that called wait() on the same object.
Syntax: public void notifyAll()
Understanding the process of inter-thread
communication

The point to point explanation of the above diagram is as


follows:
[Link] enter to acquire lock.
[Link] is acquired by on thread.
[Link] thread goes to waiting state if you call wait() method on
the object. Otherwise it releases the lock and exits.
[Link] you call notify() or notifyAll() method, thread moves to the
notified state (runnable state).
[Link] thread is available to acquire lock.
[Link] completion of the task, thread releases the lock and exits
the monitor state of the object.
Difference between wait and sleep?

wait() sleep()

The wait() method releases the lock. The sleep() method doesn't release the lock.

It is a method of Object class It is a method of Thread class

It is the non-static method It is the static method

It should be notified by notify() or notifyAll() After the specified amount of time, sleep is
methods completed.
Example for Inter-Thread Communication (Producer
Consumer Problem)

• Producer-consumer problem (also known as the bounded-buffer


problem) is a classic example of a multi-process synchronization
problem.

• The problem describes two processes, the producer and the


consumer, which share a common, fixed-size buffer used as a queue.
• The producer’s job is to generate data, put it into the buffer, and
start again
• At the same time, the consumer is consuming the data (i.e.
removing it from the buffer), one piece at a time.

While implementing, the following two


conditions should be satisfied:

 Producer should not try to add data


into the buffer when it is full
 Consumer should not try to remove
data from an empty buffer
PROGRAM FOR PRODUCER CONSUMER PROBLEM IMPLEMENTATION
class Buffer synchronized void get()
{ {
int n; try
boolean available=false; {
synchronized void put(int n) while(available==false) //buffer is empty
{ {
try wait();
{ }
while(available==true) // buffer has data }
{ catch(InterruptedException e)
wait(); {
} [Link](e);
} }
catch(InterruptedException e)
{ // Consume the data from the buffer
[Link](e); [Link]("Got : " + n);
} available=false;
// Produce the data in the buffer notify();
this.n=n; }
[Link]("Put : " + n); }
available=true;
notify();
}
class Producer extends Thread class Consumer extends Thread class Test
{ { {
Buffer b; Buffer b; public static void main(String args[])
Producer(Buffer b) Consumer(Buffer b) {
{ { Buffer b=new Buffer();
this.b=b; this.b=b; Producer p=new Producer(b);
} } Consumer c=new Consumer(b);
public void run() public void run() [Link]();
{ { [Link]();
int i=1; int i=1; }
while(i<=3) while(i<=3) }
{ { OUTPUT:
[Link](i++); [Link]();
} i++;
} }
} }
}
Note:
if available = false (indicates buffer empty)
•Producer executes put(i)
•Consumer’s get() waits till it is notified by the producer that the data is available in the buffer.
if available = true (indicates buffer full)
•Consumer executes get()
•Producer’s put() waits till it is notified by the consumer that the data in the buffer is consumed.
INPUT/ OUTPUT BASICS
• Java I/O (Input and Output) is used to process the input and produce the output.
• Java uses the concept of a stream to make I/O operation fast.

• The [Link] package contains all the classes required for input and output operations.
Stream
• A stream can be defined as a sequence of data.
There are two kinds of Streams

[Link] − The InputStream is used to read data from a source.

[Link] − The OutputStream is used for writing data to a destination.


Hierarchy of Java Classes to deal with Input and Output Streams
Byte Streams
• Java byte streams are used to
perform input and output of 8-bit
bytes. Though there are many
classes related to byte streams
but the most frequently used
classes are,

• FileInputStream

• FileOutputStream.
Some important Byte Stream Methods

Class Method Description


FileInputStream int read() Reads one byte at a time, returns -1 if the end of the file is
reached.
FileInputStream int read(byte[] b) Reads bytes into an array.
FileOutputStream void write(int b) Writes a single byte.
FileOutputStream void write(byte[] b) Writes an array of bytes.

void close(): Closes the stream and releases resources.


Character Streams
• Java Byte streams are used to perform input and output

of 8-bit bytes, whereas Java Character streams are

used to perform input and output for 16-bit

unicode.

• Though there are many classes related to character

streams but the most frequently used classes are,

FileReader and FileWriter. Though internally

FileReader uses FileInputStream and FileWriter uses

FileOutputStream but here the major difference is that

FileReader reads two bytes at a time and FileWriter

writes two bytes at a time.


Some important Character Stream Methods
Class Method Description
FileReader int read() Reads a single character at a time, returns -1 if the end of
the file is reached.
FileReader int read(char[] cbuf) Reads characters into an array.
FileWriter void write(int c) Writes a single character.
BufferedReader String readLine() Reads a full line of text.
BufferedWriter void write(String str) Writes a string.

void close(): Closes the stream and releases resources.


Reading and Writing Files
COPY FROM ONE FILE TO ANOTHER USING
BYTESTREAM CLASSES
finally
import [Link].*; { Output:
class Test try
{ { [Link]
if (in != null) HELLO WORLD
public static void main(String args[])
{
{ [Link](); [Link]
FileInputStream in = null; } HELLO WORLD
FileOutputStream out = null; if (out != null)
{
try
[Link]();
{ }
in = new FileInputStream("[Link]"); }
out = new FileOutputStream("[Link]");
catch (IOException e)
int c;
{
while ((c = [Link]()) != -1) [Link](e);
{ }
[Link](c); } //end of finally
}
}
}
}
catch (IOException e)
{
[Link](e);
}
PRINT THE FILE CONTENTS TO CONSOLE USING

BYTESTREAM CLASSES finally Output:


import [Link].*; {
try [Link]
class Test
{ HELLO WORLD
{ if (in != null)
public static void main(String args[]) { Console
{ [Link](); HELLO WORLD
FileInputStream in = null; }
}
try catch (IOException e)
{ {
in = new FileInputStream("[Link]"); [Link](e);
int c; }
} //end of finally
while ((c = [Link]()) != -1)
}
{ }
[Link](char(c));
}
}
catch (IOException e)
{
[Link](e);
}
COPY FROM ONE FILE TO ANOTHER USING
CHARACTER STREAM CLASSES
import [Link].*; finally Output:
class Test {
try [Link]
{ { HELLO WORLD
public static void main(String args[]) if (in != null)
{ { [Link]
FileReader in = null; [Link](); HELLO WORLD
}
FileWriter out = null;
if (out != null)
try {
{ [Link]();
in = new FileReader("[Link]"); }
out = new FileWriter("[Link]"); }
catch (IOException e)
int c;
{
while ((c = [Link]()) != -1) [Link](e);
{ }
[Link](c); } //end of finally
}
}
}
}
catch (IOException e)
{
[Link](e);
}
PRINT THE FILE CONTENTS ON CONSOLE USING
finally Output:
CHARACTER STREAM CLASSES
{
import [Link].*; try [Link]
class Test { HELLO WORLD
{ if (in != null)
{ Console
public static void main(String args[])
[Link](); HELLO WORLD
{ }
FileReader in = null; }
try catch (IOException e)
{
{
[Link](e);
in = new FileReader("[Link]"); }
int c; } //end of finally
while ((c = [Link]()) != -1) }
{ }
[Link](char(c));
}
}
catch (IOException e)
{
[Link](e);
}
Standard Streams
• All the programming languages provide support for standard I/O
where the user's program can take input from a keyboard and then
produce an output on the computer screen.

• In Java, 3 streams are created for us automatically with the console.

1)[Link]: standard output stream

2)[Link]: standard input stream

3)[Link]: standard error stream


Example

[Link]("simple message");
int i=[Link]();//returns ASCII code of 1st character
[Link]((char)i);//will print the character
[Link]("error message");
Reading and Writing Console
Reading Console Input
The preferred method of reading console input is to use a character-oriented
stream.
There are three different ways for reading input from the user in the command
line environment(console).
[Link] BufferedReader Class
[Link] Scanner Class
[Link] Console Class
[Link] Buffered Reader Class
• In Java, console input is accomplished by reading from [Link]. To obtain a
character based stream that is attached to the console, wrap [Link] in a
BufferedReader object.

• BufferedReader supports a buffered input stream. Its most commonly used


constructor is shown here:
BufferedReader(Reader inputReader)
• Here, inputReader is the stream that is linked to the instance of BufferedReader that is
being created. Reader is an abstract class. One of its concrete subclasses is
InputStreamReader, which converts bytes to characters.

• To obtain an InputStreamReader object that is linked to [Link], use the following


constructor.

InputStreamReader(InputStream inputStream)

• Because [Link] refers to an object of type InputStream, it can be used for inputStream.
Putting it all together, the following line of code creates a BufferedReader that is
connected to the keyboard:

BufferedReader br = new BufferedReader(new InputStreamReader([Link]));


Most important methods of BufferedReader Class

Method Description

int read() It is used for reading a single character.

int read(char[] cbuf, int off, int len) It is used for reading characters into a portion of an

array.

String readLine() It is used for reading a line of text.

void close() It closes the input stream and releases any of the

system resources associated with the stream.


Input Computer
Output Computer
2. Using Scanner Class
• This is probably the most preferred method to take input. The main purpose of the Scanner class is
to parse primitive types and strings using regular expressions, however it is also can be used to
read input from the user in the command line.
Advantages:
• Convenient methods for parsing primitives (nextInt(), nextFloat(), …) from
the tokenized input.
• Regular expressions can be used to find tokens.
Example
// Java program to demonstrate working of Scanner in Java

import [Link].*;

class Test
{
public static void main(String args[])
{

// Using Scanner for Getting Input from User

Scanner in = new Scanner([Link]);

String s = [Link]();
[Link]("You entered string: "+s);
int a = [Link]();
[Link]("You entered integer: "+a);
float b = [Link]();
[Link]("You entered float: "+b);
}
}

Input Computer 12 14.3


Output
You entered string: Computer

You entered integer: 12


You entered float: 14.3
3. Using Console Class
It is a preferred way for reading user’s input from the command line. In addition, it can be used for
reading password-like input without choosing the characters entered by the user; the format string
syntax can also be used (like [Link]()).
Most important methods of Console Class

Method Description

String readLine() It is used to read a single line of text from the

console.

char[] readPassword() It is used to read password that is not being

displayed on the console.

void flush() It is used to flushes the console.


• Reading password without choosing the entered characters.
• Reading methods are synchronized.
• Format string syntax can be used.
• Drawback:
• Does not work in non-interactive environment (such as in an IDE).

Example
class Test
{
public static void main(String[] args) Input Computer
{ Output Computer
// Using Console to input data from user
Console con= [Link]();
String name = [Link]();
[Link](name);
}
}
Writing Console Output
• Console output is most easily accomplished with print() and println() methods. These methods are
defined by the class PrintStream which is the type of object referenced by [Link].

• Even though [Link] is a byte stream, using it for a simple program output is still acceptable.

• Because the PrintStream is an output stream derived from the OutputStream, it also implements
the low-level method write(). Thus, write() can be used to write to the console.

• The simplest form of write() defined by the PrintStream is shown below :


• void write(int byteval)

• This method writes the byte specified by byteval. Although byteval is declared as an integer, only
the low-order eight bits are written.
Example
Example 1:
Example 2:

class WriteConsoleOutput
{
public static void main(String arg[])
{
int y;
y=’X’
[Link](y);
}
}

Output:
X

You will not often use write() to perform console


output (although doing so might be useful in some
situations) because print() and println() are
substantially easier to use.
Generic Programming
• Generic programming allows us to create classes, methods, and interfaces that work with

different data types while ensuring type safety and code reusability.

Advantages

The main advantages of Java generics

• Type Safety – Ensures type correctness at compile time.

• Code Reusability – The same class/method can be used for multiple data types.

• Eliminates Type Casting – No need for explicit type casting.

• Compile-time Checking – Errors are caught at compile time rather than at runtime
Generic class
• A generic class is a class with one or more type variables.
• Generics means parameterized types. It enables to create classes, interfaces, and methods in which
the type of data upon which they operate is specified as a parameter.
• Class, interface, or method that operates on a parameterized type is called generic, as in generic
class or generic method.
Syntax for declaring a generic class:
class class-name<type-param-list >
{ // …
Syntax for declaring a reference to a generic class:
class-name<type-arg-list > var-name =new class-name<type-arg-list >(cons-arg- list);
}
A Generic Class with One Type Parameter
Example:

Generic class with one Type Parameter class Test

{
class GenericClass<T>
{ public static void main(String[] args)
T data;
{
GenericClass(T data) GenericClass<String> ob1 = new GenericClass<String>(“Hari”);
{
[Link] = data; GenericClass<Integer> ob2 = new GenericClass<Integer>(100);
}
void display() [Link]();
{ [Link]();
[Link]("Value =" + data);
} }
}
}
Output:

Value is : Hari

Value is: 100


A Generic Class with Two Type Parameters
Example:
class Test
Generic class with two Type Parameter
{
class GenericClass<T1,T2> public static void main(String[] args)
{
T1 data1; {
T2 data2;
GenericClass<Integer,String> ob1 = new GenericClass<Integer,String>(100,"Hari");

GenericClass(T1 data1, T2 data2) GenericClass<String, Double> ob2 = new GenericClass<String, Double>("CSE",95.5);


{
this.data1 = data1; [Link]();
this.data2 = data2; [Link]();
}
}
void display()
{ }
[Link]("Values are : " + data1 + "," + data2); Output:
}
} Values are : 100,Hari

Values are : CSE,95.5


Generic methods
• Methods inside a generic class can make use of a class’ type parameter and are, therefore,
automatically generic relative to the type parameter.
• However, it is possible to declare a generic method that uses one or more type parameters of its
own.
• The scope of arguments is limited to the method where it is declared. It allows static as well as
non-static methods.
Syntax for a generic method:
<type-parameter> return_type method_name (parameters)
{
...
}
Example : Print an array of different type using a single Generic method
class GenericMethod
{ OUTPUT:
public static <T> void printarray(T[] arr) Displaying Integers
{ 1
for (T i : arr) 2
{ 3
[Link](i); 4
} Displaying Double numbers
} 11.1
} 22.2
class Test 33.3
{
public static void main(String[] args)
{
Integer[] arr1 = {1, 2, 3, 4};
Double[] arr2 = {11.1, 22.2, 33.3};
[Link]("Displaying Integers");
[Link](arr1);
[Link]("Displaying Double numbers");
[Link](arr2);
}
}
Bounded Types

• In Java Generics it is possible to set the restriction on the type that will be allowed to pass to a type-
parameter. This is done with the help of extends keyword when specifying the type parameter.
< T extends Number >
• Here we have taken Number class, it can be any wrapper class name. This specifies that T can be only be replaced
by Number class data itself or any of its subclass.
Example1 : Print an array of different type of numbers (using bounded types in Generic method)
class GenericMethod
{ OUTPUT:
public static <T extends Number> void printarray(T[] arr) Displaying Integers
{ 1
for (T i : arr) 2
{ 3
[Link](i); 4
} Displaying Double numbers
} 11.1
} 22.2
class Test 33.3
{
public static void main(String[] args)
Note:
{
Integer[] arr1 = {1, 2, 3, 4};
When we pass a Character Array or a String Array to
Double[] arr2 = {11.1, 22.2, 33.3};
the printarray() method, it shows compilation error
[Link]("Displaying Integers");
as T is bounded to only the Number datatypes.
[Link](arr1);
[Link]("Displaying Double numbers");
[Link](arr2);
}
}
Example 2: Find the square of a number class Test
(Using bounded types in Generic Class) {

public static void main(String[] args)


// A Generic class with bounded type parameter
{
class Square<T extends Number> Square<Integer> ob1 = new Square<Integer>(5);
{
T num; Square<Double> ob2 = new Square<Double>(3.5);
Square(T num)
{
[Link] = num; [Link]("Square of the number: " + [Link]());
}
[Link]("Square of the number: " + [Link]());
double calculate() }
{
return [Link]() * [Link](); }
}
} OUTPUT:
Square of the number: 25.0
Square of the number: 12.25
Example 3: Find the average of the array elements (Using bounded types in Generic Class)

class Average<T extends Number> class Test


{ {
T[] arr; public static void main(String[] args)
{
Average(T[] arr) Integer arr1[] = { 1, 2, 3, 4, 5 };
{
[Link]= arr; Double arr2[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
}

double calculate() Average<Integer> ob1 = new Average<Integer>(arr1);


{ Average<Double> ob2 = new Average<Double>(arr2);
double sum = 0.0;
int len=[Link];
for(int i=0; i < len; i++) [Link]("Average of integers: " + [Link]());
{
sum += arr[i].doubleValue(); [Link]("Average of double numbers: " + [Link]());
} }
return sum / len; } OUTPUT:
} Average of integers: 3.0
}
Average of double numbers: 3.3
Generic Interface
•A generic interface in Java allows us to define an interface with type parameters.
•The generic interface can be implemented by different classes using different data types. It helps in writing flexible
and reusable code.
Program: class Test

interface GenericInterface<T> {
{ public static void main(String[] args)
T getdata();
} {
GenericClass<String> obj = new GenericClass<>(“Hello");
class GenericClass<T> implements GenericInterface<T>
{ [Link]([Link]());
T data; }
GenericClass(T data)
{ }
[Link] = data;
} Output:
public T getdata() Hello
{
return data;
}
}
Generic Restrictions

• Restrictions on Type Parameter


• Restrictions on Static Members
• Restrictions on Arrays
• Restrictions on Exceptions
Restrictions on Type Parameter
• Type Parameters can’t Be Instantiated
• It is not possible to create an instance of a type parameter.
For example, consider this class:
class Gen<T>
{
T ob; Gen()
{
ob = new T(); // Illegal!!!
}
}
Here, it is illegal to attempt to create an instance of T. The reason is since T does not exist at run time, how the
compiler doesn’t know what type of object to create.
Restrictions on Static Members
•No static member can use a type parameter declared by the enclosing class.

For example, consider this class:


class Wrong<T>

static T ob; // Wrong, no static variables of type T.

static T getob() // Wrong, no static method can use T.

return ob;

Although we can’t declare static members that use a type parameter declared by the enclosing class, we can declare static

generic methods, which define their own type parameters.


Restrictions on Arrays
There are two important generics restrictions that apply to arrays.
1. First, you cannot instantiate an array whose element type is a type parameter.
2. Second, you cannot create an array of type-specific generic references.
The following short program shows both situations:
class Gen<T extends Number>
{
T ob;
T vals[]; // OK
Gen(T o, T[] nums)
{
ob = o;
// vals = new T[10]; // cannot instantiate an array whose element type is a type parameter.
vals = nums; // OK to assign reference to existing array
}
}
class GenArrays
{
public static void main(String args[])
{
Integer n[] = { 1, 2, 3, 4, 5 };
Gen<Integer> ob = new Gen<Integer>(50, n);
// Cannot create an array of type-specific generic references.
// Gen<Integer> gens[] = new Gen<Integer>[10]; // Wrong!
Gen<?> gens[] = new Gen<?>[10]; // OK
}
}
Restrictions on Exception
• A generic class cannot extend Throwable.
• This means that you cannot create generic exception classes.

General Restrictions:
Java Runtime Only Recognizes Raw Types, Not Generic Parameters
• Java's virtual machine does not keep track of generic type information at runtime.
• So, you cannot check if an object is an instance of a generic type using instanceof, and if you try to cast to a
generic type, you will get a warning.

You might also like