0% found this document useful (0 votes)
13 views35 pages

Java Unit-3

Uploaded by

23wj1a05m1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
13 views35 pages

Java Unit-3

Uploaded by

23wj1a05m1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 35

UNIT-3

Exception Handling

An exception is an abnormal condition that arises in a code sequence at


run time.

In other words, an exception is a run-time error.

In computer languages that do not support exception handling, errors must


be checked and handled manually—typically through the use of error
codes, and so on.

Java’s exception handling avoids these problems and, in the process,


brings run-time error management into the object-oriented world.

Exception-Handling Fundamentals

When an exceptional condition arises, an object representing that


exception is created and thrown in the method that caused the error.

That method may choose to handle the exception itself, or pass it on.

Either way, at some point, the exception is caught and processed.

Exceptions can be generated by the Java run-time system, or they


can be manually generated by your code.

Java exception handling is managed via five keywords:


try, catch, throw,
throws, and finally.

Program statements that to monitor for exceptions are contained within a


try block.

If an exception occurs within the try block, it is thrown. Your code can
catch this
exception (using catch) and handle it in some rational manner.

System generated exceptions are automatically thrown by the Java run-


time system.

To manually throw an exception, use the keyword throw.

Any exception that is thrown out of a method must be specified as such


by a throws clause.

Any code that absolutely must be executed after a try block completes is
put in a finally block.

This is the general form of an exception-handling block:

Exception Types
All exception types are subclasses of the built-in class Throwable.
Throwable is at the top of the exception class hierarchy.

Throwable are two subclasses that partition exceptions into two distinct
branches.

One branch is headed by Exception. This class is used for exceptional


conditions that user programs should catch.

This is also the class that you will subclass to create your own custom
exception types.

There is an important subclass of Exception, called RuntimeException.

Exceptions of this type are automatically defined for the programs that
you write and include things such as division by zero and invalid array
indexing.

The other branch is topped by Error, which defines exceptions that are not
The diagram showing the exception hierarchy

Checked and Unchecked Exceptions

Java’s Built-in Exceptions:-


Inside the standard package java.lang, Java defines several exception
classes.The most general of these exceptions are subclasses of the
standard type RuntimeException. These exceptions need not be included
in any method’s throws list. In the language of Java, these are called
unchecked exceptions because the compiler does not check to see if a
method handles or throws these exceptions. The unchecked exceptions
defined in java.lang are listed in Table.
Table 10-2 lists those exceptions defined by java.lang that must be
included in a method’s throws list if that method can generate one of these
exceptions and does not handle it itself. These are called checked
exceptions. In addition to the exceptions in java.lang, Java defines several
more that relate to its other standard packages.

usage of try and catch:-


To guard against and handle a run-time error, simply enclose the code that
you want to monitor inside a try block. Immediately following the try
block, include a catch clause that specifies the exception type that you
wish to catch. To illustrate how easily this can be done, the following
program includes a try block and a catch clause that processes the
ArithmeticException generated by the division-by-zero error:

class Exc
{
public static void main(String[]args)
{
int d,a;
try
{
d=0;
a=42/d;
System.out.println("This will notbe printed");
}
catch(ArithmeticException e)
{
System.out.println("Division by zero");
}
System.out.println("after the catch block");
}
}

o/p: Division by zero.


After catch statement.

Multiple catch Statements

public class Mul


{
public static void main(String[]args)
{
try
{
int a=args.length;
System.out.println("a="+a);
int b=42/a;
int c[]={1};
c[42]=99;
}
catch(ArithmeticException e)
{
System.out.println("Divide by zero"+e);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Array index oob"+e);
}
System.out.println("after try catch block");
}
}
o/p : a=0
Divide by zerojava.lang.ArithmeticException: / by zero
after try catch block

when a=1 the output becomes

o/p a=1
Array index oobjava.lang.ArrayIndexOutOfBoundsException: 42
after try catch block

When you use multiple catch statements, it is important to remember that


exception subclasses must come before any of their superclasses. This is
because a catch statement that uses a superclass will catch exceptions of
that type plus any of its subclasses. Thus, a subclass would never be
reached if it came after its superclass. Further, in Java, unreachable code
is an error. For example, consider the following program:

public class Mul


