Core Java
Lectures 12-18
- The compiler compiles the java file to create class file of bytecode. Verifier provides the safety that the language cannot provide. After verification depending on whether virtual machine is interpreter or compiler it will execute the code on machine. JIT compiler performs the optimisation.
- There are organised into modules called classes.Everything has to written inside a class. Each class have data in variables and subroutines called methods.
public static void main (String[] args) {
System.out.println(“Echo !!!”);
} }
- Entry point is a main module. It must be
- public : anyone can access.
- static: can be called without creating object
- void: by default, does not have to return anything
- String is a built-in class.
- args: arguments, argc i.e. count is part of args as attribute length is attached to it by java.
- Java follows following hierarchy : Package -> Class -> Method. The notation
- method, (within a class)
- Class/object.method (outside the class) or
- package.class/object.method (outside the package) is usually how to invoke a method.
- e.g. System.out.println(); where
- System: Class
- out : Static var.
- println() : method
- Syntax is similar to C: braces for blocks, semicolon after each statement.
- In C everything is based on libraries while in java everything is based on classes.
- Steps to execute a java program
- Edit a java program in any editor and save as Echo.java. Name of file can be anything, may not be same as name of a class.
- compile using $ javac Echo.java command. It creats a file named echo.class if the compilation succeeds. A java file can have more than one class definitions, it generates one ‘class’ file per java class
- Class file is run using Java interpreter (JVM) $ java Echo
import java.lang.* //or java.lang.Math; by default
import java.util.*;
Import java.util.Random
class Abc {
int ia; // instance var./data members
double da;
final int fia = 100;
static int isa; // Class (Static) data members
Abc(){...}; //set of constructors
Abc(int i) { ... }
Abc(Abc oa) { .... }
public void Abc(){ .... } // instance Methods
public static void SAbc(){ ..} // Static Methods
}
- Java does not have preprocessor directives as no preprocessing is required before execution of the code.
- import : nothing is included unlike C which includes the header files.
- Class contains:
- data items (optional prefix : static, modifiers like final etc.)
- set of constructors, these are methods with same name as class name and without return type(not like C which has default return type as int). It performs polymorphism using function overloading.
- methods : (optional prefix static)
- Java built in data types (primitive)
- Min value = 2(bits – 1)
- Max value = 2(bits-1) – 1 where 1 byte = 8 bits
- In java assignment statements, operators, declarations and control statements are similar to C.
- Java modifiers with respect to class, class variables, method and method variables
- Java access modifiers specify what can be accessed and from where:
- public : can be accessed from anywhere
- private : can be accessed within the class
- protected : can be accessed within the package and sub-classes
- Default (when nothing is specified) : within the package
- Static cannot be prefixed with method variables i.e. there is no static variable in method because static variable requires global memory and there is no global memory in java.
- No preprocessor directives because no preprocessing is required before the run.
- import package/class work differently, they do not include anything unlike C which includes header files
- No Global data, though semantics of global could be used differently by defining the C global variables as static class variables.
- No constant, though ‘final’ has very similar semantic.
- No static local variable within a function.However, variables and methods, within a class could be prefixed with static modifier.
- No syntax for pointers and references, no pointer arithmetic to avoid access to garbage.
- Calling convention :
- Built-in Data Type : call by Value
- User-Defined Data Type (including Array): call by reference
- Every variable/object must be ‘initialized before use’.Initialisation is important for ensuring safety. Java has comprehensive plan for initialisation. Default init values are:
- long, int, short, byte: 0
- double, float: 0.0
- boolean: false
- char ‘\u000’
- object reference: null
- Every user defined object is created by new function which is memory allocator like malloc and calloc in C.
- Java programs with built-in data types (without user defined data types/ objects)
- Java program with static data/ methods only
public class StaticExample {
static int ia;
public static void main(String[] args){
System.out.println("In main method");
method1();
method2();
}
public static void method1(){
System.out.println( "method 1");
method2();
}
public static void method2(){
System.out.println( "method 2");
}
}
- Static method or variable of any class can be invoked without creating object instance of that class by class qualifier or also by any object of the class. While non static method can be invoked only through an object instance of that class.
- Semantics of static are different in Java than C
- In C, there are 2 Semantics
- static linkages: applicable to both data and methods. It means data or method is accessible only within the module
- static local variable: It means life of variable is extended throughout the program execution.It is created on Global Memory Space but still visible locally only.
- In Java, there is no concept of Global Memory Space and hence local static variable (within a method) cannot be created.Otherwise, semantics of static in Java, are akin to the linkages in C.
- In Java,
- static variables and methods are linked to a Class.They are called ‘class’ variables and methods.They are not included with the instantiated objects of the class, though an object can access static data / methods.
- Static variables: They have single storage per class (single value), which can be accessed by the class or any of the objects of the class.
- Static methods : They are not associated with any object of the class though, it could be invoked by object.
- Within the definition of static methods, none of the non-static attributes can be accessed though within non-static method, one can access static fields.
- Java has comprehensive package for Input / Output: text / binary
- import java.io.*;
- import java.util.Scanner;
- Following function for printing output
- println - print with newline character.
System.out.println("The square root of " + i + " is " + r + ".");
$ The square root of 5 is 2.23606797749979
- print - print without newline character
- format - C like formated output
System.out.format("The square root of %d is %f.%n", i, d);
$ The square root of 5 is 2.236067
- Java has OutputStreams like DataOutStreams, FileOutputStreams (for printing output to the file), etc.
- e.g. OutputStream output = new FileOutputStream(“FileTxt.txt");
- Input / Output Stream Reader:
- Reading from standard input stream: A Reader object is created and connected to the Standard Input Stream.
static private BufferedReader br = new BufferedReader(new InputStreamReader (System.in));
String s = br.readLine();
// Parsing to get the desired data type. Parsing in java is similar to tokenizing in C.
int i = Integer.parseInt(s);
byte b = (byte(i); short s = (short)i;
Long lg = Long.parseLong(s);
double db = Double.parseDouble(s);
- Reading and writing to file :
BufferedReader inStream = new BufferedReader(new FileReader(“abcd.txt"));
BufferedWriter outStream = new BufferedWriter(new FileWriter(“abcd.txt"));
- C program and equivalent java program
- In C, Mystruct *abc;*obj ; =(equivalent) Mystruct abc,obj; in Java
- In C, *abc = malloc(...) ; = (equivalent) abc = new mystruct() ; in Java
- In C, *obj = abc = (equivalent) obj = abc;
- In java, without new, we cannot have any object of user defined data type.
- In java, every input is taken as string like C. Every class name starts with upper case e.g. Mystruct while primitive data type with lower case like int.
- Integer is wrapper class for primitive data type int.
- In C we need to declare variable and method before use while in Java for variable we need to declare before use but not compulsory for method.
- Java program with objects
- Creating & Initializing Objects:
class Abc {
int ia; // instance (non-static) var./data members
double da;
static int isa; // Class (Static) data members
final int fia = 100; // not necessary to assign a value; one time assignment
Abc(){};
Abc(int i) { ... } // many types of constructors / initializers
public void Abc(){ .... } // Non-static Methods
public static void SAbc(){ ..} // Static Methods
}
- An object (user defined data type defined by a class) is :
- Created by new for any class, new also assigns memory
- Initialized by constructors. In case of no user-defined constructor, PL creates one (default constructor).
- It should never be private.
- Does not have return type, returns object of same class.
- static function can not call any non-static function.
- Static space for a class is created and initialized at the time of loading of program.
- Static Space is created per class not per object.
- Each object of the class can access static data of the class so there should be some mechanism exist by which objects can access static data.
- Static data can not access per object data
- Every user defined data type is an extension of this Object class.
- By default every class extends this object class no need to write explicitly.
- Some methods that are available to all classes in java
- (i)GetClass():-This method returns class of the object representing class of the object.
- (ii)equals():-This method returns true if first object's contents are equal to the second object's contents.
- Difference b/w (==) and equals is when object1 and object2 both points to same reference then (==) return true and if object1 and object2 are content wise equal but points to different object then (==) return false and equals() will return true.
- It is used to wrap any data (primitive data type) around Object class.
- Example:-int i ;
- Integer obj_i=new Integer(i);
- Classes and Sub-classes:-
- Base and derived class have single inheritance.
- Multiple inheritance is not directly supported by java but with the help of Interface we can achieve multiple inheritance.
- When we move downward from Base to Derived Class that is Specialization.
- Abstract Classes:- We can create reference of the abstract class but we can not create object of abstract class using new.
- Interface:-We can achieve multiple inheritance with the help of Interface.
- Arity of function:-It is 1+no of parameters of the function.
For example:-void fun(int x,int y):-arity of this function is 3.
- Java Types:-In java main types are
- (i)primitive types:-
- (ii)Reference types:-
- Java Array:-Array is type.
- Declaration:-int A[]; or int []A
- Construction:-int A[]=new int[10];
- initialization:-int A[]={1,2,3,4};
- Array Declaration: Following are the ways in which arrays can be declaration in java -
- int myArray[]; // Array of int
- int[] myArray; // this is more natural: array of int
- Animal [] Aarray; // Array of pointers
- double[][] doubleArray;
- Array Construction: Arrays are constructed like objects in java with new keyword.
- int[] myArray = new int[5];
- int[][] twoDimArray = new int[5][4]
- Array Initialization: In java arrays must be initialised before use.
- int[] myArray = new int[5];
- int[5] myArray = {1,2,3,4,5};
- int[] myArray = {1,2,3,4,5};
- for(int i=0; i<myArray.len; i++) myArray[i]=i++;
- Java arrays: Similarities and Differences with C
typedef struct animal { . . . .} Animal;
Animal arr[2][2];
Class Animal { . . . .}
Animal[][] arr = new Animal[2][2];
- In C/C++, multidimensional arrays are stored in contiguous memory but in java they are stored as array of arrays. In C we can exceed the boundaries of an array, it may or may not give segmentation fault depending on the whether the garbage value is interpretable or not but int Java we cannot exceed the boundaries.(It is not because of the meta data length associated with the array, Java has no role to play here. Why so?, we will see later while learning runtime environment.)
- Here we are studying array not as a class but as a type. Array Type is a subtype of Object[ ], Object. Array type T[ ] exists for each class, interface type T. Array type is final and cannot be extended.
- Memory is allocated dynamically and garbage collected.
- Arrays are treated as a reference type where an array variable is a pointer to an array. It can be null.
- Java : Creation and Initialization
- In Java, everything is created using new keyword and everything is created on heap. C++ is a hybrid of C and Java. It creates objects using new like Java and also without new like C.
- Java Safety Protocol: A variable or an object must be initialized before use.
- If anything is not initialised then Java initialises it with default values. Any type ultimately formed by primitive data types whose default initial values are:
- long, int, short, byte : 0
- double, float : 0.0
- boolean : false
- char : \u000
- object ref. : null
- Initialisation is classified into 2 types -
- Initialization of objects/instance variables:
1. instance initializers (also called instance initialization blocks)
2. instance variable initializers, and
3. Constructors.
- Initialization of static variables: Only first two are applicable, constructor may assign values (like incrementing the count of objects), but cannot initialize static variables.
- Java : Initialization of Static/Class Variables
- 1. Static Variable Initializers
Class Abc {
static int sa = 10;
static boolean flag = true;
}
- 2. Initialization static blocks
Class Abc {
static int [][] arr;
}
How to initialize arr ?
static {
arr = new [?][?];
}
- The static block code is executed in the first reference. to the Class. There can be many such static blocks within a class. Execution order is by the appearance in the class definition.
- Only static members can be accessed inside the static block, not instance variables.
- We can also use static methods to re-initialise the the static variables. Re-initialisation is assignment of static variables to initial values.
- Java : Initialization of Object Instance Variables
Class Abc {
int a = 10;
boolean flag = true;
}
- 2. Initialization blocks:
Class Abc {
int [][] arr;
}
How to initialize arr ?
{
arr = new [?][?];
}
- This is an “init” block for instance variables.This method of initialisation is not necessary but provided just for uniformity
- 3. Constructors : This is the most common way to initialise the instance variables.
Class Abc {
Abc(…){ . . . }
}
- Constructor do not have a Return Type unlike methods.
- Name is unique and same as that of class.
- Constructors could be overloaded just like a method based on arity or type of arguments.
- Java : Type of Constructors
1. No-Argument Constructor
2. Constructor with arguments
3. Copy Constructor
4. Default Constructor and Default Copy Constructor
5. Constructors : Pseudo Variables - this (…) and super(. . .)
- 1. No Argument Constructor
Class Point {
private int x, y;
private int color=0;
Point(){x = 0; y = 0;} }
Thumb Rule: Always define constructor with no arguments that initialises the
variables as we want, otherwise Java defines a default constructor that initialises
all the variables to its default initial values. Anything initialised by default may
cause problems.
- 2. Constructor with Arguments
EX 1: Class Point {
private int x,y;
private int color = 0;
Point(int a, int b){
this.x = a; // this is a pseudo-var for current object
this.y = b; } }
EX 2: Class Point {
private int x, y;
private int color;
Point(int a, int b, int c){
this (a,b);
this.color = c; } }
- 3. Default Constructor : If no constructor is defined, then the system will introduce a Zero Argument Default constructor. Values to be initialized will be based on default init and init block.
Point () { } // this is equivalent to default constructor
Class Point {
private int x,y;
private int color = 0;
Point(Point P){
this.x = P.x;
this.y = P.y;
this.color = P.color } }
Point P1 = new Point(…)
Point P2 = P1;
Reference of P1 is copied in Java, though in C++, it will call copy constructor and if not defined it will call default copy constructor. In Java copy constructor is used as follows:
P2 = new Point (P1);
- Copy Constructor vs. Clone : Clone is a method of Object class which can be overridden. It has issue of class subclass (override).
- Deep copy vs. shallow copying: Deep copy copies the entire contents of the references but shallow copy only copies the references.
- Mutable vs. Immutable (string) {synchronization, sharing . . .}
- 5. Super Constructor : Java guarantees constructor call for each object. It calls the constructor of the class one level up in class hierarchy.
- Subclass constructor must call super constructor. If first statement is not call to super, then call super() inserted automatically by compiler. If superclass does not have a constructor with no args, then this causes compiler error.
- Exception to rule: if one constructor invokes another, then it is responsibility of second constructor to call super, e.g.,
ColorPoint() { ColorPoint(0,blue);}
is compiled without inserting call to super
- Always define two constructors: Zero argument and Copy constructor. Otherwise system will use default constructors which may cause problems.
- Constructors should never be defined as private, as it is to be used by others, though we can have private constructors for internal use but those cannot be accessed outside.
- Class object without any field variable also allocates memory for each object. What does it contain? It contains meta data of objects. Static variables and meta data of class are in class space while instance variables and meta data of objects are in object/instance space where class space and object space are in data space.
Note: Methods don’t consume data space but only consume code space.
- Shallow copy: Structure is copied, reference is also copied as structure. e.g. In case of link list, head node is copied and reference to the next node is also copied.
- Deep copy : Structure is copied and along with it the data pointed by each reference is also copied. e.g. In case of link list, whole link list is copied.
- In C:
Point P1, P2; // assume Point has some references too.
. . . // Initialize & Operate P1
P2 = P1;
An assignment operator does Shallow Copy in C, by default.
Point P2 = P1; // assignment opr
Reference is copied in P2; this is neither Shallow nor Deep Copy.
- In C++:
- Point P2 = P1; // Not a simple assignment operator
- This is a Copy Constructor:If Default Copy Constructor is used then it is a Shallow Copy, else you can make a Deep Copy by writing your own constructor.
- Due to such features C++ is a powerful language and prefered language for system programing.
- In Java, Object Class has a method called clone with following signature
protected Object clone () throws cloneNotSupportedException
- It throws an exception if the object is not Cloneable else creates a shallow copy. It has to be overridden with a public modifier. Do not know, why it is defined as protected ?
public class Person implements Clonable {
private String name; //if immutable, no need to clone
private Date dob;
…
public Person Clone (){
Person p;
p = (Person) super.clone(); //within try-catch block
p.dob = (Date) dob.clone();
return p;
}}
- Immutable String means initial string will remain as it is and if any changes are made then new versions are created.
- There are several issues with clone method but not to be discussed here.
- public: Class can be accessed from any other class present in any package.
- default : Class can be accessed only from within the same package. Classes
outside the package in which the class is defined cannot access this class.
- final : This class cannot be sub-classed, one cannot extend this class
- abstract : Class cannot be instantiated, need to sub-class/extend.
- strictfp :Confirms that all methods in the class will conform to IEEE standard
rules for floating points.
Class cannot be private, otherwise it is of no use if no one can access it.
- public :Method can be accessed from any other class present in any package
- private:Method can be accessed from only within the class. Such methods are called helper methods.
- protected:Method can be accessed from all classes in the same package and sub- classes.
- default:Method can be accessed only from within the same package.
- final :The method cannot be overridden.
- abstract:Only provides the method declaration.
- strictfp:Method conforms to IEEE standard rules for floating points
- synchronized:Only one thread can access the method at a time
- native:Method is implemented in platform dependent language.
- static:Can access only static members.
- Java Modifiers : Class and Instance Attributes
- public :Attribute can be accessed from any other class present in any package
- private:Attribute can be accessed from only within the class.Mostly attributes must be private and should be accessed through the class methods.
- protected:Attribute can be accessed from all classes in the same package and sub-classes.
- default:Attribute can be accessed only from within the same package.
- final :This value of the attribute cannot be changed, can assign only 1 value
- transient:The attribute value cannot be serialized (platform independent)
- Volatile (with synch):Thread always reconciles its own copy of attribute with master.
- static:Only one value of the attribute per class
- Signature distinguishes one method from another.
- In ANSI C: Every function has to have a different name.Not required in C99
- In Today’s PL: Methods have to differ in their names or in the number
or types of their parameters
- foo(int), foo(double)
- foo(int), foo(int, int)
- foo(int, double), foo(double, int )
- foo(double, double)
- Signature may include the return type (not in Java now)
- Method call based on Closest Match.
e.g. if we have foo(double,double) and foo(int) then call foo(5,4) will do closest match and call definition foo(double,double).
- Method Overloading, Overriding/Shadowing/Method hidding
- Overloading : Between methods with different Signatures (return type not included) but within a same class.It is static polymorphism, known at Compile time. Generally between multiple Methods with same name with different number/types of parameters.
- Overriding (& Shadowing) : Between methods with same Signature (return type not included) but within a class and subclass hierarchy. It is dynamic polymorphism, only know at runtime
- Basis for both is Reusability and Elegant SW Design
- The return type alone is not sufficient for overloaded methods
public void move (int x, int y) { ... }
public int move (int x, int y) { ... }
- It gives compilation error as there is ambiguity which function definition to call when call statement is move(5,5).
- Overloading is done when we need to perform similar tasks on different data types. It also increases the readability of the program.
e.g. myPrint(int),myPrint(double),...
- Can also be used for better reusability like
myPrint(int i, double d) { myPrint(i); …. ; }
- Default Arguments (Not in Java): Parameters from the tail take default values.This reduces the programmer’s effort.
myPrint (int i, Device d=printer) { … } //Device as a Default argument
Method Call:
myPrint(5);
myPrint(5,console);
- Overloading is applicable to both Static and Non-Static methods. A class may have multiple methods with the same name as long as the parameter signature is unique. It may not overload on return type (as in Java)
- Methods in different classes may have same name and signature as this is a not method overloading.
- In some OOPLs methods to be overridden should be prefixed with virtual.In Java all methods are virtual by default.
Modifier | Overloading (diff signature) | Overriding (same signature) |
Private | Yes | No( because it is not accessible to an inheriting class) |
Static (any access) | Yes | No(Overriding is in the context of objects and A static method belongs to the whole class) |
Non-Static (non private) | Yes | Yes |
final | Yes | No (not allowed) |
- Covariance : substitute derived type in place of base type
Shape s = new Circle();
- Contravariance : substitute base class in place of derived. This could lead to runtime exception.
Circle c = (Circle) s;
- Inheritance gives vertical hierarchy while Generics gives horizontal hierarchy
- Every expression has a type that is determined from its parts.Some type conversions, many casts are checked at run time
- Ex, assuming A <: B (B is subclass of A)
- If A x,i.e. x is object of class A, then we can use x as argument to method that requires argument as object of class B.
- If B x, then we can try to cast x to A but downcast checked at run-time, may raise exception.
- In Java every method is virtual and can be reused by overriding and returning different types of objects. Core concept in overriding is message dispatch.
- Operator Overriding (NOT in Java)
- Operator Overloading is to use traditional operators with user-defined objects. It is not supported by Java because it is somewhat complex to implement and may be Java does not want to compromise on its simplicity.
- ‘=‘ is overloaded on all data-types and by default supported by all languages.
- ‘+’ performs arithmetic on different primitive data-types, and it is sensitive to data types i.e. semantics is same but implementation is different. e.g. for string it is implemented as concatenation.
- ‘&’ address operator: return address of the object in memory
- Overloading is generalization of Function overloading and thus makes code more readable. It is extension of language to include user-defined types. It is best suited with ADT and thus ADT must support operator overloading.
Complex a, b, c;
.. .
a = b + c; // a = b.complex_add(c);
b = b + c * a;
c = a * b + complex(1,2);
- General Format of defining operator overload
returnType operator*(parameters);
- Return type may be whatever the operator returns including a reference to the object of the operand. Operator symbol is an overload-able operator.
class complex {
double re, img;
complex(double r, double i) {}
complex operator+(complex, complex);
complex operator*(complex, complex);
complex& operator=(complex, complex);} //a=b, b is assigned to a and
reference of a is returned.
- Calling convention: a.operator+(b); a + b; operator+(a,b); or a + b;
- Operator Overload Philosophy
- Operators retains precedence and associativity
- Operator retain arity (number of operands)
- Some both unary and binary: &, *, + and -
- Cannot redefine operators for built-in-types
- Not possible to define new symbols
- Operators that cannot be overloaded in C++
- “ . ”, “ .* ”, “ :: “, “ ?: “, “sizeof”
- Operator overloading is syntactic simplicity of programing language.
- Makes the program Readable, Compact and Elegant.Single operator, single semantics, single mindset. It must be done with care, else catastrophic.
- Not in java, (May be) Java does not wish to compromise with simplicity.
- Errors and Exceptions: Runtime Error Handling : Traditional Style
- Syntax Errors
- Runtime errors: Exception deals with controllable runtime errors.
- Logical Errors: Programmer has no control
- Traditionally when a method detects an Error it returns an Error Code (may be a boolean, in C)
int Err_code = obj.do_something ();
- Issues with traditional style:
- The calling method may forget to check the return value.
- A failure notification may go completely undetected.In that case program keeps processing faulty results and mysteriously fails later.
- The calling method may not be able to process the Error Code due to its own failure.
- Many method calls need to be checked in code with hierarchy of if-else.
- Needs a mechanism in which “abnormal behavior” is not overlooked.
- An exception is an error condition that changes the normal flow of control in a program. Exception Handling is a mechanism in which “abnormal behavior” is controlled.
- Exceptions cannot be overlooked.They are sent directly to an Exception Handler (unlike the caller of the failed method).Exceptions in Java separates error handling from main program logic.
- Throwing and Catching: Syntax
- An error can throw an exception
throw <exception object>;
- Exception handlers can catch the specified exceptions and recover from error
catch (<exception type> e) {
//statements that handle the exception }
- Throwing an Exception : Syntax
- Creates a subclass of Exception
class MyException extends Exception { }
- Method throws an exception
class MyClass {
void oops(){
if { (/* no error occurred */)
/* normal processing */ }
}
else {
/* error occurred */
throw new MyException();
}
}
}
- Exception Class Hierarchy
- Checked Exceptions : Exceptions that must be caught or declared in program.
- Unchecked Exceptions : Runtime and System Errors.Not to be handled by program.They are Unrecoverable.
- Exception : Flow of Control
- Exception breaks the normal flow of control. When an exception occurs, the statement that would normally execute next is not executed.
- What happens instead depends on:
- whether the exception is caught,if yes goes to exception handler.
- where it is caught,
- what statements are executed in the ‘catch block’,
- whether you have a ‘finally block’. It is always executed, normally resources are released in this block.
- Atmost one catch block is executed. Order of catch blocks is very important, in the class hierarchy, the specialist class must be caught first. If superclass is declared first then it gives compile time error, as subclass exception will never be executed.
- Declaring, throwing and Catching an Exception
- Every method must state the types of checked exceptions it might throw. It may not state the unchecked exceptions.A method can throw multiple exceptions (no need to specify ‘unchecked’)
public int computeFileSize() throws IOException, ArithmeticException
- When the program detects an error, the program can create an instance of an appropriate exception type and throw it.
throw new TheException();
TheException ex = new TheException();
throw ex;
Example:
/** Set a new radius */
public void setRadius(double newRadius)
throws IllegalArgumentException {
if (newRadius >= 0)
radius = newRadius;
else
throw new IllegalArgumentException(
"Radius cannot be negative");
}
- Catching an Exception: Each try block can catch multiple exceptions starting with the most specific exceptions.
try {
statements; // Statements that may throw exceptions
}
catch (Exception1 ex1) {
handler for exception1;
}
catch (Exception2 ex2) {
handler for exception2;
}
...
catch (ExceptionN ex3) {
handler for exceptionN;
}
- Arrangement of Catch Blocks:Most Specialized class first: At most one is executed.
- If your method is defined to throw an exception, you need not catch it within your method, it could be caught in calling method.
- Re-throwing an Exception : No keyword for rethrow, we perform rethrow by calling throw in catch block.If you catch an exception but the code determines it cannot reasonably handle the exception, it can be re-thrown.
try {
statements;
}
catch(TheException ex) {
perform operations before exits;
throw ex;
}
- Finally Clause:Finally block always executes once, whether there’s an error or not. A good place to put clean-up code. ie. Close any open files, etc. Finally block could have exception handler also.
- Java Exception Hierarchy :
- Checked exceptions : Compiler forces the programmer to check and deal with these exceptions. It includes other than runtime exceptions.
- Unchecked exceptions : Errors and Runtime Exceptions are unchecked exceptions.
- Throwable is an interface. Errors and unchecked exceptions are handled similarly by system but unchecked can also be handled in own way like checked but errors cannot be handled.
- There are two classes because unchecked are many and most of them have default handler.
- Exception describes errors caused by your program and external circumstances. These exceptions can be caught and handled by your program.
- System errors are thrown by JVM and represented in the Error class. The Error class describes internal system errors. Such errors rarely occur.If one does, there is little you can do beyond notifying the user and trying to terminate the program gracefully.
- Unchecked exceptions reflect programming logic errors which are not recoverable, e.g., NullPointerException, IndexOutOfBoundsException. Java does not mandate you to write code to catch unchecked exceptions.
- Runtime Exception is caused by programming errors, such as bad casting, accessing an out-of bounds array, and numeric errors. You can ignore to catch, will be caught by System’s catch-all-handler.
- Checked Exceptions:
- If your code invokes a method which is defined to throw checked exception, your code MUST provide a catch handler.The compiler generates an error if the appropriate catch handler is not present.
- These exceptions can occur through normal operation of the virtual machine. You can choose to catch them or not. If an unchecked exception is not caught, it will go to the default catch-all-handler for the application. All Unchecked exceptions are subclassed from RuntimeException
- Internal system errors. Little one can do, other than terminating the program.
- Define your own Exceptions : Checked or unchecked
- To define your own exception you must do the following:
- Create an exception class to hold the exception data. Your exception class must subclass "Exception" or another exception class.
- To create unchecked exceptions, subclass the RuntimeException class.
- Minimally, your exception class should provide a constructor which takes the exception description as its argument.
- To throw your own exceptions:
- If your exception is checked, any method which is going to throw the exception must define it using the throws keyword. When an exceptional condition occurs, create a new instance of the exception and throw it.
- Examples
- 1. Uncaught Unchecked Exception
class exc0{
public static void main (String args[]) {
int d=0;
int a=4/d;
}
}
Output: java.lang.ArithmeticException: / by zero at exc0.main(exc0.java:4)
- A new exception object is constructed and then thrown. This exception is caught by the default handler provided by the java runtime system.
- The default handler displays: a string describing the exception and prints the stack trace from the point at which the exception occurred and terminates the program.
- 2. Caught an unchecked Exception
- Throwable overrides the toString() method (defined by Object) so that it returns a string containing a description of the exception.
catch(ArithmeticException e) {
System.out.println(“Exception: “+e);
}
- Output: Exception: java.lang.ArithmeticException: / by zero
- Unchecked Exceptions are RuntimeException or its subclasses
- Unchecked Exceptions are unchecked by compiler.Whether you catch the exception or not compiler will pass (OK) the compilation process.
- If Unchecked exception is caught then exception handling code will be executed and program’s execution continues. If Unchecked exception is not caught then java interpreter/compiler will provide the default handler. But in this case execution of the program will be stopped by displaying the name of the exceptions object.
- Some Common Unchecked Exceptions are:
- ArithmaticException (Divide By 0)
- ArrayIndexOutOfBoundsException
- ArrayStoreException
- FileNotFoundException
- NullPointerException
- NumberFormatException
- IllegalArumentsException
- Checked Exceptions extend the Exception or any one its subclass except RunTimeException class.
- Checked Exceptions are checked by Java compiler.
- Handling Checked Exceptions includes:
- Inform the compiler that a method can throw an Exception.
- Catch the checked exception in try-catch block.
- If Checked exception is caught then exception handling code will be executed and program’s execution continues.
- If Checked exception is not caught then java interpreter/compiler will provide the default handler. But in this case execution of the program will be stopped by displaying the name of the exception object.
- A few sample Checked Exceptions
- IOException
- ClassNotFoundExceptions
- InterruptedException
- NoSuchMethodException
- If checked exception is not mentioned then the compiler gives an error.
unreported exception java.io.IOException; must be caught or declared to be thrown
- Exceptions are not always necessary. They require extra overhead to create an object ….
- We may replace it with if-else statements like
try {
System.out.println(refVar.toString());
}
catch (NullPointerException ex) {
System.out.println("refVar is null");
}
Could be replaced by:
if (refVar != null)
System.out.println(refVar.toString());
else
System.out.println("refVar is null");
- Summary : Exception Handling
- Exception handling separates error-handling code from normal programming tasks, thus making programs easier to read and to modify.
- However, exception handling requires instantiating a new exception object, rolling back the call stack, and propagating the errors to the calling methods.
- For an exception to be processed by its caller, create an exception object and throw it. If the exception can be handled in the method where it occurs, there is no need to throw it.
- Do not overburden the system with unnecessary exceptions.
- Introduced with Java 1.4 and reformed with Java 1.5, it is a Java statement that enables you to assert an assumption about your program. An assertion contains a Boolean expression that should be true during program execution.
- Motivation is that method shold have preconditions and postconditions.Assertions can be used to assure program correctness and avoid logic errors.
- Java keyword assert
- assert assertion; or
- assert assertion : detailMessage;
- where assertion is a Boolean expression, and detailMessage is a primitive-type or an Object value.
assert sum > 10 && sum < 5 * 10 : "sum is " + sum;
- Another good use of assertions is place assertions in a switch statement without a default case. ex.
- switch (month) {
case 1: ... ; break;
case 2: ... ; break;
...
case 12: ... ; break;
default: assert false : "Invalid month: " + month;
}
- Use Java Assertions vs. Exception Handling
- Assertion should not be used to replace exception handling. Exception handling deals with unusual circumstances during program execution.
- Assertions are to assure the correctness of the program.Exception handling addresses robustness and assertion addresses correctness.
- Like exception handling, assertions are not used for normal tests, but for internal consistency and validity checks.
- Assertions are checked at runtime and can be turned on or off at startup time.
- Use assertions to reaffirm assumptions. This assures correctness of the program.
- Proper use of assertion
public void setRadius(double newRadius) {
assert newRadius >= 0;
radius = newRadius; }
- Here assertion is just checking for non-negative radius. Exception handling would check for any illegal argument like character, negative etc. therefore exception handling would have been better here.
- Exception handling ensures the separation of interface, implementation and verifier for good software design.
- When an assertion statement is executed, Java evaluates the assertion. If it is false, an AssertionError will be thrown.
- The AssertionError class has a no-arg constructor and seven overloaded single-argument constructors of type int, long, float, double, boolean, char, and Object.
- For the first assert statement with no detail message, the no-arg constructor of AssertionError is used.
- For the second assert statement with a detail message, an appropriate AssertionError constructor is used to match the datatype of the message.
- Since AssertionError is a subclass of Error, when an assertion becomes false, the program displays a message on the console and exits.