Unit 4
Unit 4
Unit 4
1.Compile-time errors
2.Run-time errors
3.Logical errors.
1.Compile-time errors:
These are syntactical errors found in the code, due to which a program fails to
compile.
For example, forgetting a semicolon at the end of the a java program, or writing a
statement without proper syntax will result in compilation-time error.
class CError{
public static void main(String args[]){
System.out.println(“Compilation Error…..”)
}
}
D:\>javac Cerror.java
CError.java:4: ';' expected
}
^
1 error
2.Run-time errors:
These are the errors which represent inefficiency of the computer system to execute
a particular statement, means computer system can not process.
For example, division by zero error occur at run-time.
class RError{
public static void main(String args[]){
int a=10,b=0;
System.out.println(“a/b: ”+(a/b));
}
}
D:\>javac RError.java
D:\>java RError
Exception in thread "main" java.lang.ArithmeticException: / by zero
at RError.main(RError.java:4)
3.Logical errors:
These errors depict flaws in the logic of the program.
The programmer might be using a wrong formula or the design of the program itself
is wrong.
Logical errors are not detected either by the java compiler or JVM.
The programmer is solely responsible for them.
Logical errors means the logic of the program is wrong and these are identified after
observing the output.
class LError{
int sum(int a,int b){
return a-b;
}
public static void main(String args[]){
LError le=new LError();
System.out.println("Sum is: "+le.sum(20,10));
}
} D:\>javac LError.java
D:\>java LError
Sum is: 10
What is an Exception?
An Exception is an abnormal situation (or) unexpected situation in the
normal flow of the program execution.
Examples
– Exit program (abort)
– Ignore exception
– Deal with exception and continue
• Print error message
• Request new data
• Retry action
Benefits of Exception Handling
9
Exception-Handling Fundamentals
10
(contd..)
Code within catch block catch the exception and handle it.
11
(contd..)
To manually throw an exception, use the keyword throw
NullPointerExceptio
NullPointerExceptio
RuntimeExceptio
RuntimeExceptio nn
nn
IndexOutOfBoundsExceptio
IndexOutOfBoundsExceptio
… nn
Objec
Objec Throwabl
Throwabl
tt ee
NoSuchElementExceptio
NoSuchElementExceptio
nn
VirtualMachineError
VirtualMachineError
Ex:
Ex: Stack
Stack overflow
overflow
Erro
Erro …
rr
Checke
Checke
dd
…
Unchecke
Unchecke
dd
java.lang.Object
Exception Types
Throwable
Exception Error
Built –in Exception User-defined Exception
Un Checked Exceptions
(java.lang.RuntimeException)
Exception
Since java.lang is implicitly imported into all Java programs, most exceptions
derived from RuntimeException are automatically available.
These are called unchecked exceptions because the compiler does not check
to see if a method handles or throws these exceptions.
try{
// block of code to monitor for errors
}
catch (ExceptionType1 exOb) {
// exception handler for ExceptionType1
}
catch (ExceptionType2 exOb) {
// exception handler for ExceptionType2
}
class Exc1 {
static void subroutine() {
int d = 0;
int a = 10 / d;
java.lang.ArithmeticException: / by zero }
at Exc1.subroutine(Exc1.java:4) public static void main(String
at Exc1.main(Exc1.java:7) args[]) {
Exc1.subroutine();
}
}
• When the Java run-time system detects the attempt to divide by zero, it
constructs a new exception object and then throws this exception.
• This causes the execution of Exc0 to stop, because once an exception has
been thrown, it must be caught by an exception handler and dealt with
immediately.
To illustrate how easily this can be done, the following program includes
a try block and a catch clause which processes the
ArithmeticException generated by the division-by-zero error:
class Exc2 {
public static void main(String args[]) {
int d, a;
try { // monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be
printed.");
}
catch (ArithmeticException e) { // catch divide-by-
zero error
System.out.println("Division by zero.");
}
System.out.println("After catch statement.");
}
} Output:
Division by
zero.
A try and its catch statement form a unit. System.out.println("b: "
+ b);
// Handle an exception and move on.
System.out.println("c: "
import java.util.Random; + c);
class HandleError { System.out.println("b/c:
" + (b/c));
public static void main(String args[]) {
System.out.println("a: "
int a=0, b=0, c=0; + a);Division by zero. Division by zero.
b: 635388915 b: -1025942228
Random r = new Random(); }
c: 2049977621 c: 1479649026
for(int i=0; i<5; i++) { b/c: 0 } b/c: 0
} a: 0 a: 0
try {
b = r.nextInt(); b: 1508383197 b: 1864084761
c: -1038643924 c: 29995622
c = r.nextInt(); b/c: -1 b/c: 62
a: -12345 a: 199
a = 12345 / (b/c);
} Division by zero.
b: -431455168
catch c: 606293637
(ArithmeticException e) { b/c: 0
a: 0
System.out.println("Division by
zero.");
a = 0; // set a to
zero and continue
• The scope of the catch clause is restricted to those statements specified by the
immediately preceding try statement.
• You can display this description in a println( ) statement by simply passing the
exception as an argument.
• For example, the catch block in the preceding program can be rewritten like
this:
catch (ArithmeticException e) {
System.out.println("Exception: " + e);
a = 0; // set a to zero and continue
}
When this version is substituted in the program, and the program is run, each
divide-by-zero error displays the following message:
Exception: java.lang.ArithmeticException: / by
zero
Multiple catch Clauses
• When an exception is thrown, each catch statement is inspected in
order, and the first one whose type matches that of the exception is
executed.
• After one catch statement executes, the others are bypassed, and
execution continues after the try/catch block.
class MultiCatch { // Demonstrate multiple catch statements.
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 0: " + e);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks.");
} C:\>java MultiCatch
} a=0
Divide by 0: java.lang.ArithmeticException: / by zero
After try/catch blocks.
C:\>java MultiCatch TestArg
a=1
Array index oob: java.lang.ArrayIndexOutOfBoundsException
After try/catch blocks.
/* This program contains an error. A subclass must come before its super class in
a series of catch statements. If not, unreachable code will be created and a compile-
time error will result. */
class SuperSubCatch {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
}
catch(Exception e) {
System.out.println("Generic Exception catch.");
}
/* This catch is never reached because ArithmeticException is a subclass of Exception. */
catch(ArithmeticException e){ //
ERROR - unreachable
System.out.println("This is never reached.");
}
}
}
Nested try Statements
• The try statement can be nested.
• That is, a try statement can be inside the block of another try.
• 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.
class NestTry { // An example of nested try statements.
public static void main(String args[]) {
try {
C:\>java NestTry
int a = args.length; Divide by 0: java.lang.ArithmeticException: / by zero
int b = 42 / a;
System.out.println("aC:\>java
= " + a);
NestTry One
try { // nested trya =block
1
if(a==1) a =Divide by 0: java.lang.ArithmeticException: / by zero
a/(a-a);
if(a==2) { C:\>java NestTry One Two
inta c[]
= 2 = { 1 };
c[42]
Array= index
99; out-of-bounds:
} java.lang.ArrayIndexOutOfBoundsException
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out-of-
bounds: " + e);
}
}
catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
}
}
}
throw
Dealt with catching an exceptions that are thrown by the Java run-time system.
Program can also 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.
It finds the catch which is suitable, 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.
class ThrowDemo { // Demonstrate throw.
static void demoproc() {
try {
throw new NullPointerException();
}
catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
}
}
public static void main(String args[]) {
try {
demoproc();
}
catch(NullPointerException e) {
System.out.println("Recaught: " + e);
}
}
}
throws
If a method is capable of causing an exception that it does not handle, then it
must specify some behavior so that callers of the method can guard themselves
against that exception.
A throws clause lists the types of exceptions that a method might throw.
All other exceptions that a method can throw must be declared in the throws
clause.
This can be useful for closing file handles and freeing up any other resources.
However, each try statement requires at least one catch or a finally clause.
Any time a method is about to return to the caller from inside a try/catch
block, via an uncaught exception or an explicit return statement, the finally
clause is also executed just before the method returns.
class FinallyDemo { static void procC() {
static void procA() { try {
try {
System.out.println("inside System.out.println("inside procC");
procA"); }
throw new finally {
RuntimeException("demo");
} System.out.println("procC's finally");
finally { }
System.out.println("procA's }
finally"); public static void main(String args[]) {
} try {
} procA();
static void procB() { }
try { catch (Exception e) {
System.out.println("inside inside procA
System.out.println("Exception
procB"); caught"); procA’s finally
return; } Exception caught
} procB(); inside procB
finally { procC();
procB’s finally
System.out.println("procB's } inside procC
finally");
} } procC’s finally
}
Java’s Built-in Exceptions
Inside java.lang package, Java defines several exception classes.
Since java.lang is implicitly imported into all Java programs, most exceptions
derived from RuntimeException are automatically available.
These are called unchecked exceptions because the compiler does not check
to see if a method handles or throws these exceptions.
The Exception class does not define any methods of its own. It does, of
course, inherit those methods provided by Throwable.
Thus, all exceptions, including those that you create, have the methods
defined by Throwable available to them.
You may also wish to override one or more of these methods in exception
classes that you create.
Every user defined Exception last word must be Exception since every
exception is a class.
E.g., AgeException
MarksOutOfBoundsException
This means we are wasting a lot of processor time and processor has to
sit idle without any job for a long time.
In this, most of the processor time is getting engaged and it is not sitting
idle.
Uses:
Each part of such a program is called a thread, and each thread defines a
separate path of execution.
New State:
After the creations of Thread instance the thread is in this state but
before the start() method invocation. At this point, the thread is
considered not alive.
A thread first enters runnable state after the invoking of start() method
but a thread can return to this state after either running, waiting,
sleeping or coming back from blocked state also.
There are several ways to enter in Runnable state but there is only one
way to enter in Running state: the scheduler select a thread from
runnable pool.
Blocked State:
A thread can enter in this state because of waiting the resources that are
hold by another thread.
Dead State:
A thread can be considered dead when its run() method completes.
If any thread comes on this state that means it cannot ever run again.
t( )
r
sta Schedular dispatch
Thread Life Cycle (Contd..)
Starting from the birth of a thread, till its death, a thread exists in different
states which are collectively called “Thread Life Cycle”.
A thread goes into runnable state when start() method is applied on it.
That is void start() method is used to call the public void run() method.
From runnable state, a thread may get into not-runnable state, when sleep()
or wait() or suspend() methods act on it.
notify() and resume() methods are used to restart waiting and suspended
threads respectively.
Thread Life Cycle (Contd..)
Where group is the thread group, target is the object whose run method is
called.
NOTE 2:A thread’s priority is used to decide when to switch from one running
thread to the next. This is called a context switch.
A thread can voluntarily relinquish control.
A thread can be preempted by a higher-priority thread.
When a Java program starts up, one thread begins running immediately.
This is usually called the main thread of your program, because it is the
one that is executed when your program begins.
group.add(this);
start0();
x }
private native void start0();
Thread t=Thread.currentThread();
System.out.println(“Main Thread is:
"+t.getName());
Calls t1.join()
Main thread
resumes
// Using join() to wait for threads to finish.
class DemoJoin {
class NewThread implements Runnable {
public static void main(String args[]) {
String name; // name of thread
Thread t; NewThread ob1 = new
NewThread("One");
NewThread(String threadname) {
NewThread ob2 = new
name = threadname; NewThread("Two");
t = new Thread(this, name); NewThread ob3 = new
NewThread("Three");
System.out.println("New thread:
" + t);
System.out.println("Thread One is alive: "+
t.start(); // Start the thread
ob1.t.isAlive());
} System.out.println("Thread Two is alive: "+
ob2.t.isAlive());
// This is the entry point for thread. System.out.println("Thread Three is alive: "+ ob3.t. isAlive());
public void run() {
try { // wait for threads to finish
try {
for(int i = 5; i > 0; i--) System.out.println("Waiting for threads
{ to finish.");
ob1.t.join();
System.out.println(name + ": " + i);
ob2.t.join();
Thread.sleep(1000);
} ob3.t.join();
}
}
catch (InterruptedException e) { catch (InterruptedException e) {
System.out.println(name + " System.out.println("Main
interrupted."); thread Interrupted");
}
}
System.out.println(name + " System.out.println("Thread One is alive: "+
exiting."); ob1.t.isAlive());
}
Synchronization
When two or more threads need access to a shared resource, they need some way to
ensure that the resource will be used by only one thread at a time.
When a thread enters into the monitor all other threads attempting to enter
the locked monitor will be suspended until the first thread exits the
monitor.
Ex:-
Check availability
Reserve seat
Check
availability
Check availability
Reserve seat
Reserve seat
Seat reservation
database
80
//Without Synchronization class Caller extends Thread{
class Callme{ Callme target;
String msg;
void call(String msg){
Thread t;
System.out.print("["+msg);
Caller(Callme tar,String str){
try { target=tar;
msg=str;
Thread.sleep(1000); t = new Thread(this);
} t.start();
catch(InterruptedException }
e) { public void run(){
target.call(msg);
System.out.println("Interrupted"); }
}
}
class SyncDemo{
System.out.println("]"); public static void main(String
} [One[Three[Two] args[]){
} ] Callme cr=new
] Callme();
Caller t1=new
Caller(cr,"One");
Caller t2=new
Caller(cr,"Two");
//Synchronization Example class Caller extends Thread{
class Callme{ Callme target;
String msg;
public synchronized void call(String msg){
Thread t;
System.out.print("["+msg); Caller(Callme tar,String str){
try { target=tar;
Thread.sleep(1000); msg=str;
} t = new Thread(this);
catch(InterruptedException e) t.start();
{ }
public void run(){
System.out.println("Interrupted"); target.call(msg);
}
}
}
System.out.println("]");
class SyncDemo{
} public static void main(String
} [One] args[]){
[Three] Callme cr=new
[Two] Callme();
Caller t1=new
Caller(cr,"One");
Caller t2=new
Caller(cr,"Two");
class BlockSyn implements Runnable { /Example for block level
synchronization
public void run(){ first
display(); second
} i value is:0
public void display(){ i value is:1
System.out.println(Thread.currentThread().getName()); i value is:2
synchronized(this){ i value is:0
for(int i=0;i<3;i++){ i value is:1
try{ i value is:2
Thread.sleep(1000);
System.out.println("i value is:"+i);
} public static void main(String args[]){
catch(Exception e){ BlockSyn s= new BlockSyn();
System.out.println(e);Thread t1= new
} Thread(s,"first");
} Thread t2= new
Thread(s,"second");
} t1.start();
} t2.start();