{
public static void main(String[]args)
{
try
{
int a=0;
int b=42/a;
}
catch(Exception e)
{
System.out.println("Generic Exception ");
}
catch(ArithmeticException e)
{
System.out.println("This is never reached ");
}
System.out.println("after try catch block");
}
}

If you try to compile this program, you will receive an error message
stating that the second catch statement is unreachable because the
exception has already been caught. Since ArithmeticException is a
subclass of Exception, the first catch statement will handle all Exception-
based errors, including ArithmeticException. This means that the second
catch statement will never execute. To fix the problem, reverse the order
of the catch statements

Nested try Statements


The try statement can be nested. That is, a try statement can be inside the
block of another try. Each time a try statement is entered, the context of
that exception is pushed on the stack. If an inner try statement does not
have a catch handler for a particular exception, the stack is unwound and
the next try statement’s catch handlers are inspected for a match. This
continues until one of the catch statements succeeds, or until all of the
nested try statements are exhausted. If no catch statement matches, then
the Java run-time system will handle the exception. Here is an example
that uses nested try statements:
class Multipletry
{
public static void main(String[]args)
{
try
{
int []a={1,0,4,2};
try
{
System.out.println("before the exception");
int x=a[3]/a[1];
}
catch(ArithmeticException e)
{
System.out.println("Division by zero");
}
a[4]=10;
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("after the inner try catch block");
}
}
}
o/p: ---
before the exception
Division by zero
after the inner try catch block

another example

class Nestedtry
{
public static void main(String[]args)
{
try
{
try
{
System.out.println("before the exception");
int b=39/0;
}
catch(ArithmeticException e)
{
System.out.println("Division by zero");
}
try
{
int []a=new int[4];
a[5]=4;
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("The array index error");
}
}
catch(Exception e)
{
System.out.println("The outer exception ");
}
}
}
o/p: before the exception
Division by zero
The array index error

throw
So far, you have only been catching exceptions that are thrown by the Java
run time
system. However, it is possible for your program to throw an exception
explicitly, using the throw statement. The general form of throw is shown
here:
throw ThrowableInstance;

Here, ThrowableInstance must be an object of type Throwable or a


subclass of Throwable. There are two ways you can obtain a Throwable
object: using a parameter in a catch clause or creating one with the new
operator.

The flow of execution stops immediately after the throw statement; any
subsequent statements are not executed. The nearest enclosing try block
is inspected to see if it has a catch statement that matches the type of
exception.

If it does find a match, control is transferred to that statement. If not, then


the next enclosing try statement is inspected, and so on. If no matching
catch is found, then the default exception handler halts the program and
prints the stack trace. Here is a sample program that creates and throws an
exception. The handler
that catches the exception rethrows it to the outer handler.

Java throws Keyword


The throws keyword is used to declare the list of exception that a method
may throw during execution of program. Any method that is capable of
causing exceptions must list all the exceptions possible during its
execution, so that anyone calling that method gets a prior knowledge
about which exceptions are to be handled. A method can do so by using
the throws keyword.
Syntax:

type method_name(parameter_list) throws exception_list


{
// definition of method
}

class Test
{
static void check() throws ArithmeticException
{
System.out.println("Inside check function");
throw new ArithmeticException("demo");
}
public static void main(String args[])
{
try
{
check();
}
catch(ArithmeticException e)
{
System.out.println("caught" + e);
}
}
}

Difference between throw and throws


throw throws

throw keyword is used to throw an exception throws keyword is used to declare an exception
explicitly. possible during its execution.

throw keyword is followed by an instance of throws keyword is followed by one or more


Throwable class or one of its sub-classes. Exception class names separated by commas.

throw keyword is declared inside a method throws keyword is used with method signature
body. (method declaration).

We cannot throw multiple exceptions using We can declare multiple exceptions (separated
throw keyword. by commas) using throws keyword.

finally clause
A finally keyword is used to create a block of code that follows a try block.
A finally block of code is always executed whether an exception has
occurred or not. Using a finally block, it lets you run any cleanup type
statements that you want to execute, no matter what happens in the
protected code. A finally block appears at the end of catch block.

Class ExceptionTest
{
public static void main(String[] args)
{
int a[] = new int[2];
System.out.println("out of try");
try
{
System.out.println("Access invalid element"+ a[3]);
}
finally
{
System.out.println("finally is always executed.");
}
}
}

