Vous êtes sur la page 1sur 67

Introduction to Java Classes

A class is nothing but a blueprint or a template for creating different objects which
defines its properties and behaviors. Java class objects exhibit the properties and
behaviors defined by its class. A class can contain fields and methods to describe the
behavior of an object.

Methods are nothing but members of a class that provide a service for an object or
perform some business logic. Java fields and member functions names are case sensitive.
Current states of a class’s corresponding object are stored in the object’s instance
variables. Methods define the operations that can be performed in java programming.

A class has the following general syntax:

<class modifiers>class<class name>


<extends clause> <implements clause>{

// Dealing with Classes (Class body)

<field declarations (Static and Non-Static)>


<method declarations (Static and Non-Static)>
<Inner class declarations>
<nested interface declarations>
<constructor declarations>
<Static initializer blocks>
}

Below is an example showing the Objects and Classes of the Cube class that defines 3
fields namely length, breadth and height. Also the class contains a member function
getVolume().

public class Cube {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
}

How do you reference a data member/function?

This is accomplished by stating the name of the object reference, followed by a period
(dot), followed by the name of the member inside the object.
( objectReference.member ). You call a method for an object by naming the object
followed by a period (dot), followed by the name of the method and its argument list, like
this: objectName.methodName(arg1, arg2, arg3).

For example:

cubeObject.length = 4;
cubeObject.breadth = 4;
cubeObject.height = 4;
cubeObject.getvolume()

Class Variables – Static Fields


We use class variables also know as Static fields when we want to share characteristics
across all objects within a class. When you declare a field to be static, only a single
instance of the associated variable is created common to all the objects of that class.
Hence when one object changes the value of a class variable, it affects all objects of the
class. We can access a class variable by using the name of the class, and not necessarily
using a reference to an individual object within the class. Static variables can be accessed
even though no objects of that class exist. It is declared using static keyword.

Class Methods – Static Methods


Class methods, similar to Class variables can be invoked without having an instance of
the class. Class methods are often used to provide global functions for Java programs. For
example, methods in the java.lang.Math package are class methods. You cannot call non-
static methods from inside a static method.

Instance Variables
Instance variables stores the state of the object. Each class would have its own copy of
the variable. Every object has a state that is determined by the values stored in the object.
An object is said to have changed its state when one or more data values stored in the
object have been modified. When an object responds to a message, it will usually perform
an action, change its state etc. An object that has the ability to store values is often said to
have persistence.

Consider this simple Java program showing the use of static fields and static methods

// Class and Object initialization showing the Object Oriented concepts in Java
class Cube {

int length = 10;


int breadth = 10;
int height = 10;
public static int numOfCubes = 0; // static variable
public static int getNoOfCubes() { //static method
return numOfCubes;
}
public Cube() {
numOfCubes++; //
}
}

public class CubeStaticTest {

public static void main(String args[]) {


System.out.println("Number of Cube objects = " + Cube.numOfCubes);
System.out.println("Number of Cube objects = "
+ Cube.getNoOfCubes());
}
}

Download CubeStaticTest.java

Output

Number of Cube objects = 0


Number of Cube objects = 0

Final Variable, Methods and Classes


In Java we can mark fields, methods and classes as final. Once marked as final, these
items cannot be changed.

Variables defined in an interface are implicitly final. You can’t change value of a final
variable (is a constant). A final class can’t be extended i.e., final class may not be
subclassed. This is done for security reasons with basic classes like String and Integer. It
also allows the compiler to make some optimizations, and makes thread safety a little
easier to achieve. A final method can’t be overridden when its class is inherited. Any
attempt to override or hide a final method will result in a compiler error.

Introduction to Java Objects


The Object Class is the super class for all classes in Java.

Some of the object class methods are

equals
toString()
wait()
notify()
notifyAll()
hashcode()
clone()
An object is an instance of a class created using a new operator. The new operator
returns a reference to a new instance of a class. This reference can be assigned to a
reference variable of the class. The process of creating objects from a class is called
instantiation. An object encapsulates state and behavior.

An object reference provides a handle to an object that is created and stored in memory.
In Java, objects can only be manipulated via references, which can be stored in variables.

Creating variables of your class type is similar to creating variables of primitive data
types, such as integer or float. Each time you create an object, a new set of instance
variables comes into existence which defines the characteristics of that object. If you
want to create an object of the class and have the reference variable associated with this
object, you must also allocate memory for the object by using the new operator. This
process is called instantiating an object or creating an object instance.

When you create a new object, you use the new operator to instantiate the object. The
new operator returns the location of the object which you assign o a reference type.

Below is an example showing the creation of Cube objects by using the new operator.

public class Cube {

int length = 10;


int breadth = 10;
int height = 10;
public int getVolume() {
return (length * breadth * height);
}
public static void main(String[] args) {
Cube cubeObj; // Creates a Cube Reference
cubeObj = new Cube(); // Creates an Object of Cube
System.out.println("Volume of Cube is : " +
cubeObj.getVolume());
}
}

Download Cube.java

Method Overloading
Method overloading results when two or more methods in the same class have the same
name but different parameters. Methods with the same name must differ in their types or
number of parameters. This allows the compiler to match parameters and choose the
correct method when a number of choices exist. Changing just the return type is not
enough to overload a method, and will be a compile-time error. They must have a
different signature. When no method matching the input parameters is found, the
compiler attempts to convert the input parameters to types of greater precision. A match
may then be found without error. At compile time, the right implementation is chosen
based on the signature of the method call

Below is an example of a class demonstrating Method Overloading

public class MethodOverloadDemo {

void sumOfParams() { // First Version


System.out.println("No parameters");
}
void sumOfParams(int a) { // Second Version
System.out.println("One parameter: " + a);
}
int sumOfParams(int a, int b) { // Third Version
System.out.println("Two parameters: " + a + " , " + b);
return a + b;
}
double sumOfParams(double a, double b) { // Fourth Version
System.out.println("Two double parameters: " + a + " , " +
b);
return a + b;
}
public static void main(String args[]) {
MethodOverloadDemo moDemo = new MethodOverloadDemo();
int intResult;
double doubleResult;
moDemo.sumOfParams();
System.out.println();
moDemo.sumOfParams(2);
System.out.println();
intResult = moDemo.sumOfParams(10, 20);
System.out.println("Sum is " + intResult);
System.out.println();
doubleResult = moDemo.sumOfParams(1.1, 2.2);
System.out.println("Sum is " + doubleResult);
System.out.println();
}
}

Download MethodOverloadDemo.java

Output

No parameters
One parameter: 2

Two parameters: 10 , 20
Sum is 30

Two double parameters: 1.1 , 2.2


Sum is 3.3000000000000003

Below is a code snippet to shows the interfaces that a Class Implements:

Class cls = java.lang.String.class;


Class[] intfs = cls.getInterfaces();
// [java.lang.Comparable, java.lang.CharSequence, java.io.Serializable]
// The interfaces for a primitive type is an empty array
cls = int.class;
intfs = cls.getInterfaces(); // []

Below is a code snippet to show whether a Class Object Represents a Class or Interface:

Class cls = java.lang.String.class;


boolean isClass = !cls.isInterface(); // true
cls = java.lang.Cloneable.class;
isClass = !cls.isInterface(); // false

Java Access Specifiers


The access to classes, constructors, methods and fields are regulated using access
modifiers i.e. a class can control what information or data can be accessible by other
classes. To take advantage of encapsulation, you should minimize access whenever
possible.

Java provides a number of access modifiers to help you set the level of access you want
for classes as well as the fields, methods and constructors in your classes. A member has
package or default accessibility when no accessibility modifier is specified.

Access Modifiers

1. private
2. protected
3. default
4. public

public access modifier


Fields, methods and constructors declared public (least restrictive) within a public class
are visible to any class in the Java program, whether these classes are in the same
package or in another package.

private access modifier

The private (most restrictive) fields or methods cannot be used for classes and Interfaces.
It also cannot be used for fields and methods within an interface. Fields, methods or
constructors declared private are strictly controlled, which means they cannot be accesses
by anywhere outside the enclosing class. A standard design strategy is to make all fields
private and provide public getter methods for them.

protected access modifier

The protected fields or methods cannot be used for classes and Interfaces. It also cannot
be used for fields and methods within an interface. Fields, methods and constructors
declared protected in a superclass can be accessed only by subclasses in other packages.
Classes in the same package can also access protected fields, methods and constructors as
well, even if they are not a subclass of the protected member’s class.

<br /><font size=-1>


default access modifier

Java provides a default specifier which is used when no access modifier is present. Any
class, field, method or constructor that has no declared access modifier is accessible only
by classes in the same package. The default modifier is not used for fields and methods
within an interface.

Below is a program to demonstrate the use of public, private, protected and default access
modifiers while accessing fields and methods. The output of each of these java files
depict the Java access specifiers.

The first class is SubclassInSamePackage.java which is present in pckage1 package. This


java file contains the Base class and a subclass within the enclosing class that belongs to
the same class as shown below.

package pckage1;

class BaseClass {

public int x = 10;


private int y = 10;
protected int z = 10;
int a = 10; //Implicit Default Access Modifier
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
private int getY() {
return y;
}
private void setY(int y) {
this.y = y;
}
protected int getZ() {
return z;
}
protected void setZ(int z) {
this.z = z;
}
int getA() {
return a;
}
void setA(int a) {
this.a = a;
}
}

public class SubclassInSamePackage extends BaseClass {

public static void main(String args[]) {


BaseClass rr = new BaseClass();
rr.z = 0;
SubclassInSamePackage subClassObj = new
SubclassInSamePackage();
//Access Modifiers - Public
System.out.println("Value of x is : " + subClassObj.x);
subClassObj.setX(20);
System.out.println("Value of x is : " + subClassObj.x);
//Access Modifiers - Public
// If we remove the comments it would result in a compila
// error as the fields and methods being accessed are
private
/* System.out.println("Value of y is : "+subClassObj.y);

subClassObj.setY(20);

System.out.println("Value of y is : "+subClassObj.y);*/
//Access Modifiers - Protected
System.out.println("Value of z is : " + subClassObj.z);
subClassObj.setZ(30);
System.out.println("Value of z is : " + subClassObj.z);
//Access Modifiers - Default
System.out.println("Value of x is : " + subClassObj.a);
subClassObj.setA(20);
System.out.println("Value of x is : " + subClassObj.a);
}
}