Multithreaded Programming
Java provides built-in support for multithreaded programming. A
multithreaded program contains two or more parts that can run
concurrently. Each part of such a program is called a thread, and each
thread defines a separate path of execution. Thus, multithreading is a
specialized form of multitasking.

There are two distinct types of multitasking: process-based and thread-


based.
A process is, in essence, a program that is executing.

process-based multitasking is the feature that allows your computer to run


two or more programs concurrently.In process-based multitasking,a
program is the smallest unit of code that can be dispatched by the
scheduler.

In a thread-based multitasking environment, the thread is the smallest unit


of dispatchable code. This means that a single program can perform two
or more tasks simultaneously.

Multitasking threads require less overhead than multitasking processes.


Processes are heavyweight tasks that require their own separate address
spaces.

Interprocess communication is expensive and limited. Threads, on the


other hand, are lighter weight.

Interthread communication is inexpensive, and context switching from


one thread to the next is lower in cost.

Multithreading enables to write efficient programs that make maximum


use of the processing power available in the system. One important way
multithreading achieves this is by keeping idle time to a minimum.

Threads exist in several states. Here is a general description. A thread can


be running. It can be ready to run as soon as it gets CPU time. A running
thread can be suspended, which temporarily halts its activity. A suspended
thread can then be resumed, allowing it to pick up where it left off. A
thread can be blocked when waiting for a resource. At any time, a thread
can be terminated, which halts its execution immediately. Once
terminated, a thread cannot be resumed.
Along with threadbased multitasking comes the need for a special type of
feature called synchronization, which allows the execution of threads to
be coordinated in certain welldefined ways. Java has a complete
subsystem devoted to synchronization,and its key features are also
described here.

The thread class and runnable interface

Java’s multithreading system is built upon the Thread class and its
companion interface, Runnable. Both are packaged in java.lang. Thread
encapsulates a thread of execution. To create a new thread, program will
either extend Thread or implement the Runnable interface.

The Thread class defines several methods that help manage threads. Here
are some of

Creating a Thread
Java defines two ways in which we can create a runnable object:
1.implement the Runnable interface. 2.Extend the Thread class

Both approaches still use the Thread class to instantiate, access, and
control the thread. The only difference is how a thread enabled class is
created.
The Runnable interface abstracts a unit of executable code. You can
construct a thread on any object that implements the Runnable interface.
Runnable defines only one method called run.
public void run()

define the code that constitutes the new thread


Once created, the new thread will not start running until you call its start(
) method,
which is declared within Thread. In essence, start( ) executes a call to run(
). The
start( ) method is shown here:
void start( )

By Extending Thread class


class Multi extends Thread // Extending thread class
{
public void run() // run() method declared
{
System.out.println("thread is running...");
}
public static void main(String args[])
{
Multi t1=new Multi(); //object initiated
t1.start(); // run() method called through start()
}
}
Output: thread is running…

By implementing Runnable interface

class Multi3 implements Runnable // Implementing Runnable interface


{
public void run()
{
System.out.println("thread is running...");
}
public static void main(String args[])
{
Multi3 m1=new Multi3(); // object initiated for class
Thread t1 =new Thread(m1); // object initiated for thread
t1.start();
}
}

Output: thread is running…


LIFE cycle of a thread
• During the life time of a thread, there are
many states it can enter.
• They include:
1. Newborn state
2. Runnable state
3. Running state
4. Blocked state
5. Dead state
LIFE cycle of a thread contd.
Newborn State:
The thread is born and is said to be in newborn state.
The thread is not yet scheduled for running.
At this state, we can do only one of the following:
• Schedule it for running using start() method.

• Kill it using stop() method.


Runnable State:
The thread is ready for execution
Waiting for the availability of the processor.
The thread has joined the queue

Running State:
• Thread is executing
• The processor has given its time to the thread for its execution.
• The thread runs until it gives up control on its own or taken over
by other threads.
Blocked State:
• A thread is said to be blocked
• It is prevented to entering into the runnable and the running state.
• This happens when the thread is suspended, sleeping, or waiting in
order to satisfy certain requirements.
• A blocked thread is considered "not runnable" but not dead and
therefore fully qualified to run again.
• This state is achieved when we Invoke suspend() or sleep() or
wait() methods.

Dead State:
• Every thread has a life cycle.
• A running thread ends its life when it has completed executing its
run( ) method. It is a natural death.
• A thread can be killed in born, or in running, or even in "not
runnable" (blocked) condition.
• It is called premature death.
• This state is achieved when we invoke stop() method or the thread
completes it execution.

Stopping and blocking


Stopping a thread:
• To stop a thread from running further, we may do so by calling its
stop() method.
• This causes a thread to stop immediately and move it to its dead
state.
• It forces the thread to stop abruptly before its completion
• It causes premature death.
• To stop a thread we use the following syntax:
thread.stop();

Blocking a Thread:
• A thread can also be temporarily suspended or blocked from
entering into the runnable and subsequently running state,
1. sleep(t) // blocked for ‘t’ milliseconds
2. suspend() // blocked until resume() method is invoked
3. wait() // blocked until notify () is invoked.

Creating Multiple Threads

class MyThread implements Runnable {


String name;
Thread t;
MyThread String thread){
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start();
}
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
}catch (InterruptedException e) {
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}
class MultiThread {
public static void main(String args[]) {
new MyThread("One");
new MyThread("Two");
new NewThread("Three");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}

Determining when a thread ends

It is often useful to know when a thread has ended. The main thread
alive until the other threads ended.In those examples, main thread
sleep longer than the child threads that it spawned. This is, of course,
hardly a satisfactory or generalizable solution!

Thread provides two means by which can determine if a thread has


ended. First, can call isAlive( ) on the thread. Its general form is
shown here:

final boolean isAlive( )


The isAlive( ) method returns true if the thread upon which it is
called is still
running. It returns false otherwise. To try isAlive( ), substitute this
version of
MoreThreads for the one shown in the preceding program:

The difference is that it uses isAlive( ) to wait for the child threads
to terminate. Another way to wait for a thread to finish is to call join(
), shown here:
final void join( ) throws InterruptedException

Additional forms of join( ) allow you to specify a maximum amount


of time that want to wait for the specified thread to terminate.

class MyRunnableClass implements Runnable{


public void run() {
for(int i = 0; i < 5 ; i++){
System.out.println(Thread.currentThread().getName() + " i
- " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnableClass(), "t1");
Thread t2 = new Thread(new MyRunnableClass(), "t2");
t1.start();
t2.start();
System.out.println("t1 Alive - " + t1.isAlive());
System.out.println("t2 Alive - " + t2.isAlive());
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 Alive - " + t1.isAlive());
System.out.println("t2 Alive - " + t2.isAlive());
System.out.println("Processing finished");
}
}

Thread priority
• Each thread is assigned a priority, which affects the order in which
it is scheduled for running.
• Java permits us to set the priority of a thread using the setPriority()
method as follows:

ThreadName.setPriority(int Number);

The intNumber is an integer value to which the thread's priority is


set. The Thread class defines several priority constants:
1. public static int MIN_PRIORITY = 1
2. public static int NORM_PRIORITY = 5
3. public static int MAX_PRIORITY = 10
• The default setting is NORM_PRIORITY. Most userlevel
processes should use NORM_PRIORITY.

public class Threadpriority extends Thread{


public void run(){
System.out.println("running thread name
s:"+Thread.currentThread().getName());
System.out.println("running
threadpriorityis:"+Thread.currentThread().getPriority());

}
public static void main(String args[]){
Threadpriority m1=new Threadpriority();
Threadpriority m2=new Threadpriority();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();

}
}
Set the priority of the threads

public class ThreadDemo extends Thread {


public void run()
{
System.out.println("Inside run method");
}

public static void main(String[] args)


{
ThreadDemo t1 = new ThreadDemo();
ThreadDemo t2 = new ThreadDemo();
System.out.println("t1 thread priority : "+ t1.getPriority());
System.out.println("t2 thread priority : " + t2.getPriority());
t1.setPriority(2);
t2.setPriority(5);
System.out.println("t1 thread priority : " + t1.getPriority());
System.out.println("t2 thread priority : " + t2.getPriority());
System.out.println("Currently Executing Thread : "+
Thread.currentThread().getName());
System.out.println("Main thread priority : "+
Thread.currentThread().getPriority());
Thread.currentThread().setPriority(10);
System.out.println( "Main thread priority : " +
Thread.currentThread().getPriority());
}
}

Java synchronization
• Generally threads use their own data and methods provided inside their
run() methods.
• But if we wish to use data and methods outside the thread’s run()
method, they may compete for the same resources and may lead to serious
problems.
• Java enables us to overcome this problem using a technique known as
Synchronization.

For ex.: One thread may try to read a record from a file while another is
still writing to the same file.

When the method declared as synchronized, Java creates a "monitor" and


hands it over to the thread that calls the method first time.

synchronized (lock-object)
{
.......... // code here is synchronized
}

Without Synchronization

class Table{
void printTable(int n){//method not synchronized
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}

}
}

class MyThread1 extends Thread{


Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}

}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
5
100
10
200
15
300
20
400
25
500

//example of java synchronized method


class Table
{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){
System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Inter thread communication

THREAD COMMUNICATION USING NOTIFY( ), WAIT( ), AND


NOTIFYALL( )

The wait( ), notify( ), and notifyAll( ) methods are part of all objects because they
are implemented by the Object class. These methods should be called only from
within a synchronized context. Here is how they are used. When a thread is
temporarily blocked from running, it calls wait( ).

This causes the thread to go to sleep and the monitor for that object to be released,
allowing another thread to use the object. At a later point, the sleeping thread is
awakened when some other thread enters the same monitor and calls notify( ), or
notifyAll( ).

class ThreadB extends Thread{


int total;
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();

synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}

System.out.println("Total is: " + b.total);


}
}
}

suspend(), resume() and stop()

class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
synchronized void deposit(int amount){
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();
}}