Output

Value of x is : 10
Value of x is : 20
Value of z is : 10
Value of z is : 30
Value of x is : 10
Value of x is : 20

The second class is SubClassInDifferentPackage.java which is present in a different


package then the first one. This java class extends First class
(SubclassInSamePackage.java).

import pckage1.*;

public class SubClassInDifferentPackage extends SubclassInSamePackage {

public int getZZZ() {


return z;
}

public static void main(String args[]) {


SubClassInDifferentPackage subClassDiffObj = new
SubClassInDifferentPackage();
SubclassInSamePackage subClassObj = new SubclassInSamePackage();
//Access specifiers - Public
System.out.println("Value of x is : " + subClassObj.x);
subClassObj.setX(30);
System.out.println("Value of x is : " + subClassObj.x);
//Access specifiers - Private
// if we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are private
/* System.out.println("Value of y is : "+subClassObj.y);

subClassObj.setY(20);

System.out.println("Value of y is : "+subClassObj.y);*/
//Access specifiers - Protected
// If we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are protected.
/* System.out.println("Value of z is : "+subClassObj.z);

subClassObj.setZ(30);
System.out.println("Value of z is : "+subClassObj.z);*/
System.out.println("Value of z is : " + subClassDiffObj.getZZZ());
//Access Modifiers - Default
// If we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are default.
/*

System.out.println("Value of a is : "+subClassObj.a);

subClassObj.setA(20);

System.out.println("Value of a is : "+subClassObj.a);*/
}
}

Output

Value of x is : 10
Value of x is : 30
Value of z is : 10

The third class is ClassInDifferentPackage.java which is present in a different package


then the first one.

import pckage1.*;

public class ClassInDifferentPackage {

public static void main(String args[]) {


SubclassInSamePackage subClassObj = new SubclassInSamePackage();
//Access Modifiers - Public
System.out.println("Value of x is : " + subClassObj.x);
subClassObj.setX(30);
System.out.println("Value of x is : " + subClassObj.x);
//Access Modifiers - Private
// If we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are private
/* System.out.println("Value of y is : "+subClassObj.y);

subClassObj.setY(20);

System.out.println("Value of y is : "+subClassObj.y);*/
//Access Modifiers - Protected
// If we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are protected.
/* System.out.println("Value of z is : "+subClassObj.z);

subClassObj.setZ(30);

System.out.println("Value of z is : "+subClassObj.z);*/
//Access Modifiers - Default
// If we remove the comments it would result in a compilaton
// error as the fields and methods being accessed are default.
/* System.out.println("Value of a is : "+subClassObj.a);
subClassObj.setA(20);

System.out.println("Value of a is : "+subClassObj.a);*/
}
}

Output

Value of x is : 10
Value of x is : 30

A java constructor has the same name as the name of the class to which it belongs.
Constructor’s syntax does not include a return type, since constructors never return a
value.

Constructors may include parameters of various types. When the constructor is invoked
using the new operator, the types must match those that are specified in the constructor
definition.

Java provides a default constructor which takes no arguments and performs no special
actions or initializations, when no explicit constructors are provided.

The only action taken by the implicit default constructor is to call the superclass
constructor using the super() call. Constructor arguments provide you with a way to
provide parameters for the initialization of an object.

Below is an example of a cube class containing 2 constructors. (one default and one
parameterized constructor).

public class Cube1 {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube1() {
length = 10;
breadth = 10;
height = 10;
}
Cube1(int l, int b, int h) {
length = l;
breadth = b;
height = h;
}
public static void main(String[] args) {
Cube1 cubeObj1, cubeObj2;
cubeObj1 = new Cube1();
cubeObj2 = new Cube1(10, 20, 30);
<font size=-1>

System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());


System.out.println("Volume of Cube1 is : " + cubeObj2.getVolume());
}
}

Download Cube1.java

Note: If a class defines an explicit constructor, it no longer has a default constructor to set
the state of the objects.
If such a class requires a default constructor, its implementation must be provided. Any
attempt to call the default constructor will be a compile time error if an explicit default
constructor is not provided in such a case.

Java Overloaded Constructors


Like methods, constructors can also be overloaded. Since the constructors in a class all
have the same name as the class, />their signatures are differentiated by their parameter
lists. The above example shows that the Cube1 constructor is overloaded one being the
default constructor and the other being a parameterized constructor.

It is possible to use this() construct, to implement local chaining of constructors in a


class. The this() call in a constructorinvokes the an other constructor with the
corresponding parameter list within the same class. Calling the default constructor to
create a Cube object results in the second and third parameterized constructors being
called as well. Java requires that any this() call must occur as the first statement in a
constructor.

Below is an example of a cube class containing 3 constructors which demostrates the


this() method in Constructors context