O/P:
going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
Thread groups:
Java thread group is implemented by java.lang.ThreadGroup class.
A ThreadGroup represents a set of threads. A thread group can also
include the other thread group. The thread group creates a tree in which
every thread group except the initial thread group has a parent.
Example
public class ThreadGroupDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
Thread t1 = new Thread(tg1, runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getName());
tg1.list();
} }
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]

Daemon Thread in Java


Daemon thread in Java is a service provider thread that provides services to the user
thread. Its life depend on the mercy of user threads i.e. when all the user threads dies,
JVM terminates this thread automatically.

There are many java daemon threads running automatically e.g. gc, finalizer etc.
public class TestDaemonThread1 extends Thread{
public void run(){
if(Thread.currentThread().isDaemon()){//checking for daemon thread
System.out.println("daemon thread work");
}
else{
System.out.println("user thread work");
}
}
public static void main(String[] args){
TestDaemonThread1 t1=new TestDaemonThread1();//creating thread
TestDaemonThread1 t2=new TestDaemonThread1();
TestDaemonThread1 t3=new TestDaemonThread1();

t1.setDaemon(true);//now t1 is daemon thread

t1.start();//starting threads
t2.start();
t3.start();
} }
O/P: daemon thread work
user thread work
user thread work

Autoboxing:
The automatic conversion of primitive data types into its equivalent
Wrapper type is known as boxing and opposite operation is known as
unboxing. This is the new feature of Java5. So java programmer doesn't
need to write the conversion code.

No need of conversion between primitives and Wrappers manually so less coding is


required.
class BoxingExample1{
public static void main(String args[]){
int a=50;
Integer a2=new Integer(a);//Boxing

Integer a3=5;//Boxing

System.out.println(a2+" "+a3);
}
}
O/P: Output:50 5

class UnboxingExample1{
public static void main(String args[]){
Integer i=new Integer(50);
int a=i;

System.out.println(a);
}
}
O/P : 50

Generics in Java:-
The Java Generics programming is introduced in J2SE 5 to deal with
type-safe objects. It makes the code stable by detecting the bugs at
compile time.

There are mainly 3 advantages of generics.


1) Type-safety: We can hold only a single type of objects in generics. It doesn?t allow
to store other objects.
2) Type casting is not required: There is no need to typecast the object.
3) Compile-Time Checking: It is checked at compile time so problem will not occur at
runtime. The good programming strategy says it is far better to handle the problem at
compile time than runtime.

import java.util.*;
class TestGenerics1{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();
list.add("rahul");
list.add("jai");
//list.add(32);//compile time error

String s=list.get(1);//type casting is not required


System.out.println("element is: "+s);

Iterator<String> itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
} } }
Output:
element is: jai
rahul
jai

You might also like