public class Cube2 {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube2() {
this(10, 10);
System.out.println("Finished with Default Constructor");
}
Cube2(int l, int b) {
this(l, b, 10);
System.out.println("Finished with Parameterized Constructor having 2
params");
}
Cube2(int l, int b, int h) {
length = l;
breadth = b;
height = h;
System.out.println("Finished with Parameterized Constructor having 3
params");
}
public static void main(String[] args) {
Cube2 cubeObj1, cubeObj2;
cubeObj1 = new Cube2();
cubeObj2 = new Cube2(10, 20, 30);
System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
System.out.println("Volume of Cube2 is : " + cubeObj2.getVolume());
}
}

public class Cube2 {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube2() {
this(10, 10);
System.out.println("Finished with Default Constructor");
}
Cube2(int l, int b) {
this(l, b, 10);
System.out.println("Finished with Parameterized Constructor having 2
params");
}
Cube2(int l, int b, int h) {
length = l;
breadth = b;
height = h;
System.out.println("Finished with Parameterized Constructor having 3
params");
}
public static void main(String[] args) {
Cube2 cubeObj1, cubeObj2;
cubeObj1 = new Cube2();
cubeObj2 = new Cube2(10, 20, 30);
System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
System.out.println("Volume of Cube2 is : " + cubeObj2.getVolume());
}
}

Output

Finished with Parameterized Constructor having 3 params


Finished with Parameterized Constructor having 2 params
Finished with Default Constructor
Finished with Parameterized Constructor having 3 params
Volume of Cube1 is : 1000
Volume of Cube2 is : 6000

Download Cube2.java

Constructor Chaining
Every constructor calls its superclass constructor. An implied super() is therefore
included in each constructor which does not include either the this() function or an
explicit super() call as its first statement. The super() statement invokes a constructor of
the super class.
The implicit super() can be replaced by an explicit super(). The super statement must be
the first statement of the constructor.
The explicit super allows parameter values to be passed to the constructor of its
superclass and must have matching parameter types A super() call in the constructor of a
subclass will result in the call of the relevant constructor from the superclass, based on
the signature of the call. This is called constructor chaining.

Below is an example of a class demonstrating constructor chaining using super() method.

class Cube {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube() {
this(10, 10);
System.out.println("Finished with Default Constructor of Cube");
}
Cube(int l, int b) {
this(l, b, 10);
System.out.println("Finished with Parameterized Constructor having
2 params of
Cube");
}
Cube(int l, int b, int h) {
length = l;
breadth = b;
height = h;
System.out.println("Finished with Parameterized Constructor having
3 params of
Cube");
}
}

public class SpecialCube extends Cube {


int weight;
SpecialCube() {
super();
weight = 10;
}
SpecialCube(int l, int b) {
this(l, b, 10);
System.out.println("Finished with Parameterized Constructor having
2 params of
SpecialCube");
}
SpecialCube(int l, int b, int h) {
super(l, b, h);
weight = 20;
System.out.println("Finished with Parameterized Constructor having
3 params of
SpecialCube");
}
public static void main(String[] args) {
SpecialCube specialObj1 = new SpecialCube();
SpecialCube specialObj2 = new SpecialCube(10, 20);
System.out.println("Volume of SpecialCube1 is : "
+ specialObj1.getVolume());
System.out.println("Weight of SpecialCube1 is : "
+ specialObj1.weight);
System.out.println("Volume of SpecialCube2 is : "
+ specialObj2.getVolume());
System.out.println("Weight of SpecialCube2 is : "
+ specialObj2.weight);
}
}

Download SpecialCube.java

Output

Finished with Parameterized Constructor having 3 params of SpecialCube


Finished with Parameterized Constructor having 2 params of SpecialCube
Volume of SpecialCube1 is : 1000
Weight of SpecialCube1 is : 10
Volume of SpecialCube2 is : 2000
Weight of SpecialCube2 is : 20

The super() construct as with this() construct: if used, must occur as the first statement in
a constructor, and it can only be used in a constructor declaration. This implies that this()
and super() calls cannot both occur in the same constructor. Just as the this() construct
leads to chaining of constructors in the same class, the super() construct leads to chaining
of subclass constructors to superclass constructors.
if a constructor has neither a this() nor a super() construct as its first statement, then a
super() call to the default constructor in the superclass is inserted.
Note: If a class only defines non-default constructors, then its subclasses will not include
an implicit super() call. This will be flagged as a compile-time error. The subclasses must
then explicitly call a superclass constructor, using the super() construct with the right
arguments to match the appropriate constructor of the superclass.

Below is an example of a class demonstrating constructor chaining using explicit super()


call.

class Cube {

int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube(int l, int b, int h) {
length = l;
breadth = b;
height = h;
System.out.println("Finished with Parameterized Constructor having
3 params of Cube");
}
}

public class SpecialCube1 extends Cube {

int weight;
SpecialCube1() {
super(10, 20, 30); //Will Give a Compilation Error without this line
weight = 10;
}
public static void main(String[] args) {
SpecialCube1 specialObj1 = new SpecialCube1();
System.out.println("Volume of SpecialCube1 is : "+
specialObj1.getVolume());
}
}

Output

Finished with Parameterized Constructor having 3 params of Cube


Volume of SpecialCube1 is : 6000

Introduction to Object Serialization


Java object serialization is used to persist Java objects to a file, database, network,
process or any other system. Serialization flattens objects into an ordered, or serialized
stream of bytes. The ordered stream of bytes can then be read at a later time, or in another
environment, to recreate the original objects.
Java serialization does not cannot occur for transient or static fields. Marking the field
transient prevents the state from being written to the stream and from being restored
during deserialization. Java provides classes to support writing objects to streams and
restoring objects from streams. Only objects that support the java.io.Serializable
interface or the java.io.Externalizable interface can be written to streams.
public interface Serializable

• The Serializable interface has no methods or fields. (Marker Interface)


• Only objects of classes that implement java.io.Serializable interface can be
serialized or deserialized

Transient Fields and Java Serialization


The transient keyword is a modifier applied to instance variables in a class. It specifies
that the variable is not part of the persistent state of the object and thus never saved
during serialization.

You can use the transient keyword to describe temporary variables, or variables that
contain local information,

<br /><font size=-1>

such as a process ID or a time lapse.

Input and Output Object Streams


ObjectOutputStream is the primary output stream class that implements the ObjectOutput
interface for serializing objects. ObjectInputStream is the primary input stream class that
implements the ObjectInput interface for deserializing objects.

These high-level streams are each chained to a low-level stream, such as FileInputStream
or FileOutputStream.
The low-level streams handle the bytes of data. The writeObject method saves the state of
the class by writing the individual fields to the ObjectOutputStream. The readObject
method is used to deserialize the object from
the object input stream.

Case 1: Below is an example that demonstrates object Serialization into a File

PersonDetails is the bean class that implements the Serializable interface

import java.io.Serializable;
public class PersonDetails implements Serializable {

private String name;


private int age;
private String sex;
public PersonDetails(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}

GetPersonDetails is the class that is used to Deserialize object from the File (person.txt).

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
public class GetPersonDetails {

public static void main(String[] args) {


String filename = "person.txt";
List pDetails = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
pDetails = (ArrayList) in.readObject();
in.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
// print out the size
System.out.println("Person Details Size: " + pDetails.size());
System.out.println();
}
}
PersonPersist is the class that is used to serialize object into the File (person.txt).

public class PersonPersist {

public static void main(String[] args) {


String filename = "person.txt";
PersonDetails person1 = new PersonDetails("hemanth", 10, "Male");
PersonDetails person2 = new PersonDetails("bob", 12, "Male");
PersonDetails person3 = new PersonDetails("Richa", 10, "Female");
List list = new ArrayList();
list.add(person1);
list.add(person2);
list.add(person3);
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
System.out.println("Object Persisted");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

——————————————————————————–

Case 2: Below is an example that demonstrates object Serialization into the database

PersonDetails remains the same as shown above

GetPersonDetails remains the same as shown above

Create SerialTest Table

create table SerialTest(


name BLOB,
viewname VARCHAR2(30)
);

PersonPersist is the class that is used to serialize object into the into the Database Table
SerialTest.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class PersonPersist {

static String userid = "scott", password = "tiger";


static String url = "jdbc:odbc:bob";
static int count = 0;
static Connection con = null;
public static void main(String[] args) {
Connection con = getOracleJDBCConnection();
PersonDetails person1 = new PersonDetails("hemanth", 10, "Male");
PersonDetails person2 = new PersonDetails("bob", 12, "Male");
PersonDetails person3 = new PersonDetails("Richa", 10, "Female");
PreparedStatement ps;
try {
ps = con
.prepareStatement("INSERT INTO SerialTest VALUES
(?, ?)");
write(person1, ps);
ps.execute();
write(person2, ps);
ps.execute();
write(person3, ps);
ps.execute();
ps.close();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM SerialTest");
while (rs.next()) {
Object obj = read(rs, "Name");
PersonDetails p = (PersonDetails) obj;
System.out.println(p.getName() + "\t" + p.getAge() +
"\t"
+ p.getSex());
}
rs.close();
st.close();
} catch (Exception e) {
}
}
public static void write(Object obj, PreparedStatement ps)
throws SQLException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baos);
oout.writeObject(obj);
oout.close();
ps.setBytes(1, baos.toByteArray());
ps.setInt(2, ++count);
}
public static Object read(ResultSet rs, String column)
throws SQLException, IOException, ClassNotFoundException {
byte[] buf = rs.getBytes(column);
if (buf != null) {
ObjectInputStream objectIn = new ObjectInputStream(
new ByteArrayInputStream(buf));
return objectIn.readObject();
}
return null;
}
public static Connection getOracleJDBCConnection() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url, userid, password);
} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
return con;
}
}

——————————————————————————–

Case 3: Below is an example that demonstrates object Serialization into the database
using Base 64 Encoder

PersonDetails remains the same as shown above

GetPersonDetails remains the same as shown above

Create SerialTest Table

create table SerialTest(


name BLOB,
viewname VARCHAR2(30)
);

PersonPersist is the class that is used to serialize object into the Database Table
SerialTest

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class PersonPersist {
static String userid = "scott", password = "tiger";
static String url = "jdbc:odbc:bob";
static int count = 0;
static Connection con = null;
static String s;
public static void main(String[] args) {
Connection con = getOracleJDBCConnection();
PersonDetails person1 = new PersonDetails("hemanth", 10, "Male");
PersonDetails person2 = new PersonDetails("bob", 12, "Male");
PersonDetails person3 = new PersonDetails("Richa", 10, "Female");
PreparedStatement ps;
try {
ps = con
.prepareStatement("INSERT INTO SerialTest VALUES
(?, ?)");
write(person1, ps);
ps.execute();
write(person2, ps);
ps.execute();
write(person3, ps);
ps.execute();
ps.close();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM SerialTest");
while (rs.next()) {
Object obj = read(rs, "Name");
PersonDetails p = (PersonDetails) obj;
System.out.println(p.getName() + "\t" + p.getAge() +
"\t"
+ p.getSex());
}
rs.close();
st.close();
} catch (Exception e) {
}
}
public static void write(Object obj, PreparedStatement ps)
throws SQLException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baos);
oout.writeObject(obj);
oout.close();
byte[] buf = baos.toByteArray();
s = new sun.misc.BASE64Encoder().encode(buf);
ps.setString(1, s);
// ps.setBytes(1, Base64.byteArrayToBase64(baos.toByteArray()));
ps.setBytes(1, baos.toByteArray());
ps.setInt(2, ++count);
}
public static Object read(ResultSet rs, String column)
throws SQLException, IOException, ClassNotFoundException {
byte[] buf = new sun.misc.BASE64Decoder().decodeBuffer(s);
// byte[] buf = Base64.base64ToByteArray(new
// String(rs.getBytes(column)));
if (buf != null) {
ObjectInputStream objectIn = new ObjectInputStream(
new ByteArrayInputStream(buf));
Object obj = objectIn.readObject(); // Contains the object
PersonDetails p = (PersonDetails) obj;
System.out.println(p.getName() + "\t" + p.getAge() + "\t"
+ p.getSex());
}
return null;
}
public static Connection getOracleJDBCConnection() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url, userid, password);
} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
return con;
}
}
Below is a program that shows the serialization of a JButton object to a file and a Byte
Array Stream. As before theobject to be serialized must implement the Serializable
interface.

PersonDetails is the bean class that implements the Serializable interface

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class ObjectSerializationExample {

public static void main(String args[]) {


try {
Object object = new javax.swing.JButton("Submit");
// Serialize to a file namely "filename.dat"
ObjectOutput out = new ObjectOutputStream(
new FileOutputStream("filename.dat"));
out.writeObject(object);
out.close();
// Serialize to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
out = new ObjectOutputStream(bos);
out.writeObject(object);
out.close();
// Get the bytes of the serialized object
byte[] buf = bos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Java Inheritance defines an is-a relationship between a superclass and its subclasses. This
means that an object of a subclass can be used wherever an object of the superclass can
be used. Class Inheritance in java mechanism is used to build new classes from existing
classes. The inheritance relationship is transitive: if class x extends class y, then a class z,
which extends class x, will also inherit from class y.

For example a car class can inherit some properties from a General vehicle class. Here we
find that the base class is the vehicle class and the subclass is the more specific car class.
A subclass must use the extends clause to derive from a super class which must be
written in the header of the subclass definition. The subclass inherits members of the
superclass and hence promotes code reuse. The subclass itself can add its own new
behavior and properties. The java.lang.Object class is always at the top of any Class
inheritance hierarchy.

class Box {

double width;
double height;
double depth;
Box() {
}
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
void getVolume() {
System.out.println("Volume is : " + width * height * depth);
}
}

public class MatchBox extends Box {

double weight;
MatchBox() {
}
MatchBox(double w, double h, double d, double m) {
super(w, h, d);
<font size=-1>

weight = m;
}
public static void main(String args[]) {
MatchBox mb1 = new MatchBox(10, 10, 10, 10);
mb1.getVolume();
System.out.println("width of MatchBox 1 is " + mb1.width);
System.out.println("height of MatchBox 1 is " + mb1.height);
System.out.println("depth of MatchBox 1 is " + mb1.depth);
System.out.println("weight of MatchBox 1 is " + mb1.weight);
}
}

Output

Volume is : 1000.0
width of MatchBox 1 is 10.0
height of MatchBox 1 is 10.0
depth of MatchBox 1 is 10.0
weight of MatchBox 1 is 10.0

Download MatchBox.java

What is not possible using java class Inheritance?

1. Private members of the superclass are not inherited by the subclass and can only be
indirectly accessed.
2. Members that have default accessibility in the superclass are also not inherited by
subclasses in other packages, as these members are only accessible by their simple names
in subclasses within the same package as the superclass.
3. Since constructors and initializer blocks are not members of a class, they are not
inherited by a subclass.
4. A subclass can extend only one superclass

class Vehicle {

// Instance fields
int noOfTyres; // no of tyres
private boolean accessories; // check if accessorees present or not
protected String brand; // Brand of the car
// Static fields
private static int counter; // No of Vehicle objects created
// Constructor
Vehicle() {
System.out.println("Constructor of the Super class called");
noOfTyres = 5;
accessories = true;
brand = "X";
counter++;
}
// Instance methods
public void switchOn() {
accessories = true;
}
public void switchOff() {
accessories = false;
}
public boolean isPresent() {
return accessories;
}
private void getBrand() {
System.out.println("Vehicle Brand: " + brand);
}
// Static methods
public static void getNoOfVehicles() {
System.out.println("Number of Vehicles: " + counter);
}
}

class Car extends Vehicle {

private int carNo = 10;


public void printCarInfo() {
System.out.println("Car number: " + carNo);
System.out.println("No of Tyres: " + noOfTyres); // Inherited.
// System.out.println("accessories: " + accessories); // Not Inherit
System.out.println("accessories: " + isPresent()); // Inherited.
// System.out.println("Brand: " + getBrand()); // Not
Inherited.
System.out.println("Brand: " + brand); // Inherited.
// System.out.println("Counter: " + counter); // Not Inherited.
getNoOfVehicles(); // Inherited.
}
}

public class VehicleDetails { // (3)

public static void main(String[] args) {


new Car().printCarInfo();
}
}

Output

Constructor of the Super class called


Car number: 10
No of Tyres: 5
accessories: true
Brand: X
Number of Vehicles: 1

Download VehicleDetails.java

this and super keywords


The two keywords, this and super to help you explicitly name the field or method that
you want. Using this and super you have full control on whether to call a method or field
present in the same class or to call from the immediate superclass. This keyword is used
as a reference to the current object which is an instance of the current class. The keyword
super also references the current object, but as an instance of the current class’s super
class.

The this reference to the current object is useful in situations where a local variable hides,
or shadows, a field with the same name. If a method needs to pass the current object to
another method, it can do so using the this reference. Note that the this reference cannot
be used in a static context, as static code is not executed in the context of any object.

class Counter {

int i = 0;
Counter increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
}

public class CounterDemo extends Counter {

public static void main(String[] args) {


Counter x = new Counter();
x.increment().increment().increment().print();
}
}

Output

Volume is : 1000.0
width of MatchBox 1 is 10.0
height of MatchBox 1 is 10.0
depth of MatchBox 1 is 10.0
weight of MatchBox 1 is 10.0

Object Reference Type Casting


In java object typecasting one object reference can be type cast into another object
reference. The cast can be to its own class type or to one of its subclass or superclass
types or interfaces. There are compile-time rules and runtime rules for casting in java.

How to Typecast Objects with a dynamically loaded Class ? - The casting of object
references depends on the relationship of the classes involved in the same hierarchy. Any
object reference can be assigned to a reference variable of the type Object, because the
Object class is a superclass of every Java class.
There can be 2 casting java scenarios
· Upcasting
· Downcasting

When we cast a reference along the class hierarchy in a direction from the root class
towards the children or subclasses, it is a downcast. When we cast a reference along the
class hierarchy in a direction from the sub classes towards the root, it is an upcast. We
need not use a cast operator in this case.

The compile-time rules are there to catch attempted casts in cases that are simply not
possible. This happens when we try to attempt casts on objects that are totally unrelated
(that is not subclass super class relationship or a class-interface relationship) At runtime a
ClassCastException is thrown if the object being cast is not compatible with the new type
it is being cast to.

<br /><font size=-1>

Below is an example showing when a ClassCastException can occur during object


casting

//X is a supper class of Y and Z which are sibblings.


public class RunTimeCastDemo {

public static void main(String args[]) {


X x = new X();
Y y = new Y();
Z z = new Z();
X xy = new Y(); // compiles ok (up the hierarchy)
X xz = new Z(); // compiles ok (up the hierarchy)
// Y yz = new Z(); incompatible type (siblings)
// Y y1 = new X(); X is not a Y
// Z z1 = new X(); X is not a Z
X x1 = y; // compiles ok (y is subclass of X)
X x2 = z; // compiles ok (z is subclass of X)
Y y1 = (Y) x; // compiles ok but produces runtime error
Z z1 = (Z) x; // compiles ok but produces runtime error
Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)
// Y y3 = (Y) z; inconvertible types (siblings)
// Z z3 = (Z) y; inconvertible types (siblings)
Object o = z;
Object o1 = (Y) o; // compiles ok but produces runtime error
}
}

Download ClassCastException example Source Code


Casting Object References: Implicit Casting using a
Compiler
In general an implicit cast is done when an Object reference is assigned (cast) to:

* A reference variable whose type is the same as the class from which the object was
instantiated.
An Object as Object is a super class of every Class.
* A reference variable whose type is a super class of the class from which the object was
instantiated.
* A reference variable whose type is an interface that is implemented by the class from
which the object was instantiated.
* A reference variable whose type is an interface that is implemented by a super class of
the class from which the object was instantiated.

Consider an interface Vehicle, a super class Car and its subclass Ford. The following
example shows the automatic conversion of object references handled by the compiler

interface Vehicle {
}
class Car implements Vehicle {
}

class Ford extends Car {


}

Let c be a variable of type Car class and f be of class Ford and v be an vehicle interface
reference. We can assign the Ford reference to the Car variable:
I.e. we can do the following

Example 1
c = f; //Ok Compiles fine

Where c = new Car();


And, f = new Ford();
The compiler automatically handles the conversion (assignment) since the types are
compatible (sub class - super class relationship), i.e., the type Car can hold the type Ford
since a Ford is a Car.

Example 2
v = c; //Ok Compiles fine
c = v; // illegal conversion from interface type to class type results in compilation error

Where c = new Car();


And v is a Vehicle interface reference (Vehicle v)
The compiler automatically handles the conversion (assignment) since the types are
compatible (class – interface relationship), i.e., the type Car can be cast to Vehicle
interface type since Car implements Vehicle Interface. (Car is a Vehicle).

Casting Object References: Explicit Casting

Sometimes we do an explicit cast in java when implicit casts don’t work or are not
helpful for a particular scenario. The explicit cast is nothing but the name of the new
“type” inside a pair of matched parentheses. As before, we consider the same Car and
Ford Class

class Car {
void carMethod(){
}
}

class Ford extends Car {


void fordMethod () {
}
}

We also have a breakingSystem() function which takes Car reference (Superclass


reference) as an input parameter.
The method will invoke carMethod() regardless of the type of object (Car or Ford
Reference) and if it is a Ford object, it will also invoke fordMethod(). We use the
instanceof operator to determine the type of object at run time.

public void breakingSystem (Car obj) {


obj.carMethod();
if (obj instanceof Ford)

((Ford)obj).fordMethod ();
}

To invoke the fordMethod(), the operation (Ford)obj tells the compiler to treat the Car
object referenced by obj as if it is a Ford object. Without the cast, the compiler will give
an error message indicating that fordMethod() cannot be found in the Car definition.

The following program shown illustrates the use of the cast operator with references.

Note: Classes Honda and Ford are Siblings in the class Hierarchy. Both these classes are
subclasses of Class Car. Both Car and HeavyVehicle Class extend Object Class. Any
class that does not explicitly extend some other class will automatically extends the
Object by default. This code instantiates an object of the class Ford and assigns the
object’s reference to a reference variable of type Car. This assignment is allowed as Car
is a superclass of Ford. In order to use a reference of a class type to invoke a method, the
method must be defined at or above that class in the class hierarchy. Hence an object of
Class Car cannot invoke a method present in Class Ford, since the method fordMethod is
not present in Class Car or any of its superclasses. Hence this problem can be colved by a
simple downcast by casting the Car object reference to the Ford Class Object reference as
done in the program. Also an attempt to cast an object reference to its Sibling Object
reference produces a ClassCastException at runtime, although compilation happens
without any error.

class Car extends Object {

void carMethod() {
}
}

class HeavyVehicle extends Object {


}

class Ford extends Car {

void fordMethod() {
System.out.println("I am fordMethod defined in Class Ford");
}
}

class Honda extends Car {

void fordMethod() {
System.out.println("I am fordMethod defined in Class Ford");
}
}

public class ObjectCastingEx {

public static void main(String[] args) {


Car obj = new Ford();
// Following will result in compilation error
// obj.fordMethod(); //As the method fordMethod is undef
for the Car Type
// Following will result in compilation error
// ((HeavyVehicle)obj).fordMethod();
//fordMethod is undefined in the HeavyVeh
Type
// Following will result in compilation error
((Ford) obj).fordMethod();
//Following will compile and run
// Honda hondaObj = (Ford)obj; Cannot convert as they
sibblings
}
}

Download Object Reference Casting Source Code

One common casting that is performed when dealing with collections is, you can cast an
object reference into a String.

import java.util.Vector;

public class StringCastDemo {

public static void main(String args[]) {


String username = "asdf";
String password = "qwer";
Vector v = new Vector();
v.add(username);
v.add(password);
// String u = v.elementAt(0); Cannot convert from object t
String
Object u = v.elementAt(0); //Cast not done
System.out.println("Username : " + u);
String uname = (String) v.elementAt(0); // cast allowed
String pass = (String) v.elementAt(1); // cast allowed
System.out.println();
System.out.println("Username : " + uname);
System.out.println("Password : " + pass);
}
}

Download Object String Casting Source Code

Output

Username : asdf
Username : asdf
Password : qwer

instanceof Operator
The instanceof operator is called the type comparison operator, lets you determine if an
object belongs to a specific class, or implements a specific interface. It returns true if an
object is an instance of the class or if the object implements the interface, otherwise it
returns false.

Below is an example showing the use of instanceof operator


class Vehicle {

String name;
Vehicle() {
name = "Vehicle";
}
}

class HeavyVehicle extends Vehicle {

HeavyVehicle() {
name = "HeavyVehicle";
}
}

class Truck extends HeavyVehicle {

Truck() {
name = "Truck";
}
}

class LightVehicle extends Vehicle {

LightVehicle() {
name = "LightVehicle";
}
}

public class InstanceOfExample {

static boolean result;


static HeavyVehicle hV = new HeavyVehicle();
static Truck T = new Truck();
static HeavyVehicle hv2 = null;
public static void main(String[] args) {
result = hV instanceof HeavyVehicle;
System.out.print("hV is an HeavyVehicle: " + result + "\n");
result = T instanceof HeavyVehicle;
System.out.print("T is an HeavyVehicle: " + result + "\n");
result = hV instanceof Truck;
System.out.print("hV is a Truck: " + result + "\n");
result = hv2 instanceof HeavyVehicle;
System.out.print("hv2 is an HeavyVehicle: " + result + "\n");
hV = T; //Sucessful Cast form child to parent
T = (Truck) hV; //Sucessful Explicit Cast form parent to child
}
}

Download instanceof operator Source Code

Output

hV is an HeavyVehicle: true
T is an HeavyVehicle: true
hV is a Truck: false
hv2 is an HeavyVehicle: false

Note: hv2 does not yet reference an HeavyVehicle object, instanceof returns false. Also
we can’t use instanceof operator with siblings

Abstract Class in java


Java Abstract classes are used to declare common characteristics of subclasses. An
abstract class cannot be instantiated. It can only be used as a superclass for other classes
that extend the abstract class. Abstract classes are declared with the abstract keyword.
Abstract classes are used to provide a template or design for concrete subclasses down
the inheritance tree.

Like any other class, an abstract class can contain fields that describe the characteristics
and methods that describe the actions that a class can perform. An abstract class can
include methods that contain no implementation. These are called abstract methods. The
abstract method declaration must then end with a semicolon rather than a block. If a class
has any abstract methods, whether declared or inherited, the entire class must be declared
abstract. Abstract methods are used to provide a template for the classes that inherit the
abstract methods.

Abstract classes cannot be instantiated; they must be subclassed, and actual


implementations must be provided for the abstract methods. Any implementation
specified can, of course, be overridden by additional subclasses. An object must have an
implementation for all of its methods. You need to create a subclass that provides an
implementation for the abstract method.

A class abstract Vehicle might be specified as abstract to represent the general abstraction
of a vehicle, as creating instances of the class would not be meaningful.

<br /><font size=-1>


abstract class Vehicle {

int numofGears;
String color;
abstract boolean hasDiskBrake();
abstract int getNoofGears();
}

Example of a shape class as an abstract class

abstract class Shape {

public String color;


public Shape() {
}
public void setColor(String c) {
color = c;
}
public String getColor() {
return color;
}
abstract public double area();
}

We can also implement the generic shapes class as an abstract class so that we can draw
lines, circles, triangles etc. All shapes have some common fields and methods, but each
can, of course, add more fields and methods. The abstract class guarantees that each
shape will have the same set of basic properties. We declare this class abstract because
there is no such thing as a generic shape. There can only be concrete shapes such as
squares, circles, triangles etc.

public class Point extends Shape {

static int x, y;
public Point() {
x = 0;
y = 0;
}
public double area() {
return 0;
}
public double perimeter() {
return 0;
}
public static void print() {
System.out.println("point: " + x + "," + y);
}
public static void main(String args[]) {
Point p = new Point();
p.print();
}
}

Output

point: 0, 0

Notice that, in order to create a Point object, its class cannot be abstract. This means that
all of the abstract methods of the Shape class must be implemented by the Point class.

The subclass must define an implementation for every abstract method of the abstract
superclass, or the subclass itself will also be abstract. Similarly other shape objects can be
created using the generic Shape Abstract class.
A big Disadvantage of using abstract classes is not able to use multiple inheritance. In the
sense, when a class extends an abstract class, it can’t extend any other class.

Java Interface
In Java, this multiple inheritance problem is solved with a powerful construct called
interfaces. Interface can be used to define a generic template and then one or more
abstract classes to define partial implementations of the interface. Interfaces just specify
the method declaration (implicitly public and abstract) and can only contain fields (which
are implicitly public static final). Interface definition begins with a keyword interface. An
interface like that of an abstract class cannot be instantiated.

Multiple Inheritance is allowed when extending interfaces i.e. one interface can extend
none, one or more interfaces. Java does not support multiple inheritance, but it allows
you to extend one class and implement many interfaces.

If a class that implements an interface does not define all the methods of the interface,
then it must be declared abstract and the method definitions must be provided by the
subclass that extends the abstract class.

Example 1: Below is an example of a Shape interface

interface Shape {

public double area();


public double volume();
}

Below is a Point class that implements the Shape interface.

public class Point implements Shape {

static int x, y;
public Point() {
x = 0;
y = 0;
}
public double area() {
return 0;
}
public double volume() {
return 0;
}
public static void print() {
System.out.println("point: " + x + "," + y);
}
public static void main(String args[]) {
Point p = new Point();
p.print();
}
}

Similarly, other shape objects can be created by interface programming by implementing


generic Shape Interface.

Example 2: Below is a java interfaces program showing the power of interface


programming in java

Listing below shows 2 interfaces and 4 classes one being an abstract class.
Note: The method toString in class A1 is an overridden version of the method defined in
the class named Object. The classes B1 and C1 satisfy the interface contract. But since
the class D1 does not define all the methods of the implemented interface I2, the class D1
is declared abstract.
Also,
i1.methodI2() produces a compilation error as the method is not declared in I1 or any of
its super interfaces if present. Hence a downcast of interface reference I1 solves the
problem as shown in the program. The same problem applies to i1.methodA1(), which is
again resolved by a downcast.

When we invoke the toString() method which is a method of an Object, there does not
seem to be any problem as every interface or class extends Object and any class can
override the default toString() to suit your application needs. ((C1)o1).methodI1()
compiles successfully, but produces a ClassCastException at runtime. This is because B1
does not have any relationship with C1 except they are “siblings”. You can’t cast siblings
into one another.

When a given interface method is invoked on a given reference, the behavior that results
will be appropriate to the class from which that particular object was instantiated. This is
runtime polymorphism based on interfaces and overridden methods.

interface I1 {

void methodI1(); // public static by default


}

interface I2 extends I1 {

void methodI2(); // public static by default


}

class A1 {

public String methodA1() {


String strA1 = "I am in methodC1 of class A1";
return strA1;
}
public String toString() {
return "toString() method of class A1";
}
}

class B1 extends A1 implements I2 {

public void methodI1() {


System.out.println("I am in methodI1 of class B1");
}
public void methodI2() {
System.out.println("I am in methodI2 of class B1");
}
}

class C1 implements I2 {

public void methodI1() {


System.out.println("I am in methodI1 of class C1");
}
public void methodI2() {
System.out.println("I am in methodI2 of class C1");
}
}

// Note that the class is declared as abstract as it does not


// satisfy the interface contract
abstract class D1 implements I2 {

public void methodI1() {


}
// This class does not implement methodI2() hence declared abstract.
}

public class InterFaceEx {

public static void main(String[] args) {


I1 i1 = new B1();
i1.methodI1(); // OK as methodI1 is present in B1
// i1.methodI2(); Compilation error as methodI2 not present in I1
// Casting to convert the type of the reference from type I1 to type I2
((I2) i1).methodI2();
I2 i2 = new B1();
i2.methodI1(); // OK
i2.methodI2(); // OK
// Does not Compile as methodA1() not present in interface reference I1
// String var = i1.methodA1();
// Hence I1 requires a cast to invoke methodA1
String var2 = ((A1) i1).methodA1();
System.out.println("var2 : " + var2);
String var3 = ((B1) i1).methodA1();
System.out.println("var3 : " + var3);
String var4 = i1.toString();
System.out.println("var4 : " + var4);
String var5 = i2.toString();
System.out.println("var5 : " + var5);
I1 i3 = new C1();
String var6 = i3.toString();
System.out.println("var6 : " + var6); // It prints the Object toString()
method
Object o1 = new B1();
// o1.methodI1(); does not compile as Object class does not define
// methodI1()
// To solve the probelm we need to downcast o1 reference. We can do it
// in the following 4 ways
((I1) o1).methodI1(); // 1
((I2) o1).methodI1(); // 2
((B1) o1).methodI1(); // 3
/*
*
* B1 does not have any relationship with C1 except they are "siblings".
*
* Well, you can't cast siblings into one another.
*
*/
// ((C1)o1).methodI1(); Produces a ClassCastException
}
}

Output

I am in methodI1 of class B1
I am in methodI2 of class B1
I am in methodI1 of class B1
I am in methodI2 of class B1
var2 : I am in methodC1 of class A1
var3 : I am in methodC1 of class A1
var4 : toString() method of class A1
var5 : toString() method of class A1
var6 : C1@190d11
I am in methodI1 of class B1
I am in methodI1 of class B1
I am in methodI1 of class B1

Method Overriding is achieved when a subclass overrides non-static methods defined in


the superclass, following which the new method implementation in the subclass that is
executed.

The new method definition must have the same method signature (i.e., method name and
parameters) and return type. Only parameter types and return type are chosen as criteria
for matching method signature. So if a subclass has its method parameters as final it
doesn’t really matter for method overriding scenarios as it still holds true. The new
method definition cannot narrow the accessibility of the method, but it can widen it. The
new method definition can only specify all or none, or a subset of the exception classes
(including their subclasses) specified in the throws clause of the overridden method in the
super class

A program to explain the different concepts of Java Method Overridding

class CustomException extends Exception {

class SuperClassWithDifferentMethods {

protected int field1 = 10;


protected static int field2 = 20;
public void method1() {
System.out.println("SuperClassWithDifferentMethods.method1()");
}
public final void method2() {
System.out.println("SuperClassWithDifferentMethods.method2()");
}
private void method3() {
System.out.println("SuperClassWithDifferentMethods.method3()");
}
private final void method4() {
<font size=-1>

System.out.println("SuperClassWithDifferentMethods.method4()");
}
public static void method5() {
System.out.println("SuperClassWithDifferentMethods.method5()");
}
public void method6() throws Exception {
System.out.println("SuperClassWithDifferentMethods.method6()");
}
private void method7() {
System.out.println("SuperClassWithDifferentMethods.method7()");
}
private void method8(int x) {
System.out.println("SuperClassWithDifferentMethods.method8()");
}
public static void method9() {
System.out.println("SuperClassWithDifferentMethods.method9()");
}
}

class OverridingClass extends SuperClassWithDifferentMethods {

public int field1 = 30;


public static int field2 = 40;
public void method1() {
System.out.println("OverridingClass.method1()");
}
//We can't override a public final method
/* public final void method2(){

System.out.println("OverridingClass.method2()");
}*/
private void method3() {
System.out.println("OverridingClass.method3()");
}
private final void method4() {
System.out.println("OverridingClass.method4()");
}
public static void method5() {
System.out.println("OverridingClass.method5()");
}
public void method6() throws CustomException {
System.out.println("OverridingClass.method6()");
}
public void method7() {
System.out.println("OverridingClass.method7()");
}
public void method8(final int x) {
System.out.println("OverridingClass.method8()");
}
//A static method cannot be overridden to be non-static instance method
/*public void method9() {

System.out.println("OverridingClass.method9()");

}*/
}

public class MethodOverridingDemo {

public static void main(String[] args) {


OverridingClass oc1 = new OverridingClass();
SuperClassWithDifferentMethods sc3 = new OverridingClass();
oc1.method1();
oc1.method2();
// Since its private, the below 2 methods are not visible
/* oc1.method3();

oc1.method4();*/
oc1.method5();
try {
oc1.method6();
} catch (CustomException e) {
e.printStackTrace();
}
oc1.method7();
oc1.method8(100);
System.out.println("oc1.field1 : " + oc1.field1);
System.out.println("oc1.field2 : " + oc1.field2);
System.out.println("sc3.field1 : " + sc3.field1);
System.out.println("sc3.field2 : " + sc3.field2);
sc3.method5();
OverridingClass overClass = new OverridingClass();
SuperClassWithDifferentMethods supClass = (SuperClassWithDifferentMethods)
overClass;
supClass.method5();
supClass.method1();
}
}

Output

OverridingClass.method1()
SuperClassWithDifferentMethods.method2()
OverridingClass.method5()
OverridingClass.method6()
OverridingClass.method7()
OverridingClass.method8()
oc1.field1 : 30
oc1.field2 : 40
sc3.field1 : 10
sc3.field2 : 20
SuperClassWithDifferentMethods.method5()
SuperClassWithDifferentMethods.method5()
OverridingClass.method1()

Download MethodOverridingDemo.java

The new method definitions in the subclass OverridingClass have the same signature and
the same return type as the methods in the superclass SuperClassWithDifferentMethods.
The new overridden method6 definition specifies a subset of the exceptions
(CustomException). The new overridden method7 definition also widens the accessibility
to public from private. The overriding method8 also declares the parameter to be final,
which is not a part of the method signature and Method Overriding holds good. A static
method cannot be overridden to be non-static instance method as shown in the overridden
method declaration of method9. A static method is class-specific and not part of any
object, while overriding methods are invoked on behalf of objects of the subclass. There
are no such restrictions on the fields, as for fields only the field names matter. A final
method cannot be overridden, an attempt to which will result in a compile-time error. A
private method is not accessible outside the class in which it is defined; therefore, a
subclass cannot override it.

A subclass must use the ‘super’ keyword in order to invoke an overridden method in the
superclass. A subclass cannot override fields of the superclass, but it can hide them. Code
in the subclass can use the keyword super to access members, including hidden fields.

The following distinction between invoking instance methods on an object and accessing
fields of an object must be noted. When an instance method is invoked on an object using
a reference, it is the class of the current object denoted by the reference, not the type of
the reference, that determines which method implementation will be executed. When a
field of an object is accessed using a reference, it is the type of the reference, not the class
of the current object denoted by the reference, that determines which field will actually
be accessed. This is demonstrated in the above program

Implementing toString method in java is done by overriding the Object’s toString


method. The java toString() method is used when we need a string representation of an
object. It is defined in Object class. This method can be overridden to customize the
String representation of the Object. Below is a program showing the use of the Object’s
Default toString java method.

class PointCoordinates {

private int x, y;
public PointCoordinates(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}

public class ToStringDemo {

public static void main(String args[]) {


PointCoordinates point = new PointCoordinates(10, 10);
// using the Default Object.toString() Method
System.out.println("Object toString() method : " + point);
// implicitly call toString() on object as part of string concatenation
String s = point + " testing";
System.out.println(s);
}
}

Download ToStringDemo.java

When you run the ToStringDemo program, the output is:


Object toString() method : PointCoordinates@119c082

<br /><font size=-1>

PointCoordinates@119c082 testing

In the above example when we try printing PointCoordinates object, it internally calls the
Object’s toString() method as we have not overridden the java toString() method. Since
out example has no toString method, the default one in Object is used. The format of the
default toString method of the Object is as shown below.
Class Name, “@”, and the hex version of the object’s hashcode concatenated into a
string.
The default hashCode method in Object is typically implemented by converting the
memory address of the object into an integer.

Below is an example shown of the same program by Overriding the default Object
toString() method. The toString() method must be descriptive and should generally cover
all the contents of the object.

class PointCoordinates {

private int x, y;
public PointCoordinates(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
// Custom toString() Method.
public String toString() {
return "X=" + x + " " + "Y=" + y;
}
}

public class ToStringDemo2 {

public static void main(String args[]) {


PointCoordinates point = new PointCoordinates(10, 10);
System.out.println(point);
String s = point + " testing";
System.out.println(s);
}
}

Download ToStringDemo2.java

When you run the ToStringDemo2 program, the output is:

X=10 Y=10
X=10 Y=10 testing

Strings in java
Java String Class is immutable, i.e. Strings in java, once created and initialized, cannot
be changed on the same reference. A java.lang.String class is final which implies no
class and extend it. The java.lang.String class differs from other classes, one difference
being that the String objects can be used with the += and + operators for concatenation.
Two useful methods for String objects are equals( ) and substring( ). The equals( )
method is used for testing whether two Strings contain the same value. The substring( )
method is used to obtain a selected portion of a String.

Java.lang.String class creation


A simple String can be created using a string literal enclosed inside double quotes as
shown;

String str1 = “My name is bob”;

Since a string literal is a reference, it can be manipulated like any other String reference.
The reference value of a string literal can be assigned to another String reference.

If 2 or more Strings have the same set of characters in the same sequence then they share
the same reference in memory. Below illustrates this phenomenon.

String str1 = “My name is bob”;


String str2 = “My name is bob”;
String str3 = “My name ”+ “is bob”; //Compile time expression
String name = “bob”;
String str4 = “My name is” + name;
String str5 = new String(“My name is bob”);

<br /><font size=-1>

In the above code all the String references str1, str2 and str3 denote the same String
object, initialized with the character string: “My name is bob”. But the Strings str4 and
str5 denote new String objects.

Constructing String objects can also be done from arrays of bytes, arrays of characters, or
string buffers. A simple way to convert any primitive value to its string representation is
by concatenating it with the empty string (”"), using the string concatenation operator (+).

public class StringsDemo {

public static void main(String[] args) {

byte[] bytes = {2, 4, 6, 8};

char[] characters = {'a', 'b', 'C', 'D'};

StringBuffer strBuffer = new StringBuffer("abcde");

// Examples of Creation of Strings


String byteStr = new String(bytes);

String charStr = new String(characters);

String buffStr = new String(strBuffer);

System.out.println("byteStr : "+byteStr);

System.out.println("charStr : "+charStr);

System.out.println("buffStr : "+buffStr);

Java String compare to determine Equality


java string compare can be done in many ways as shown below. Depending on the type
of java string compare you need, each of them is used.

* == Operator
* equals method
* compareTo method

Comparing using the == Operator

The == operator is used when we have to compare the String object references. If two
String variables point to the same object in memory, the comparison returns true.
Otherwise, the comparison returns false. Note that the ‘==’ operator does not compare the
content of the text present in the String objects. It only compares the references the 2
Strings are pointing to. The following Program would print “The strings are unequal” In
the first case and “The strings are equal” in the second case.

<br /><font size=-1>

public class StringComparision1 {

public static void main(String[] args) {


String name1 = "Bob";
String name2 = new String("Bob");
String name3 = "Bob";
// 1st case
if (name1 == name2) {
System.out.println("The strings are equal.");
} else {
System.out.println("The strings are unequal.");
}
// 2nd case
if (name1 == name3) {
System.out.println("The strings are equal.");
} else {
System.out.println("The strings are unequal.");
}
}
}

Download StringComparision1.java

Comparing using the equals Method

The equals method is used when we need to compare the content of the text present in the
String objects. This method returns true when two String objects hold the same content
(i.e. the same values). The following Program would print “The strings are unequal” In
the first case and “The strings are equal” in the second case.

public class StringComparision2 {

public static void main(String[] args) {


String name1 = "Bob";
String name2 = new String("Bob1");
String name3 = "Bob";
// 1st case
if (name1.equals(name2)) {
System.out.println("The strings are equal.");
} else {
System.out.println("The strings are unequal.");
}
// 2nd case
if (name1.equals(name3)) {
System.out.println("The strings are equal.");
} else {
System.out.println("The strings are unequal.");
}
}
}

Download StringComparision2.java

Comparing using the compareTo Method

The compareTo method is used when we need to determine the order of Strings
lexicographically. It compares char values similar to the equals method. The compareTo
method returns a negative integer if the first String object precedes the second string. It
returns zero if the 2 strings being compared are equal. It returns a positive integer if the
first String object follows the second string. The following Program would print “name2
follows name1” In the first case and “name1 follows name3” in the second case.

public class StringComparision3 {

public static void main(String[] args) {


String name1 = "bob";
String name2 = new String("cob");
String name3 = "Bob";
// 1st case
if (name1.compareTo(name2) == 0) {
System.out.println("The strings are equal.");
} else if (name1.compareTo(name2) < 0) {
System.out.println("name2 follows name1");
} else {
System.out.println("name1 follows name2");
}
// 2nd case. Comparing Ascii Uppercase will be smaller then Lower Case
if (name1.compareTo(name3) == 0) {
System.out.println("The strings are equal.");
} else if (name1.compareTo(name3) < 0) {
System.out.println("name3 follows name1");
} else {
System.out.println("name1 follows name3");
}
}
}

StringBuffer Class
StringBuffer class is a mutable class unlike the String class which is immutable. Both the
capacity and character string of a StringBuffer Class. StringBuffer can be changed
dynamically. String buffers are preferred when heavy modification of character strings is
involved (appending, inserting, deleting, modifying etc).

Strings can be obtained from string buffers. Since the StringBuffer class does not
override the equals() method from the Object class, contents of string buffers should be
converted to String objects for string comparison.
A StringIndexOutOfBoundsException is thrown if an index is not valid when using
wrong index in String Buffer manipulations

Creation of StringBuffers
StringBuffer Constructors

public class StringBufferDemo {

public static void main(String[] args) {


// Examples of Creation of Strings
StringBuffer strBuf1 = new StringBuffer("Bob");
StringBuffer strBuf2 = new StringBuffer(100); //With capacity 100
StringBuffer strBuf3 = new StringBuffer(); //Default Capacity 16
System.out.println("strBuf1 : " + strBuf1);
System.out.println("strBuf2 capacity : " + strBuf2.capacity());
System.out.println("strBuf3 capacity : " + strBuf3.capacity());
}
}

Download StringBufferDemo.java

<br /><font size=-1>

Output

strBuf1 : Bob
strBuf2 capacity : 100
strBuf3 capacity : 16

StringBuffer Functions
The following program explains the usage of the some of the basic StringBuffer methods
like ;

1. capacity()
Returns the current capacity of the String buffer.

2. length()
Returns the length (character count) of this string buffer.

3. charAt(int index)
The specified character of the sequence currently represented by the string buffer, as
indicated by the index argument, is returned.

4. setCharAt(int index, char ch)


The character at the specified index of this string buffer is set to ch

5. toString()
Converts to a string representing the data in this string buffer

6. insert(int offset, char c)


Inserts the string representation of the char argument into this string buffer.
Note that the StringBuffer class has got many overloaded ‘insert’ methods which can be
used based on the application need.

7. delete(int start, int end)


Removes the characters in a substring of this StringBuffer
8. replace(int start, int end, String str)
Replaces the characters in a substring of this StringBuffer with characters in the specified
String.

9. reverse()
The character sequence contained in this string buffer is replaced by the reverse of the
sequence.

10. append(String str)


Appends the string to this string buffer.
Note that the StringBuffer class has got many overloaded ‘append’ methods which can be
used based on the application need.

11. setLength(int newLength)


Sets the length of this String buffer.

public class StringBufferFunctionsDemo {

public static void main(String[] args) {


// Examples of Creation of Strings
StringBuffer strBuf1 = new StringBuffer("Bobby");
StringBuffer strBuf2 = new StringBuffer(100); //With capacity 100
StringBuffer strBuf3 = new StringBuffer(); //Default Capacity 16
System.out.println("strBuf1 : " + strBuf1);
System.out.println("strBuf1 capacity : " + strBuf1.capacity());
System.out.println("strBuf2 capacity : " + strBuf2.capacity());
System.out.println("strBuf3 capacity : " + strBuf3.capacity());
System.out.println("strBuf1 length : " + strBuf1.length());
System.out.println("strBuf1 charAt 2 : " + strBuf1.charAt(2));
// A StringIndexOutOfBoundsException is thrown if the index is not
valid.
strBuf1.setCharAt(1, 't');
System.out.println("strBuf1 after setCharAt 1 to t is : "
+ strBuf1);
System.out
.println("strBuf1 toString() is : " + strBuf1.toString())
strBuf3.append("beginner-java-tutorial");
System.out.println("strBuf3 when appended with a String : "
+ strBuf3.toString());
strBuf3.insert(1, 'c');
System.out.println("strBuf3 when c is inserted at 1 : "
+ strBuf3.toString());
strBuf3.delete(1, 'c');
System.out.println("strBuf3 when c is deleted at 1 : "
+ strBuf3.toString());
strBuf3.reverse();
System.out.println("Reversed strBuf3 : " + strBuf3);
strBuf2.setLength(5);
strBuf2.append("jdbc-tutorial");
System.out.println("strBuf2 : " + strBuf2);
// We can clear a StringBuffer using the following line
strBuf2.setLength(0);
System.out.println("strBuf2 when cleared using setLength(0): "
+ strBuf2);
}
}

Exceptions in java are any abnormal, unexpected events or extraordinary conditions that
may occur at runtime. They could be file not found exception, unable to get connection
exception and so on. On such conditions java throws an exception object. Java
Exceptions are basically Java objects. No Project can never escape a java error exception.

Java exception handling is used to handle error conditions in a program systematically by


taking the necessary action. Exception handlers can be written to catch a specific
exception such as Number Format exception, or an entire group of exceptions by using a
generic exception handlers. Any exceptions not specifically handled within a Java
program are caught by the Java run time environment

An exception is a subclass of the Exception/Error class, both of which are subclasses of


the Throwable class. Java exceptions are raised with the throw keyword and handled
within a catch block.

A Program Showing How the JVM throws an Exception at runtime

public class DivideException {

public static void main(String[] args) {


division(100,4); // Line 1
division(100,0); // Line 2
System.out.println("Exit main().");
}

public static void division(int totalSum, int totalNumber) {


<font size=-1>

System.out.println("Computing Division.");
int average = totalSum/totalNumber;
System.out.println("Average : "+ average);
}
}

Download DivideException.java

An ArithmeticException is thrown at runtime when Line 11 is executed because integer


division by 0 is an illegal operation. The “Exit main()” message is never reached in the
main method
Output

Computing Division.
java.lang.ArithmeticException: / by zero
Average : 25
Computing Division.
at DivideException.division(DivideException.java:11)
at DivideException.main(DivideException.java:5)
Exception in thread “main”

Exceptions in Java
Throwable Class

The Throwable class provides a String variable that can be set by the subclasses to
provide a detail message that provides more information of the exception occurred. All
classes of throwables define a one-parameter constructor that takes a string as the detail
message.

The class Throwable provides getMessage() function to retrieve an exception. It has a


printStackTrace() method to print the stack trace to the standard error stream. Lastly It
also has a toString() method to print a short description of the exception. For more
information on what is printed when the following messages are invoked, please refer the
java docs.

Syntax

String getMessage()

void printStackTrace()

String toString()

Class Exception

The class Exception represents exceptions that a program faces due to abnormal or
special conditions during execution. Exceptions can be of 2 types: Checked (Compile
time Exceptions)/ Unchecked (Run time Exceptions).

Class RuntimeException

Runtime exceptions represent programming errors that manifest at runtime. For example
ArrayIndexOutOfBounds, NullPointerException and so on are all subclasses of the
java.lang.RuntimeException class, which is a subclass of the Exception class. These are
basically business logic programming errors.
Class Error

Errors are irrecoverable condtions that can never be caught. Example: Memory leak,
LinkageError etc. Errors are direct subclass of Throwable class.

Checked and Unchecked Exceptions

Checked exceptions are subclass’s of Exception excluding class RuntimeException and


its subclasses. Checked Exceptions forces programmers to deal with the exception that
may be thrown. Example: Arithmetic exception. When a checked exception occurs in a
method, the method must either catch the exception and take the appropriate action, or
pass the exception on to its caller

Unchecked exceptions are RuntimeException and any of its subclasses. Class Error and
its subclasses also are unchecked. Unchecked exceptions , however, the compiler doesn’t
force the programmers to either catch the exception or declare it in a throws clause. In
fact, the programmers may not even know that the exception could be thrown. Example:
ArrayIndexOutOfBounds Exception. They are either irrecoverable (Errors) and the
program should not attempt to deal with them, or they are logical programming errors.
(Runtime Exceptions). Checked exceptions must be caught at compile time. Runtime
exceptions do not need to be. Errors often cannot be.

Exception Statement Syntax

Exceptions are handled using a try-catch-finally construct, which has the Syntax

try {
<code>
} catch (<exception type1> <parameter1>) { // 0 or more
<statements>
}
} finally { // finally block
<statements>
}

try Block
The java code that you think may produce an exception is placed within a try block for a
suitable catch block to handle the error.

If no exception occurs the execution proceeds with the finally block else it will look for
the
matching catch block to handle the error. Again if the matching catch handler is not
found execution
proceeds with the finally block and the default exception handler throws an exception.. If
an exception is
generated within the try block, the remaining statements in the try block are not executed.
catch Block
Exceptions thrown during execution of the try block can be caught and handled in a catch
block. On exit from a catch block, normal execution continues and the finally block is
executed
(Though the catch block throws an exception).

finally Block
A finally block is always executed, regardless of the cause of exit from the try block, or
whether any catch block was executed. Generally finally block is used for freeing
resources, cleaning up, closing connections etc. If the finally clock executes a control
transfer statement such as a return or a break statement, then this control
statement determines how the execution will proceed regardless of any return or control
statement present in the try or catch.

The following program illustrates the scenario.

try {
<code>
} catch (<exception type1> <parameter1>) { // 0 or more
<statements>

}
} finally { // finally block
<statements>
}

Download DivideException2.java

Output

Computing Division.
Exception : / by zero
Finally Block Executes. Exception Occurred
result : -1

Below is a program showing the Normal Execution of the Program.

Please note that no NullPointerException is generated as was expected by most people

public class DivideException2 {

public static void main(String[] args) {


int result = division(100,0); // Line 2
System.out.println("result : "+result);
}

public static int division(int totalSum, int totalNumber) {


int quotient = -1;
System.out.println("Computing Division.");
try{
quotient = totalSum/totalNumber;

}
catch(Exception e){
System.out.println("Exception : "+ e.getMessage());
}
finally{
if(quotient != -1){
System.out.println("Finally Block Executes");
System.out.println("Result : "+ quotient);
}else{
System.out.println("Finally Block Executes. Exception
Occurred");
return quotient;
}

}
return quotient;
}
}

Output

null (And not NullPointerException)

Rules for try, catch and finally Blocks


1. For each try block there can be zero or more catch blocks, but only
one finally block.

2. The catch blocks and finally block must always appear in conjunction
with a try block.

3. A try block must be followed by either at least one catch block or


one finally block.

4. The order exception handlers in the catch block must be from the most
specific exception
Java exception handling mechanism enables you to catch exceptions in java using try,
catch, finally block. be An exception consists of a block of code called a try block, a
block of code called a catch block, and the finally block. Let’s examine each of these in
detail.

public class DivideException1 {

public static void main(String[] args) {


division(100,0); // Line 2
System.out.println("Main Program Terminating");
}

public static void division(int totalSum, int totalNumber) {


int quotient = -1;
System.out.println("Computing Division.");
try{
quotient = totalSum/totalNumber;
System.out.println("Result is : "+quotient);
}
<font size=-1>

catch(Exception e){
System.out.println("Exception : "+ e.getMessage());
}
finally{
if(quotient != -1){
System.out.println("Finally Block Executes");
System.out.println("Result : "+ quotient);
}else{
System.out.println("Finally Block Executes. Exception
Occurred");
}

}
}
}

Download DivideException1.javaOutput

Output

Computing Division.
Exception : / by zero
Finally Block Executes. Exception Occurred
Main Program Terminating
As shown above when the divide by zero calculation is attempted, an
ArithmeticException is thrown. and program execution is transferred to the catch
statement. Because the exception is thrown from the try block, the remaining statements
of the try block
are skipped. The finally block executes.

Defining new EXCEPTIONS!!


We can have our own custom Exception handler to deal with special exception conditions
instead of using existing exception classes. Custom exceptions usually extend the
Exception class directly or any subclass of Exception (making it checked).
The super() call can be used to set a detail message in the throwable. Below is an
example that shows the use of Custom exception’s along with how the throw and throws
clause are used.

class BadTemperature extends Exception{


BadTemperature( String reason ){
super ( reason );
}
}

class TooHot extends BadTemperature{

TooHot(){
super ("Default messaeg : Hot");
}

TooHot(String message){
super (message);
}
}

class TooCold extends BadTemperature{

TooCold(){
super ("Default messaeg : Cold");
}

TooCold(String message){
super (message);
}
}

class TempertureObject{

int temperature;

TempertureObject( int temp ) {


temperature = temp;
}

void test() throws TooHot, TooCold {


if ( temperature < 70 ) throw new TooCold("Very Cold");
if ( temperature > 80 ) throw new TooHot("Very Hot");
}
}

public class ExceptionExample1{

private static void temperatureReport( TempertureObject batch ){


try{ batch.test();
System.out.println( "Perfect Temperature" );
}
catch ( BadTemperature bt ){
System.out.println( bt.getMessage( ) );
}
}

public static void main( String[] args ){


temperatureReport( new TempertureObject( 100 ) );
temperatureReport( new TempertureObject( 50 ) );
temperatureReport( new TempertureObject( 75 ) );
}
}

Download ExceptionExample.javaOutput

Output

Very Hot
Very Cold
Perfect Temperature

throw, throws statement

A program can explicitly throw an exception using the throw statement besides the
implicit exception thrown.

The general format of the throw statement is as follows:

throw <exception reference>;

The Exception reference must be of type Throwable class or one of its subclasses. A
detail message can be passed to the constructor when the exception object is created.
throw new TemperatureException(”Too hot”);

A throws clause can be used in the method prototype.

Method() throws <ExceptionType1>,…, <ExceptionTypen> {

Each <ExceptionTypei> can be a checked or unchecked or sometimes even a custom


Exception. The exception type specified in the throws clause in the method prototype can
be a super class type of the actual exceptions thrown. Also an overriding method cannot
allow more checked exceptions in its throws clause than the inherited method does.

When an exception is thrown, normal execution is suspended. The runtime system


proceeds to find a matching catch block that can handle the exception. Any associated
finally block of a try block encountered along the search path is executed. If no handler is
found, then the exception is dealt with by the default exception handler at the top level. If
a handler is found, execution resumes with the code in its catch block. Below is an
example to show the use of a throws and a throw statement.

public class DivideException3 {

public static void main(String[] args) {


try{
int result = division(100,10);
result = division(100,0);
System.out.println("result : "+result);
}
catch(ArithmeticException e){
System.out.println("Exception : "+ e.getMessage());
}
}

public static int division(int totalSum, int totalNumber) throws


ArithmeticException {
int quotient = -1;
System.out.println("Computing Division.");
try{
if(totalNumber == 0){
throw new ArithmeticException("Division attempt by 0")
}
quotient = totalSum/totalNumber;

}
finally{
if(quotient != -1){
System.out.println("Finally Block Executes");
System.out.println("Result : "+ quotient);
}else{
System.out.println("Finally Block Executes. Exception
Occurred");
}

}
return quotient;
}
}

Download DivideException3.javaOutput

Output

Computing Division.
Finally Block Executes
Result : 10
Computing Division.
Finally Block Executes. Exception Occurred
Exception : Division attempt by 0

Using break and return with Exceptions

This example demonstrates the use of the break, continue and return statements with
exceptions. Note that the finally block is executed always except when the return
statement is executed.

public class ExceptionExample6 {

public static void main(String[] args) {

int x = 10, y = 2;
int counter = 0;
boolean flag = true;
while (flag) {
start:
try {
if ( y > 1 )
break start;
if ( y < 0 )
return;
x = x / y;
System.out.println ( "x : " + x + " y : "+y );
}
catch ( Exception e ) {
System.out.println ( e.getMessage() );
}
finally {
++counter;
System.out.println ( "Counter : " + counter );
}
--y;
}
}
}

Download ExceptionExample6.javaOutput

Output

Counter : 1
x : 10 y : 1
Counter : 2
/ by zero
Counter : 3
Counter : 4

Handling Multiple Exceptions

It should be known by now that we can have multiple catch blocks for a particular try
block to handle many different kind of exceptions that can be generated. Below is a
program to demonstrate the use of multiple catch blocks.

import java.io.DataInputStream;
import java.io.IOException;

import javax.swing.JOptionPane;
public class ExceptionExample7{
static int numerator, denominator;

public ExceptionExample7( int t, int b ){


numerator = t;
denominator = b;
}

public int divide( ) throws ArithmeticException{


return numerator/denominator;
}

public static void main( String args[] ){


String num, denom;

num = JOptionPane.showInputDialog(null, "Enter the Numerator");


denom = JOptionPane.showInputDialog(null, "Enter the Denominator");

try{
numerator = Integer.parseInt( num );
denominator = Integer.parseInt( denom );
}
catch ( NumberFormatException nfe ){
System.out.println( "One of the inputs is not an
integer" );
return;
}
catch ( Exception e ){
System.out.println( "Exception: " + e.getMessage( ) );
return;
}

ExceptionExample7 d = new ExceptionExample7( numerator,


denominator );
try{
double result = d.divide( );
JOptionPane.showMessageDialog(null, "Result : " + result
}
catch ( ArithmeticException ae ){
System.out.println( "You can't divide by zero" );
}
finally{
System.out.println( "Finally Block is always Executed"
}
}
}

Introduction to Threads
Multithreading refers to two or more tasks executing concurrently within a single
program. A thread is an independent path of execution within a program. Many threads
can run concurrently within a program. Every thread in Java is created and controlled by
the java.lang.Thread class. A Java program can have many threads, and these threads
can run concurrently, either asynchronously or synchronously.

Multithreading has several advantages over Multiprocessing such as;

• Threads are lightweight compared to processes


• Threads share the same address space and therefore can share both data and code
• Context switching between threads is usually less expensive than between
processes
• Cost of thread intercommunication is relatively low that that of process
intercommunication
• Threads allow different tasks to be performed concurrently.

The following figure shows the methods that are members of the Object and Thread
Class.

Thread Creation
There are two ways to create thread in java;

• Implement the Runnable interface (java.lang.Runnable)


• By Extending the Thread class (java.lang.Thread)

Implementing the Runnable Interface


<br /><font size=-1>

The Runnable Interface Signature

public interface Runnable {

void run();

One way to create a thread in java is to implement the Runnable Interface and then
instantiate an object of the class. We need to override the run() method into our class
which is the only method that needs to be implemented. The run() method contains the
logic of the thread.

The procedure for creating threads based on the Runnable interface is as follows:

1. A class implements the Runnable interface, providing the run() method that will be
executed by the thread. An object of this class is a Runnable object.
2. An object of Thread class is created by passing a Runnable object as argument to the
Thread constructor. The Thread object now has a Runnable object that implements the
run() method.

3. The start() method is invoked on the Thread object created in the previous step. The
start() method returns immediately after a thread has been spawned.

4. The thread ends when the run() method ends, either by normal completion or by
throwing an uncaught exception.

Below is a program that illustrates instantiation and running of threads using the runnable
interface instead of extending the Thread class. To start the thread you need to invoke the
start() method on your object.

class RunnableThread implements Runnable {

Thread runner;
public RunnableThread() {
}
public RunnableThread(String threadName) {
runner = new Thread(this, threadName); // (1) Create a new thread.
System.out.println(runner.getName());
runner.start(); // (2) Start the thread.
}
public void run() {
//Display info about this particular thread
System.out.println(Thread.currentThread());
}
}

public class RunnableExample {

public static void main(String[] args) {


Thread thread1 = new Thread(new RunnableThread(), "thread1");
Thread thread2 = new Thread(new RunnableThread(), "thread2");
RunnableThread thread3 = new RunnableThread("thread3");
//Start the threads
thread1.start();
thread2.start();
try {
//delay for one second
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
}
//Display info about the main thread
System.out.println(Thread.currentThread());
}
}

Output
thread3
Thread[thread1,5,main]
Thread[thread2,5,main]
Thread[thread3,5,main]
Thread[main,5,main]private

Download Runnable Thread Program Example

This approach of creating a thread by implementing the Runnable Interface must be used
whenever the class being used to instantiate the thread object is required to extend some
other class.

Extending Thread Class


The procedure for creating threads based on extending the Thread is as follows:

1. A class extending the Thread class overrides the run() method from the Thread class to
define the code executed by the thread.

2. This subclass may call a Thread constructor explicitly in its constructors to initialize
the thread, using the super() call.

3. The start() method inherited from the Thread class is invoked on the object of the class
to make the thread eligible for running.

Below is a program that illustrates instantiation and running of threads by extending the
Thread class instead of implementing the Runnable interface. To start the thread you need
to invoke the start() method on your object.

class XThread extends Thread {

XThread() {
}
XThread(String threadName) {
super(threadName); // Initialize thread.
System.out.println(this);
start();
}
public void run() {
//Display info about this particular thread
System.out.println(Thread.currentThread().getName());
}
}

public class ThreadExample {

public static void main(String[] args) {


Thread thread1 = new Thread(new XThread(), "thread1");
Thread thread2 = new Thread(new XThread(), "thread2");
// The below 2 threads are assigned default names
Thread thread3 = new XThread();
Thread thread4 = new XThread();
Thread thread5 = new XThread("thread5");
//Start the threads
thread1.start();
thread2.start();
thread3.start();
thread4.start();
try {
//The sleep() method is invoked on the main thread to cause a one second delay.
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
}
//Display info about the main thread
System.out.println(Thread.currentThread());
}
}
Output

Thread[thread5,5,main]
thread1
thread5
thread2
Thread-3
Thread-2
Thread[main,5,main]

Download Java Thread Program Example

When creating threads, there are two reasons why implementing the Runnable interface
may be preferable to extending the Thread class:

• Extending the Thread class means that the subclass cannot extend any other class,
whereas a class implementing the Runnable interface
has this option.
• A class might only be interested in being runnable, and therefore, inheriting the
full overhead of the Thread class would be excessive.

An example of an anonymous class below shows how to create a thread and start it:

( new Thread() {

public void run() {

for(;;) System.out.println(”Stop the world!”);

}
}

).start();

Vous aimerez peut-être aussi