Sunteți pe pagina 1din 493

1

Java Tutorial
1. Java - What, Where and Why?
2. What is Java
3. Where Java is used
4. Java Applications
Java Tutorial or Core Java Tutorial is a widely used robust technology. Let's start learning of
java from basic questions like what is java tutorial, core java, where it is used, what type of
applications are created in java and why use java.

What is Java?
Java is a programming language and a platform.
Platform Any hardware or software environment in which a program runs, known as a
platform. Since Java has its own Runtime Environment (JRE) and API, it is called platform.

Java Example
1. class Simple{
2.
public static void main(String args[]){
3.
System.out.println("Hello Java");
4.
}
5. }
Test it Now

Where it is used?
According to Sun, 3 billion devices run java. There are many devices where java is currently
used. Some of them are as follows:
1.
2.
3.
4.
5.
6.

Desktop Applications such as acrobat reader, media player, antivirus etc.


Web Applications such as irctc.co.in, javatpoint.com etc.
Enterprise Applications such as banking applications.
Mobile
Embedded System
Smart Card

2
7. Robotics
8. Games etc.

Types of Java Applications


There are mainly 4 type of applications that can be created using java:

1) Standalone Application
It is also known as desktop application or window-based application. An application that we
need to install on every machine such as media player, antivirus etc. AWT and Swing are
used in java for creating standalone applications.

2) Web Application
An application that runs on the server side and creates dynamic page, is called web
application. Currently, servlet, jsp, struts, jsf etc. technologies are used for creating web
applications in java.

3) Enterprise Application
An application that is distributed in nature, such as banking applications etc. It has the
advantage of high level security, load balancing and clustering. In java, EJB is used for
creating enterprise applications.

4) Mobile Application
An application that is created for mobile devices. Currently Android and Java ME are used
for creating mobile applications.

Difference between JDK, JRE and JVM


1. Brief summary of JVM
2. Java Runtime Environment (JRE)
3. Java Development Kit (JDK)
Understanding the difference between JDK, JRE and JVM is important in Java. We are

having brief overview of JVM here.


If you want to get the detailed knowledge of Java Virtural Machine, move to the next
page. Firstly, let's see the basic differences between the JDK, JRE and JVM.

JVM
JVM (Java Virtual Machine) is an abstract machine. It is a specification that provides
runtime environment in which java bytecode can be executed.
JVMs are available for many hardware and software platforms. JVM, JRE and JDK are
platform dependent because configuration of each OS differs. But, Java is platform
independent.
The JVM performs following main tasks:

Loads code
Verifies code
Executes code
Provides runtime environment

JRE
JRE is an acronym for Java Runtime Environment.It is used to provide runtime
environment.It is the implementation of JVM.It physically exists.It contains set of
libraries + other files that JVM uses at runtime.
Implementation of JVMs are also actively released by other companies besides Sun
Micro Systems.

JDK
JDK is an acronym for Java Development Kit.It physically exists.It contains JRE +
development tools.

JVM (Java Virtual Machine)


1. Java Virtual Machine
2. Internal Architecture of JVM
JVM (Java Virtual Machine) is an abstract machine. It is a specification that provides runtime
environment in which java bytecode can be executed.
JVMs are available for many hardware and software platforms (i.e.JVM is plateform
dependent).

What is JVM?
It is:

6
1. A specification where working of Java Virtual Machine is specified. But
implementation provider is independent to choose the algorithm. Its implementation
has been provided by Sun and other companies.
2. An implementation Its implementation is known as JRE (Java Runtime
Environment).
3. Runtime Instance Whenever you write java command on the command prompt to
run the java class, and instance of JVM is created.

What it does?
The JVM performs following operation:

Loads code
Verifies code
Executes code
Provides runtime environment

JVM provides definitions for the:

Memory area
Class file format
Register set
Garbage-collected heap
Fatal error reporting etc.

Internal Architecture of JVM


Let's understand the internal architecture of JVM. It contains classloader, memory area,
execution engine etc.

1) Classloader:
Classloader is a subsystem of JVM that is used to load class files.

2) Class(Method) Area:
Class(Method) Area stores per-class structures such as the runtime constant pool, field and
method data, the code for methods.

3) Heap:
It is the runtime data area in which objects are allocated.

4) Stack:
Java Stack stores frames.It holds local variables and partial results, and plays a part in
method invocation and return.
Each thread has a private JVM stack, created at the same time as thread.
A new frame is created each time a method is invoked. A frame is destroyed when its
method invocation completes.

5) Program Counter Register:


PC (program counter) register. It contains the address of the Java virtual machine
instruction currently being executed.

6) Native Method Stack:


It contains all the native methods used in the application.

7) Execution Engine:
It contains:
1) A virtual processor
2) Interpreter:Read bytecode stream then execute the instructions.
3) Just-In-Time(JIT) compiler:It is used to improve the performance.JIT compiles
parts of the byte code that have similar functionality at the same time, and hence
reduces the amount of time needed for compilation.Here the term ?compiler? refers to a
translator from the instruction set of a Java virtual machine (JVM) to the instruction set
of a specific CPU.

Variable and Datatype in Java


1. Variable
2. Types of Variable
3. Data Types in Java
In this page, we will learn about the variable and java data types. Variable is a name of

memory location. There are three types of variables: local, instance and static. There are
two types of datatypes in java, primitive and non-primitive.

Variable
Variable is name of reserved area allocated in memory.

int data=50;//Here data is variable

Types of Variable
There are three types of variables in java

local variable
instance variable
static variable

10

Local Variable
A variable that is declared inside the method is called local variable.

Instance Variable
A variable that is declared inside the class but outside the method is called instance
variable . It is not declared as static.

Static variable
A variable that is declared as static is called static variable. It cannot be local.

We will have detailed learning of these variables in next chapters.

Example to understand the types of variables


class A{

int data=50;//instance variable

static int m=100;//static variable

void method(){

11

int n=90;//local variable


}

}//end of class

Data Types in Java


In java, there are two types of data types

primitive data types


non-primitive data types

Data Type Default Value Default size

12

boolean

false

1 bit

char

'\u0000'

2 byte

byte

1 byte

short

2 byte

int

4 byte

long

0L

8 byte

float

0.0f

4 byte

double

0.0d

8 byte

Why char uses 2 byte in java and what is \u0000 ?


because java uses unicode system rather than ASCII code system. \u0000 is the lowest
range of unicode system.To get detail about Unicode see below.

Unicode System
Unicode is a universal international standard character encoding that is capable of
representing most of the world's written languages.

Why java uses Unicode System?


Before Unicode, there were many language standards:

ASCII (American Standard Code for Information Interchange) for the United
States.
ISO 8859-1 for Western European Language.
KOI-8 for Russian.
GB18030 and BIG-5 for chinese, and so on.

This caused two problems:


1. A particular code value corresponds to different letters in the various language
standards.
2. The encodings for languages with large character sets have variable length.Some

13
common characters are encoded as single bytes, other require two or more byte.
To solve these problems, a new language standard was developed i.e. Unicode System.
In unicode, character holds 2 byte, so java also uses 2 byte for characters.
lowest value:\u0000
highest value:\uFFFF

Operators in java
Operator is a special symbol that is used to perform operations. There are many types of
operators in java such as unary operator, arithmetic operator, relational operator, shift
operator, bitwise operator, ternary operator and assignment operator.

Precedence of Operators

Operators

Precedence

postfix

expr++ expr--

unary

++expr --expr +expr -expr ~ !

multiplicative

* / %

additive

+ -

shift

<< >> >>>

relational

< > <= >= instanceof

equality

== !=

14

bitwise AND

&

bitwise exclusive OR

bitwise inclusive OR

logical AND

&&

logical OR

||

ternary

? :

assignment

= += -= *= /= %= &= ^= |= <<= >>= >>>=

Useful Programs:
There is given some useful programs such as factorial number, prime number, fibonacci
series etc.

It is better for the freshers to skip this topic and come to it after OOPs
concepts.

1) Program of factorial number.


class Operation{

static int fact(int number){


int f=1;
for(int i=1;i<=number;i++){
f=f*i;
}
return f;
}

15

public static void main(String args[]){


int result=fact(5);
System.out.println("Factorial of 5="+result);
}
}

2) Program of fibonacci series.


class Fabnoci{

public static void main(String...args)


{
int n=10,i,f0=1,f1=1,f2=0;
for(i=1;i<=n;i++)
{
f2=f0+f1;
f0=f1;
f1=f2;
f2=f0;
System.out.println(f2);
}

}
}

3) Program of armstrong number.


class ArmStrong{
public static void main(String...args)
{
int n=153,c=0,a,d;

16

d=n;
while(n>0)
{
a=n%10;
n=n/10;
c=c+(a*a*a);
}
if(d==c)
System.out.println("armstrong number");
else
System.out.println("it is not an armstrong number");

}
}

4) Program of checking palindrome number.


class Palindrome
{
public static void main( String...args)
{
int a=242;
int

n=a,b=a,rev=0;

while(n>0)
{
a=n%10;
rev=rev*10+a;
n=n/10;
}
if(rev==b)
System.out.println("it is Palindrome");

17

else
System.out.println("it is not palinedrome");

}
}

5) Program of swapping two numbers without using third variable.


class SwapTwoNumbers{
public static void main(String args[]){
int a=40,b=5;
a=a*b;
b=a/b;
a=a/b;

System.out.println("a= "+a);
System.out.println("b= "+b);

}
}

6) Program of factorial number by recursion


class FactRecursion{

static int fact(int n){


if(n==1)
return 1;

return n*=fact(n-1);
}

18

public static void main(String args[]){

int f=fact(5);
System.out.println(f);
}
}

Java OOPs Concepts


1. Object Oriented Programming
2. Advantage of OOPs over Procedure-oriented programming language
3. Difference between Objcet-oriented and Objcet-based programming language.
In this page, we will learn about basics of OOPs. Object Oriented Programming is a
paradigm that provides many concepts such as inheritance, data
binding,polymorphism etc.
Simula is considered as the first object-oriented programming language. The programming
paradigm where everything is represented as an object, is known as truly object-oriented
programming language.
Smalltalk is considered as the first truly object-oriented programming language.

OOPs (Object Oriented Programming System)

19

Object means a real word entity such


as pen, chair, table etc. Object-Oriented Programming is a methodology or paradigm to
design a program using classes and objects. It simplifies the software development and
maintenance by providing some concepts:

Object
Class
Inheritance
Polymorphism
Abstraction
Encapsulation

Object
Any entity that has state and behavior is known as an object. For example: chair, pen,
table, keyboard, bike etc. It can be physical and logical.

Class
Collection of objects is called class. It is a logical entity.

Inheritance

20

When one object acquires all the properties and behaviours of parent object i.e.
known as inheritance. It provides code reusability. It is used to achieve runtime
polymorphism.

Polymorphism
When one task is performed by different ways i.e. known as polymorphism. For
example: to convense the customer differently, to draw something e.g. shape or rectangle
etc.
In java, we use method overloading and method overriding to achieve polymorphism.
Another example can be to speak something e.g. cat speaks meaw, dog barks woof etc.

Abstraction
Hiding internal details and showing functionality is known as abstraction. For
example: phone call, we don't know the internal processing.
In java, we use abstract class and interface to achieve abstraction.

21

Encapsulation
Binding (or wrapping) code and data together into a single unit is known as
encapsulation. For example: capsule, it is wrapped with different medicines.
A java class is the example of encapsulation. Java bean is the fully encapsulated class
because all the data members are private here.

Advantage of OOPs over Procedure-oriented programming


language
1)OOPs makes development and maintenance easier where as in Procedure-oriented
programming language it is not easy to manage if code grows as project size grows.
2)OOPs provides data hiding whereas in Procedure-oriented prgramming language a
global data can be accessed from anywhere.
3)OOPs provides ability to simulate real-world event much more effectively. We can
provide the solution of real word problem if we are using the Object-Oriented
Programming language.

What is difference between object-oriented programming language and object-based


programming language?
Object based programming language follows all the features of OOPs except Inheritance.
JavaScript and VBScript are examples of object based programming languages.

22

Java Naming conventions


Java naming convention is a rule to follow as you decide what to name your identifiers
such as class, package, variable, constant, method etc.
But, it is not forced to follow. So, it is known as convention not rule.
All the classes, interfaces, packages, methods and fields of java programming language are
given according to java naming convention.

Advantage of naming conventions in java


By using standard Java naming conventions, you make your code easier to read for yourself
and for other programmers. Readability of Java program is very important. It indicates
that less time is spent to figure out what the code does.

Name
class name

Convention
should start with uppercase letter and be a noun e.g. String, Color, Button,
System, Thread etc.

interface

should start with uppercase letter and be an adjective e.g. Runnable, Remote,

name

ActionListener etc.

method name

should start with lowercase letter and be a verb e.g. actionPerformed(), main(),
print(), println() etc.

variable name

should start with lowercase letter e.g. firstName, orderNumber etc.

package

should be in lowercase letter e.g. java, lang, sql, util etc.

name
constants

should be in uppercase letter. e.g. RED, YELLOW, MAX_PRIORITY etc.

name

Understanding CamelCase in java naming conventions


Java follows camelcase syntax for naming the class, interface, method and variable.

23

If name is combined with two words, second word will start with uppercase letter always
e.g. actionPerformed(), firstName, ActionEvent, ActionListener etc.

Object and Class in Java


1. Object in Java
2. Class in Java
3. Instace Variable in Java
4. Method in Java
5. Example of Object and class that maintains the records of student
6. Annonymous Object
In this page, we will learn about java objects and classes. In object-oriented programming
technique, we design a program using objects and classes.
Object is the physical as well as logical entity whereas class is the logical entity only.

Object in Java

An entity that has state and behavior is known as an object e.g. chair, bike, marker, pen,
table, car etc. It can be physical or logical (tengible and intengible). The example of
integible object is banking system.

24

An object has three characteristics:

state: represents data (value) of an object.


behavior: represents the behavior (functionality) of an object such as deposit,
withdraw etc.
identity: Object identity is typically implemented via a unique ID. The value of the
ID is not visible to the external user. But,it is used internally by the JVM to identify
each object uniquely.

For Example: Pen is an object. Its name is Reynolds, color is white etc. known as its
state. It is used to write, so writing is its behavior.
Object is an instance of a class. Class is a template or blueprint from which objects
are created. So object is the instance(result) of a class.

Class in Java
A class is a group of objects that has common properties. It is a template or blueprint
from which objects are created.

A class in java can contain:

data member
method
constructor
block
class and interface

Syntax to declare a class:


1. class <class_name>{
2.
data member;
3.
method;
4. }

Simple Example of Object and Class


In this example, we have created a Student class that have two data members id and
name. We are creating the object of the Student class by new keyword and printing the
objects value.
1. class Student1{

25
2. int id;//data member (also instance variable)
3. String name;//data member(also instance variable)
4.
5. public static void main(String args[]){
6.
Student1 s1=new Student1();//creating an object of Student
7.
System.out.println(s1.id);
8.
System.out.println(s1.name);
9. }
10. }
Test it Now
Output:0 null

Instance variable in Java


A variable that is created inside the class but outside the method, is known as instance
variable.Instance variable doesn't get memory at compile time.It gets memory at
runtime when object(instance) is created.That is why, it is known as instance variable.

Method in Java
In java, a method is like function i.e. used to expose behaviour of an object.

Advantage of Method

Code Reusability
Code Optimization

new keyword
The new keyword is used to allocate memory at runtime.

Example of Object and class that maintains the records of


students
In this example, we are creating the two objects of Student class and initializing the
value to these objects by invoking the insertRecord method on it. Here, we are displaying
the state (data) of the objects by invoking the displayInformation method.
1. class Student2{
2. int rollno;
3. String name;

26
4.
5. void insertRecord(int r, String n){ //method
6.
rollno=r;
7.
name=n;
8. }
9.
10. void displayInformation(){System.out.println(rollno+" "+name);}//method
11.
12. public static void main(String args[]){
13. Student2 s1=new Student2();
14. Student2 s2=new Student2();
15.
16. s1.insertRecord(111,"Karan");
17. s2.insertRecord(222,"Aryan");
18.
19. s1.displayInformation();
20. s2.displayInformation();
21.
22. }
23. }
Test it Now
Output:111 Karan
222 Aryan

download this example of object and class

27

As you see in the above figure, object gets the memory in Heap area and reference
variable refers to the object allocated in the Heap memory area. Here, s1 and s2 both
are reference variables that refer to the objects allocated in memory.

Another Example of Object and Class


There is given another example that maintains the records of Rectangle class. Its
exaplanation is same as in the above Student class example.
1. class Rectangle{
2. int length;
3. int width;
4.
5. void insert(int l,int w){
6.
length=l;
7.
width=w;
8. }
9.
10. void calculateArea(){System.out.println(length*width);}
11.
12. public static void main(String args[]){
13. Rectangle r1=new Rectangle();
14. Rectangle r2=new Rectangle();

28
15.
16. r1.insert(11,5);
17. r2.insert(3,15);
18.
19. r1.calculateArea();
20. r2.calculateArea();
21. }
22. }
Output:55
45

What are the different ways to create an object in Java?


There are many ways to create an object in java. They are:

By
By
By
By

new keyword
newInstance() method
clone() method
factory method etc.

We will learn, these ways to create the object later.

Annonymous object
Annonymous simply means nameless.An object that have no reference is known as
annonymous object.
If you have to use an object only once, annonymous object is a good approach.
1. class Calculation{
2.
3. void fact(int n){
4.
int fact=1;
5.
for(int i=1;i<=n;i++){
6.
fact=fact*i;
7.
}
8. System.out.println("factorial is "+fact);
9. }
10.
11. public static void main(String args[]){
12. new Calculation().fact(5);//calling method with annonymous object
13. }
14. }
Output:Factorial is 120

29

Creating multiple objects by one type only


We can create multiple objects by one type only as we do in case of primitives.
1. Rectangle r1=new Rectangle(),r2=new Rectangle();//creating two objects
Let's see the example:
1. class Rectangle{
2. int length;
3. int width;
4.
5. void insert(int l,int w){
6.
length=l;
7.
width=w;
8. }
9.
10. void calculateArea(){System.out.println(length*width);}
11.
12. public static void main(String args[]){
13. Rectangle r1=new Rectangle(),r2=new Rectangle();//creating two objects
14.
15. r1.insert(11,5);
16. r2.insert(3,15);
17.
18. r1.calculateArea();
19. r2.calculateArea();
20. }
21. }
Output:55
45

Method Overloading in Java


1. Different ways to overload the method
2. By changing the no. of arguments
3. By changing the datatype
4. Why method overloading is not possible by changing the return type
5. Can we overload the main method
6. method overloading with Type Promotion
If a class have multiple methods by same name but different parameters, it is known
as Method Overloading.
If we have to perform only one operation, having same name of the methods increases the
readability of the program.

30

Suppose you have to perform addition of the given numbers but there can be any number
of arguments, if you write the method such as a(int,int) for two parameters, and
b(int,int,int) for three parameters then it may be difficult for you as well as other
programmers to understand the behaviour of the method because its name differs. So, we
perform method overloading to figure out the program quickly.

Advantage of method overloading?


Method overloading increases the readability of the program.

Different ways to overload the method


There are two ways to overload the method in java
1. By changing number of arguments
2. By changing the data type

In java, Methood Overloading is not possible by changing the return type of the
method.

1)Example of Method Overloading by changing the no. of


arguments
In this example, we have created two overloaded methods, first sum method performs
addition of two numbers and second sum method performs addition of three numbers.
1. class Calculation{

31
2.
void sum(int a,int b){System.out.println(a+b);}
3.
void sum(int a,int b,int c){System.out.println(a+b+c);}
4.
5.
public static void main(String args[]){
6.
Calculation obj=new Calculation();
7.
obj.sum(10,10,10);
8.
obj.sum(20,20);
9.
10. }
11. }
Test it Now
Output:30
40

2)Example of Method Overloading by changing data type of


argument
In this example, we have created two overloaded methods that differs in data type. The first
sum method receives two integer arguments and second sum method receives two double
arguments.
1. class Calculation2{
2.
void sum(int a,int b){System.out.println(a+b);}
3.
void sum(double a,double b){System.out.println(a+b);}
4.
5.
public static void main(String args[]){
6.
Calculation2 obj=new Calculation2();
7.
obj.sum(10.5,10.5);
8.
obj.sum(20,20);
9.
10. }
11. }
Test it Now
Output:21.0
40

Que) Why Method Overloaing is not possible by changing the return type of method?
In java, method overloading is not possible by changing the return type of the method
because there may occur ambiguity. Let's see how ambiguity may occur:

32

because there was problem:


1. class Calculation3{
2.
int sum(int a,int b){System.out.println(a+b);}
3.
double sum(int a,int b){System.out.println(a+b);}
4.
5.
public static void main(String args[]){
6.
Calculation3 obj=new Calculation3();
7.
int result=obj.sum(20,20); //Compile Time Error
8.
9.
}
10. }
Test it Now
int result=obj.sum(20,20); //Here how can java determine which sum() method should be
called

Can we overload main() method?


Yes, by method overloading. You can have any number of main methods in a class by
method overloading. Let's see the simple example:
1. class Overloading1{
2.
public static void main(int a){
3.
System.out.println(a);
4.
}
5.
6.
public static void main(String args[]){
7.
System.out.println("main() method invoked");
8.
main(10);
9.
}
10. }
Test it Now
Output:main() method invoked
10

Method Overloading and TypePromotion


One type is promoted to another implicitly if no matching datatype is found. Let's
understand the concept by the figure given below:

33

As displayed in the above diagram, byte can be promoted to short, int, long, float or double.
The short datatype can be promoted to int,long,float or double. The char datatype can be
promoted to int,long,float or double and so on.

Example of Method Overloading with TypePromotion


1. class OverloadingCalculation1{
2.
void sum(int a,long b){System.out.println(a+b);}
3.
void sum(int a,int b,int c){System.out.println(a+b+c);}
4.
5.
public static void main(String args[]){
6.
OverloadingCalculation1 obj=new OverloadingCalculation1();
7.
obj.sum(20,20);//now second int literal will be promoted to long
8.
obj.sum(20,20,20);
9.
10. }
11. }
Test it Now
Output:40

34

60

Example of Method Overloading with TypePromotion if


matching found
If there are matching type arguments in the method, type promotion is not performed.
1. class OverloadingCalculation2{
2.
void sum(int a,int b){System.out.println("int arg method invoked");}
3.
void sum(long a,long b){System.out.println("long arg method invoked");}
4.
5.
public static void main(String args[]){
6.
OverloadingCalculation2 obj=new OverloadingCalculation2();
7.
obj.sum(20,20);//now int arg sum() method gets invoked
8.
}
9. }
Test it Now
Output:int arg method invoked

Example of Method Overloading with TypePromotion in case


ambiguity
If there are no matching type arguments in the method, and each method promotes similar
number of arguments, there will be ambiguity.
1. class OverloadingCalculation3{
2.
void sum(int a,long b){System.out.println("a method invoked");}
3.
void sum(long a,int b){System.out.println("b method invoked");}
4.
5.
public static void main(String args[]){
6.
OverloadingCalculation3 obj=new OverloadingCalculation3();
7.
obj.sum(20,20);//now ambiguity
8.
}
9. }
Test it Now
Output:Compile Time Error

Constructor in Java
1. Types of constructors

35
1. Default Constructor
2. Parameterized Constructor
2. Constructor Overloading
3. Does constructor return any value
4. Copying the values of one object into another
5. Does constructor perform other task instead initialization
Constructor is a special type of method that is used to initialize the object.
Constructor is invoked at the time of object creation. It constructs the values i.e.
provides data for the object that is why it is known as constructor.

Rules for creating constructor


There are basically two rules defined for the constructor.
1. Constructor name must be same as its class name
2. Constructor must have no explicit return type

Types of constructors
There are two types of constructors:
1. default constructor (no-arg constructor)
2. parameterized constructor

36

1) Default Constructor
A constructor that have no parameter is known as default constructor.

Syntax of default constructor:


1. <class_name>(){}

Example of default constructor


In this example, we are creating the no-arg constructor in the Bike class. It will be
invoked at the time of object creation.
1.
2.
3.
4.
5.
6.
7.
8.

class Bike1{
Bike(){System.out.println("Bike is created");}
public static void main(String args[]){
Bike1 b=new Bike1();
}
}
Test it Now
Output: Bike is created

Rule: If there is no constructor in a class, compiler automatically creates a default


constructor.

37

Que)What is the purpose of default constructor?


Default constructor provides the default values to the object like 0, null etc. depending on
the type.

Example of default constructor that displays the default values


1. class Student3{
2. int id;
3. String name;
4.
5. void display(){System.out.println(id+" "+name);}
6.
7. public static void main(String args[]){
8. Student3 s1=new Student3();
9. Student3 s2=new Student3();
10. s1.display();
11. s2.display();
12. }
13. }
Test it Now
Output:0 null
0 null
Explanation:In the above class,you are not creating any constructor so compiler provides
you a default constructor.Here 0 and null values are provided by default constructor.

Parameterized constructor
A constructor that have parameters is known as parameterized constructor.

38

Why use parameterized constructor?


Parameterized constructor is used to provide different values to the distinct objects.

Example of parameterized constructor


In this example, we have created the constructor of Student class that have two
parameters. We can have any number of parameters in the constructor.
1. class Student4{
2.
int id;
3.
String name;
4.
5.
Student4(int i,String n){
6.
id = i;
7.
name = n;
8.
}
9.
void display(){System.out.println(id+" "+name);}
10.
11.
public static void main(String args[]){
12.
Student4 s1 = new Student4(111,"Karan");
13.
Student4 s2 = new Student4(222,"Aryan");
14.
s1.display();
15.
s2.display();
16. }
17. }
Test it Now
Output:111 Karan
222 Aryan

Constructor Overloading
Constructor overloading is a technique in Java in which a class can have any number of
constructors that differ in parameter lists.The compiler differentiates these constructors
by taking into account the number of parameters in the list and their type.

Example of Constructor Overloading


1. class Student5{
2.
int id;
3.
String name;
4.
int age;
5.
Student5(int i,String n){
6.
id = i;
7.
name = n;
8.
}

39
9.
Student5(int i,String n,int a){
10.
id = i;
11.
name = n;
12.
age=a;
13.
}
14.
void display(){System.out.println(id+" "+name+" "+age);}
15.
16.
public static void main(String args[]){
17.
Student5 s1 = new Student5(111,"Karan");
18.
Student5 s2 = new Student5(222,"Aryan",25);
19.
s1.display();
20.
s2.display();
21. }
22. }
Test it Now
Output:111 Karan 0
222 Aryan 25

What is the difference between constructor and method ?


There are many differences between constructors and methods. They are given below.

Constructor
Constructor is used to initialize the state of an object.

Method
Method is used to expose behaviour of
an object.

Constructor must not have return type.

Method must have return type.

Constructor is invoked implicitly.

Method is invoked explicitly.

The java compiler provides a default constructor if you

Method is not provided by compiler in

don't have any constructor.

any case.

Constructor name must be same as the class name.

Method name may or may not be same


as class name.

40

Copying the values of one object to another like copy constructor


in C++
There are many ways to copy the values of one object into another. They are:

By constructor
By assigning the values of one object into another
By clone() method of Object class

In this example, we are going to copy the values of one object into another using
constructor.
1. class Student6{
2.
int id;
3.
String name;
4.
Student6(int i,String n){
5.
id = i;
6.
name = n;
7.
}
8.
9.
Student6(Student s){
10.
id = s.id;
11.
name =s.name;
12.
}
13.
void display(){System.out.println(id+" "+name);}
14.
15.
public static void main(String args[]){
16.
Student6 s1 = new Student6(111,"Karan");
17.
Student6 s2 = new Student6(s1);
18.
s1.display();
19.
s2.display();
20. }
21. }
Test it Now
Output:111 Karan
111 Karan

Copying the values of one object to another without constructor


We can copy the values of one object into another by assigning the objects values to
another object. In this case, there is no need to create the constructor.
1. class Student7{
2.
int id;
3.
String name;
4.
Student7(int i,String n){

41
5.
id = i;
6.
name = n;
7.
}
8.
Student7(){}
9.
void display(){System.out.println(id+" "+name);}
10.
11.
public static void main(String args[]){
12.
Student7 s1 = new Student7(111,"Karan");
13.
Student7 s2 = new Student7();
14.
s2.id=s1.id;
15.
s2.name=s1.name;
16.
s1.display();
17.
s2.display();
18. }
19. }
Test it Now
Output:111 Karan
111 Karan

Que)Does constructor return any value?


Ans:yes,that is current class instance (You cannot use return type yet it returns a value).

Can constructor perform other tasks instead of initialization?


Yes, like object creation, starting a thread, calling method etc. You can perform any
operation in the constructor as you perform in the method.

static keyword
1. Static variable
2. Program of counter without static variable
3. Program of counter with static variable
4. Static method
5. Restrictions for static method
6. Why main method is static ?
7. Static block
8. Can we execute a program without main method ?

42

The static keyword is used in java mainly for memory management. We may apply static
keyword with variables, methods, blocks and nested class. The static keyword belongs to
the class than instance of the class.
The static can be:
1.
2.
3.
4.

variable (also known as class variable)


method (also known as class method)
block
nested class

1) static variable
If you declare any variable as static, it is known static variable.

The static variable can be used to refer the common property of all objects (that is
not unique for each object) e.g. company name of employees,college name of
students etc.
The static variable gets memory only once in class area at the time of class loading.

Advantage of static variable


It makes your program memory efficient (i.e it saves memory).

Understanding problem without static variable


1. class Student{
2.
int rollno;
3.
String name;
4.
String college="ITS";
5. }
Suppose there are 500 students in my college, now all instance data members will get
memory each time when object is created.All student have its unique rollno and name so
instance data member is good.Here, college refers to the common property of all objects.If
we make it static,this field will get memory only once.

static property is shared to all objects.

Example of static variable


1. //Program of static variable

43
2.
3. class Student8{
4.
int rollno;
5.
String name;
6.
static String college ="ITS";
7.
8.
Student8(int r,String n){
9.
rollno = r;
10. name = n;
11. }
12. void display (){System.out.println(rollno+" "+name+" "+college);}
13.
14. public static void main(String args[]){
15. Student8 s1 = new Student8(111,"Karan");
16. Student8 s2 = new Student8(222,"Aryan");
17.
18. s1.display();
19. s2.display();
20. }
21. }
Test it Now
Output:111 Karan ITS
222 Aryan ITS

44

Program of counter without static variable


In this example, we have created an instance variable named count which is incremented in
the constructor. Since instance variable gets the memory at the time of object creation,
each object will have the copy of the instance variable, if it is incremented, it won't reflect
to other objects. So each objects will have the value 1 in the count variable.
1. class Counter{
2. int count=0;//will get memory when instance is created
3.
4. Counter(){
5. count++;
6. System.out.println(count);
7. }
8.
9. public static void main(String args[]){
10.
11. Counter c1=new Counter();
12. Counter c2=new Counter();
13. Counter c3=new Counter();
14.
15. }
16. }
Test it Now
Output:1
1
1

Program of counter by static variable


As we have mentioned above, static variable will get the memory only once, if any object
changes the value of the static variable, it will retain its value.
1. class Counter2{
2. static int count=0;//will get memory only once and retain its value
3.
4. Counter2(){
5. count++;
6. System.out.println(count);
7. }
8.
9. public static void main(String args[]){
10.
11. Counter2 c1=new Counter2();

45
12. Counter2 c2=new Counter2();
13. Counter2 c3=new Counter2();
14.
15. }
16. }
Test it Now
Output:1
2
3

2) static method
If you apply static keyword with any method, it is known as static method

A static method belongs to the class rather than object of a class.


A static method can be invoked without the need for creating an instance of a class.
static method can access static data member and can change the value of it.

Example of static method


1. //Program of changing the common property of all objects(static field).
2.
3. class Student9{
4.
int rollno;
5.
String name;
6.
static String college = "ITS";
7.
8.
static void change(){
9.
college = "BBDIT";
10.
}
11.
12.
Student9(int r, String n){
13.
rollno = r;
14.
name = n;
15.
}
16.
17.
void display (){System.out.println(rollno+" "+name+" "+college);}
18.
19.
public static void main(String args[]){
20.
Student9.change();
21.
22.
Student9 s1 = new Student9 (111,"Karan");
23.
Student9 s2 = new Student9 (222,"Aryan");
24.
Student9 s3 = new Student9 (333,"Sonoo");
25.
26.
s1.display();
27.
s2.display();
28.
s3.display();

46
29.
}
30. }
Test it Now
Output:111 Karan BBDIT
222 Aryan BBDIT
333 Sonoo BBDIT

Another example of static method that performs normal


calculation
1. //Program to get cube of a given number by static method
2.
3. class Calculate{
4.
static int cube(int x){
5.
return x*x*x;
6.
}
7.
8.
public static void main(String args[]){
9.
int result=Calculate.cube(5);
10. System.out.println(result);
11. }
12. }
Test it Now
Output:125

Restrictions for static method


There are two main restrictions for the static method. They are:
1. The static method can not use non static data member or call non-static method
directly.
2. this and super cannot be used in static context.
1. class A{
2. int a=40;//non static
3.
4. public static void main(String args[]){
5.
System.out.println(a);
6. }
7. }
Test it Now
Output:Compile Time Error

47

Que)why main method is static?


Ans) because object is not required to call static method if it were non-static method,
jvm create object first then call main() method that will lead the problem of extra
memory allocation.

3)static block

Is used to initialize the static data member.


It is executed before main method at the time of classloading.

Example of static block


1. class A2{
2.
3.
static{System.out.println("static block is invoked");}
4.
5.
public static void main(String args[]){
6.
System.out.println("Hello main");
7.
}
8. }
Test it Now
Output:static block is invoked
Hello main

Que)Can we execute a program without main() method?


Ans)Yes, one of the way is static block but in previous version of JDK not in JDK 1.7.
1. class A3{
2.
static{
3.
System.out.println("static block is invoked");
4.
System.exit(0);
5.
}
6. }
Test it Now
Output:static block is invoked (if not JDK7)
In JDK7 and above, output will be:
Output:Error: Main method not found in class A3, please define the main
method as:
public static void main(String[] args)

48

this keyword
1. this keyword
2. Usage of this keyword
1. to refer the current class instance variable
2. to invoke the current class constructor
3. to invoke the current class method
4. to pass as an argument in the method call
5. to pass as an argument in the constructor call
6. to return the current class instance
3. Proving this keyword
There can be a lot of usage of this keyword. In java, this is a reference variablethat
refers to the current object.

Usage of this keyword


Here is given the 6 usage of this keyword.
1.
2.
3.
4.
5.
6.

this keyword can be used to refer current class instance variable.


this() can be used to invoke current class constructor.
this keyword can be used to invoke current class method (implicitly)
this can be passed as an argument in the method call.
this can be passed as argument in the constructor call.
this keyword can also be used to return the current class instance.

Suggestion:If you are beginner to java, lookup only two usage of this keyword.

49

1) The this keyword can be used to refer current class instance


variable.
If there is ambiguity between the instance variable and parameter, this keyword resolves
the problem of ambiguity.

Understanding the problem without this keyword


Let's understand the problem if we don't use this keyword by the example given below:
1. class Student10{
2.
int id;
3.
String name;
4.
5.
student(int id,String name){
6.
id = id;
7.
name = name;
8.
}
9.
void display(){System.out.println(id+" "+name);}
10.
11.
public static void main(String args[]){
12.
Student10 s1 = new Student10(111,"Karan");
13.
Student10 s2 = new Student10(321,"Aryan");
14.
s1.display();
15.
s2.display();
16.
}
17. }
Test it Now
Output:0 null
0 null
In the above example, parameter (formal arguments) and instance variables are same
that is why we are using this keyword to distinguish between local variable and instance
variable.

Solution of the above problem by this keyword


1. //example of this keyword
2. class Student11{
3.
int id;
4.
String name;
5.
6.
Student11(int id,String name){
7.
this.id = id;
8.
this.name = name;

50
9.
}
10.
void display(){System.out.println(id+" "+name);}
11.
public static void main(String args[]){
12.
Student11 s1 = new Student11(111,"Karan");
13.
Student11 s2 = new Student11(222,"Aryan");
14.
s1.display();
15.
s2.display();
16. }
17. }
Test it Now
Output111 Karan
222 Aryan

If local variables(formal arguments) and instance variables are different, there is no need
to use this keyword like in the following program:

Program where this keyword is not required


1. class Student12{
2.
int id;
3.
String name;
4.
5.
Student12(int i,String n){
6.
id = i;

51
7.
name = n;
8.
}
9.
void display(){System.out.println(id+" "+name);}
10.
public static void main(String args[]){
11.
Student12 e1 = new Student12(111,"karan");
12.
Student12 e2 = new Student12(222,"Aryan");
13.
e1.display();
14.
e2.display();
15. }
16. }
Test it Now
Output:111 Karan
222 Aryan

2) this() can be used to invoked current class constructor.


The this() constructor call can be used to invoke the current class constructor (constructor
chaining). This approach is better if you have many constructors in the class and want to
reuse that constructor.
1. //Program of this() constructor call (constructor chaining)
2.
3. class Student13{
4.
int id;
5.
String name;
6.
Student13(){System.out.println("default constructor is invoked");}
7.
8.
Student13(int id,String name){
9.
this ();//it is used to invoked current class constructor.
10.
this.id = id;
11.
this.name = name;
12.
}
13.
void display(){System.out.println(id+" "+name);}
14.
15.
public static void main(String args[]){
16.
Student13 e1 = new Student13(111,"karan");
17.
Student13 e2 = new Student13(222,"Aryan");
18.
e1.display();
19.
e2.display();
20. }
21. }
Test it Now
Output:
default constructor is invoked
default constructor is invoked

52

111 Karan
222 Aryan

Where to use this() constructor call?


The this() constructor call should be used to reuse the constructor in the constructor. It
maintains the chain between the constructors i.e. it is used for constructor chaining. Let's
see the example given below that displays the actual use of this keyword.
1. class Student14{
2.
int id;
3.
String name;
4.
String city;
5.
6.
Student14(int id,String name){
7.
this.id = id;
8.
this.name = name;
9.
}
10.
Student14(int id,String name,String city){
11.
this(id,name);//now no need to initialize id and name
12.
this.city=city;
13.
}
14.
void display(){System.out.println(id+" "+name+" "+city);}
15.
16.
public static void main(String args[]){
17.
Student14 e1 = new Student14(111,"karan");
18.
Student14 e2 = new Student14(222,"Aryan","delhi");
19.
e1.display();
20.
e2.display();
21. }
22. }
Test it Now
Output:111 Karan null
222 Aryan delhi

Rule: Call to this() must be the first statement in constructor.


1. class Student15{
2.
int id;
3.
String name;
4.
Student15(){System.out.println("default constructor is invoked");}
5.
6.
Student15(int id,String name){
7.
id = id;
8.
name = name;
9.
this ();//must be the first statement
10.
}
11.
void display(){System.out.println(id+" "+name);}

53
12.
13.
public static void main(String args[]){
14.
Student15 e1 = new Student15(111,"karan");
15.
Student15 e2 = new Student15(222,"Aryan");
16.
e1.display();
17.
e2.display();
18. }
19. }
Test it Now
Output:Compile Time Error

3)The this keyword can be used to invoke current class method


(implicitly).
You may invoke the method of the current class by using the this keyword. If you don't
use the this keyword, compiler automatically adds this keyword while invoking the
method. Let's see the example

1. class S{
2.
void m(){
3.
System.out.println("method is invoked");
4.
}
5.
void n(){
6.
this.m();//no need because compiler does it for you.
7.
}
8.
void p(){
9.
n();//complier will add this to invoke n() method as this.n()
10. }
11. public static void main(String args[]){
12. S s1 = new S();

54
13. s1.p();
14. }
15. }
Test it Now
Output:method is invoked

4) this keyword can be passed as an argument in the method.


The this keyword can also be passed as an argument in the method. It is mainly used in
the event handling. Let's see the example:
1. class S2{
2.
void m(S2 obj){
3.
System.out.println("method is invoked");
4.
}
5.
void p(){
6.
m(this);
7.
}
8.
9.
public static void main(String args[]){
10. S2 s1 = new S2();
11. s1.p();
12. }
13. }
Test it Now
Output:method is invoked

Application of this that can be passed as an argument:


In event handling (or) in a situation where we have to provide reference of a class to
another one.

5) The this keyword can be passed as argument in the


constructor call.
We can pass the this keyword in the constructor also. It is useful if we have to use one
object in multiple classes. Let's see the example:
1. class B{
2.
A4 obj;
3.
B(A4 obj){
4.
this.obj=obj;
5.
}
6.
void display(){
7.
System.out.println(obj.data);//using data member of A4 class

55
8.
}
9. }
10.
11. class A4{
12. int data=10;
13. A4(){
14. B b=new B(this);
15. b.display();
16. }
17. public static void main(String args[]){
18. A4 a=new A4();
19. }
20. }
Test it Now
Output:10

6) The this keyword can be used to return current class instance.


We can return the this keyword as an statement from the method. In such case, return
type of the method must be the class type (non-primitive). Let's see the example:

Syntax of this that can be returned as a statement


1. return_type method_name(){
2. return this;
3. }

Example of this keyword that you return as a statement from


the method
1. class A{
2. A getA(){
3. return this;
4. }
5. void msg(){System.out.println("Hello java");}
6. }
7.
8. class Test1{
9. public static void main(String args[]){
10. new A().getA().msg();
11. }
12. }
Test it Now
Output:Hello java

56

Proving this keyword


Let's prove that this keyword refers to the current class instance variable. In this
program, we are printing the reference variable and this, output of both variables are
same.
1. class A5{
2. void m(){
3. System.out.println(this);//prints same reference ID
4. }
5.
6. public static void main(String args[]){
7. A5 obj=new A5();
8. System.out.println(obj);//prints the reference ID
9.
10. obj.m();
11. }
12. }
Test it Now
Output:A5@22b3ea59
A5@22b3ea59

Inheritance in Java
1. Inheritance
2. Types of Inheritance
3. Why multiple inheritance is not possible in java in case of class?
Inheritance in java is a mechanism in which one object acquires all the properties and
behaviors of parent object.
The idea behind inheritance in java is that you can create new classes that are built upon
existing classes. When you inherit from an existing class, you can reuse methods and fields
of parent class, and you can add new methods and fields also.
Inheritance represents the IS-A relationship, also known as Parent-Child relationship.

Why use Inheritance?

For Method Overriding (So Runtime Polymorphism).


For Code Reusability.

Syntax of Inheritance
1. class Subclass-name extends Superclass-name
2. {

57
3.
//methods and fields
4. }
The keyword extends indicates that you are making a new class that derives from an
existing class.
In the terminology of Java, a class that is inherited is called a super class. The new class is
called a subclass.

Understanding the simple example of inheritance

As displayed in the above figure, Programmer is the subclass and Employee is the
superclass. Relationship between two classes isProgrammer IS-A Employee.It means
that Programmer is a type of Employee.
1. class Employee{
2. float salary=40000;
3. }
4.
5. class Programmer extends Employee{
6. int bonus=10000;
7. public static void main(String args[]){
8.
Programmer p=new Programmer();
9.
System.out.println("Programmer salary is:"+p.salary);

58
10. System.out.println("Bonus of Programmer is:"+p.bonus);
11. }
12. }
Test it Now
Programmer salary is:40000.0
Bonus of programmer is:10000
In the above example, Programmer object can access the field of own class as well as of
Employee class i.e. code reusability.

Types of Inheritance
On the basis of class, there can be three types of inheritance: single, multilevel and
hierarchical in java.
In java programming, multiple and hybrid inheritance is supported through interface only.
We will learn about interfaces later.

Multiple inheritance is not supported in java in case of class.

59

When a class extends multiple classes i.e. known as multiple inheritance. For Example:

Q) Why multiple inheritance is not supported in java?


To reduce the complexity and simplify the language, multiple inheritance is not supported in
java.
Consider a scenario where A, B and C are three classes. The C class inherits A and B
classes. If A and B classes have same method and you call it from child class object, there
will be ambiguity to call method of A or B class.
Since compile time errors are better than runtime errors, java renders compile time error if
you inherit 2 classes. So whether you have same method or different, there will be compile
time error now.
1.
2.
3.
4.

class A{
void msg(){System.out.println("Hello");}
}
class B{

60
5. void msg(){System.out.println("Welcome");}
6. }
7. class C extends A,B{//suppose if it were
8.
9. Public Static void main(String args[]){
10. C obj=new C();
11. obj.msg();//Now which msg() method would be invoked?
12. }
13. }
Test it Now
Compile Time Error

Aggregation in Java
If a class have an entity reference, it is known as Aggregation. Aggregation represents HASA relationship.
Consider a situation, Employee object contains many informations such as id, name, emailId
etc. It contains one more object named address, which contains its own informations such
as city, state, country, zipcode etc. as given below.
1.
2.
3.
4.
5.
6.

class Employee{
int id;
String name;
Address address;//Address is a class
...
}
In such case, Employee has an entity reference address, so relationship is Employee HAS-A
address.

Why use Aggregation?

For Code Reusability.

61

Simple Example of Aggregation

In this example, we have created the reference of Operation class in the Circle class.
1. class Operation{
2. int square(int n){
3.
return n*n;
4. }
5. }
6.
7. class Circle{
8. Operation op;//aggregation
9. double pi=3.14;
10.
11. double area(int radius){
12. op=new Operation();
13. int rsquare=op.square(radius);//code reusability (i.e. delegates the method call).
14. return pi*rsquare;
15. }
16.
17.
18.
19. public static void main(String args[]){
20. Circle c=new Circle();
21. double result=c.area(5);
22. System.out.println(result);
23. }
24. }
Test it Now
Output:78.5

When use Aggregation?

Code reuse is also best achieved by aggregation when there is no is-a relationship.
Inheritance should be used only if the relationship is-a is maintained throughout the
lifetime of the objects involved; otherwise, aggregation is the best choice.

62

Understanding meaningful example of Aggregation


In this example, Employee has an object of Address, address object contains its own
informations such as city, state, country etc. In such case relationship is Employee HAS-A
address.

Address.java
1. public class Address1 {
2. String city,state,country;
3.
4. public Address1(String city, String state, String country) {
5.
this.city = city;
6.
this.state = state;
7.
this.country = country;
8. }
9.
10. }

Emp.java
1. public class Emp {
2. int id;
3. String name;
4. Address address;
5.
6. public Emp(int id, String name,Address address) {
7.
this.id = id;
8.
this.name = name;
9.
this.address=address;
10. }
11.
12. void display(){
13. System.out.println(id+" "+name);
14. System.out.println(address.city+" "+address.state+" "+address.country);
15. }
16.
17. public static void main(String[] args) {
18. Address address1=new Address("gzb","UP","india");
19. Address address2=new Address("gno","UP","india");
20.
21. Emp e=new Emp(111,"varun",address1);
22. Emp e2=new Emp(112,"arun",address2);
23.
24. e.display();
25. e2.display();
26.

63
27. }
28. }
Test it Now
Output:111 varun
gzb UP india
112 arun
gno UP india

Method Overriding in Java


1. Understanding problem without method overriding
2. Can we override the static method
3. method overloading vs method overriding
If subclass (child class) has the same method as declared in the parent class, it is known
as method overriding.
In other words, If subclass provides the specific implementation of the method that has
been provided by one of its parent class, it is known as Method Overriding.

Advantage of Java Method Overriding

Method Overriding is used to provide specific implementation of a method that is


already provided by its super class.
Method Overriding is used for Runtime Polymorphism

Rules for Method Overriding


1. method must have same name as in the parent class
2. method must have same parameter as in the parent class.
3. must be IS-A relationship (inheritance).

Understanding the problem without method overriding


Let's understand the problem that we may face in the program if we don't use method
overriding.
1.

class Vehicle{

64
2.
void run(){System.out.println("Vehicle is running");}
3.
}
4.
class Bike extends Vehicle{
5.
6.
public static void main(String args[]){
7.
Bike obj = new Bike();
8.
obj.run();
9.
}
10. }
Test it Now
Output:Vehicle is running
Problem is that I have to provide a specific implementation of run() method in subclass that
is why we use method overriding.

Example of method overriding


In this example, we have defined the run method in the subclass as defined in the parent
class but it has some specific implementation. The name and parameter of the method is
same and there is IS-A relationship between the classes, so there is method overriding.
1. class Vehicle{
2. void run(){System.out.println("Vehicle is running");}
3. }
4. class Bike2 extends Vehicle{
5. void run(){System.out.println("Bike is running safely");}
6.
7. public static void main(String args[]){
8. Bike2 obj = new Bike2();
9. obj.run();
10. }
Test it Now
Output:Bike is running safely

Real example of Java Method Overriding


Consider a scenario, Bank is a class that provides functionality to get rate of interest. But,
rate of interest varies according to banks. For example, SBI, ICICI and AXIS banks could
provide 8%, 7% and 9% rate of interest.

65

1. class Bank{
2. int getRateOfInterest(){return 0;}
3. }
4.
5. class SBI extends Bank{
6. int getRateOfInterest(){return 8;}
7. }
8.
9. class ICICI extends Bank{
10. int getRateOfInterest(){return 7;}
11. }
12. class AXIS extends Bank{
13. int getRateOfInterest(){return 9;}
14. }
15.
16. class Test2{
17. public static void main(String args[]){
18. SBI s=new SBI();
19. ICICI i=new ICICI();
20. AXIS a=new AXIS();
21. System.out.println("SBI Rate of Interest: "+s.getRateOfInterest());
22. System.out.println("ICICI Rate of Interest: "+i.getRateOfInterest());
23. System.out.println("AXIS Rate of Interest: "+a.getRateOfInterest());
24. }
25. }
Test it Now
Output:
SBI Rate of Interest: 8
ICICI Rate of Interest: 7
AXIS Rate of Interest: 9

66

Can we override static method?


No, static method cannot be overridden. It can be proved by runtime polymorphism so
we will learn it later.

Why we cannot override static method?


because static method is bound with class whereas instance method is bound with object.
Static belongs to class area and instance belongs to heap area.

Can we override java main method?


No, because main is a static method.

What is the difference between method Overloading and Method Overriding?


There are three basic differences between the method overloading and method overriding.
They are as follows:

Method Overloading

Method Overriding

1) Method overloading is used to

Method overriding is used to provide the specific

increase the readability of the

implementation of the method that is already provided by

program.

its super class.

2) method overloading is performed

Method overriding occurs in two classes that have IS-A

within a class.

relationship.

3) In case of method overloading

In case of method overriding parameter must be same.

parameter must be different.

More topics on Method Overriding (Not For Fresher)


Method Overriding with Access Modifier

67

Let's see the concept of method overriding with access modifier.


Exception Handling with Method Overriding
Let's see the concept of method overriding with exception handling.

Covariant Return Type


The covariant return type specifies that the return type may vary in the same direction as
the subclass.
Before Java5, it was not possible to override any method by changing the return type. But
now, since Java5, it is possible to override method by changing the return type if subclass
overrides any method whose return type is Non-Primitive but it changes its return type to
subclass type. Let's take a simple example:

Note: If you are beginner to java, skip this topic and return to it after OOPs
concepts.

Simple example of Covariant Return Type


1. class A{
2. A get(){return this;}
3. }
4.
5. class B1 extends A{
6. B1 get(){return this;}
7. void message(){System.out.println("welcome to covariant return type");}
8.
9. public static void main(String args[]){
10. new B1().get().message();
11. }
12. }
Test it Now
Output:welcome to covariant return type
As you can see in the above example, the return type of the get() method of A class is A but
the return type of the get() method of B class is B. Both methods have different return type
but it is method overriding. This is known as covariant return type.

68

super keyword
The super is a reference variable that is used to refer immediate parent class object.
Whenever you create the instance of subclass, an instance of parent class is created
implicitly i.e. referred by super reference variable.

Usage of super Keyword


1. super is used to refer immediate parent class instance variable.
2. super() is used to invoke immediate parent class constructor.
3. super is used to invoke immediate parent class method.

1) super is used to refer immediate parent class instance variable.


Problem without super keyword
1. class Vehicle{
2.
int speed=50;
3. }
4.
5. class Bike3 extends Vehicle{
6.
int speed=100;
7.
8.
void display(){
9.
System.out.println(speed);//will print speed of Bike
10. }
11. public static void main(String args[]){
12. Bike3 b=new Bike3();
13. b.display();
14.
15. }
16. }
Test it Now
Output:100
In the above example Vehicle and Bike both class have a common property speed.
Instance variable of current class is refered by instance bydefault, but I have to refer
parent class instance variable that is why we use super keyword to distinguish between
parent class instance variable and current class instance variable.

Solution by super keyword


1. //example of super keyword
2.
3. class Vehicle{

69
4.
int speed=50;
5. }
6.
7. class Bike4 extends Vehicle{
8.
int speed=100;
9.
10. void display(){
11. System.out.println(super.speed);//will print speed of Vehicle now
12. }
13. public static void main(String args[]){
14. Bike4 b=new Bike4();
15. b.display();
16.
17. }
18. }
Test it Now
Output:50

2) super is used to invoke parent class constructor.


The super keyword can also be used to invoke the parent class constructor as given
below:
1. class Vehicle{
2.
Vehicle(){System.out.println("Vehicle is created");}
3. }
4.
5. class Bike5 extends Vehicle{
6.
Bike5(){
7.
super();//will invoke parent class constructor
8.
System.out.println("Bike is created");
9.
}
10. public static void main(String args[]){
11. Bike5 b=new Bike5();
12.
13. }
14. }
Test it Now
Output:Vehicle is created
Bike is created

super() is added in each class constructor automatically by compiler.

70

As we know well that default constructor is provided by compiler automatically but it also
adds super() for the first statement.If you are creating your own constructor and you
don't have either this() or super() as the first statement, compiler will provide super() as
the first statement of the constructor.

Another example of super keyword where super() is provided by the


compiler implicitly.
1. class Vehicle{
2.
Vehicle(){System.out.println("Vehicle is created");}
3. }
4.
5. class Bike6 extends Vehicle{
6.
int speed;
7.
Bike6(int speed){
8.
this.speed=speed;
9.
System.out.println(speed);
10. }
11. public static void main(String args[]){
12. Bike6 b=new Bike6(10);
13. }
14. }
Test it Now

71

Output:Vehicle is created
10

3) super can be used to invoke parent class method.


The super keyword can also be used to invoke parent class method. It should be used in
case subclass contains the same method as parent class as in the example given below:
1. class Person{
2. void message(){System.out.println("welcome");}
3. }
4.
5. class Student16 extends Person{
6. void message(){System.out.println("welcome to java");}
7.
8. void display(){
9. message();//will invoke current class message() method
10. super.message();//will invoke parent class message() method
11. }
12.
13. public static void main(String args[]){
14. Student16 s=new Student16();
15. s.display();
16. }
17. }
Test it Now
Output:welcome to java
welcome
In the above example Student and Person both classes have message() method if we call
message() method from Student class, it will call the message() method of Student class
not of Person class because priority is given to local.

In case there is no method in subclass as parent, there is no need to use super. In the
example given below message() method is invoked from Student class but Student class
does not have message() method, so you can directly call message() method.

Program in case super is not required


1.
2.
3.
4.
5.
6.
7.

class Person{
void message(){System.out.println("welcome");}
}
class Student17 extends Person{
void display(){

72
8. message();//will invoke parent class message() method
9. }
10.
11. public static void main(String args[]){
12. Student17 s=new Student17();
13. s.display();
14. }
15. }
Test it Now
Output:welcome

Instance initializer block:


1. Instance initializer block
2. Example of Instance initializer block
3. What is invoked firstly instance initializer block or constructor?
4. Rules for instance initializer block
5. Program of instance initializer block that is invoked after super()
Instance Initializer block is used to initialize the instance data member. It run each
time when object of the class is created.
The initialization of the instance variable can be directly but there can be performed
extra operations while initializing the instance variable in the instance initializer block.

Que) What is the use of instance initializer block while we can directly
assign a value in instance data member? For example:
1. class Bike{
2.
int speed=100;
3. }

Why use instance initializer block?


Suppose I have to perform some operations while assigning value to instance data
member e.g. a for loop to fill a complex array or error handling etc.

73

Example of instance initializer block


Let's see the simple example of instance initializer block the performs initialization.
1. class Bike7{
2.
int speed;
3.
4.
Bike7(){System.out.println("speed is "+speed);}
5.
6.
{speed=100;}
7.
8.
public static void main(String args[]){
9.
Bike7 b1=new Bike7();
10.
Bike7 b2=new Bike7();
11.
}
12. }
Test it Now
Output:speed is 100
speed is 100

There are three places in java where you can perform operations:
1. method
2. constructor
3. block

What is invoked firstly instance initializer block or


constructor?
1. class Bike8{
2.
int speed;
3.
4.
Bike8(){System.out.println("constructor is invoked");}
5.
6.
{System.out.println("instance initializer block invoked");}
7.
8.
public static void main(String args[]){
9.
Bike8 b1=new Bike8();
10.
Bike8 b2=new Bike8();
11.
}
12. }
Test it Now
Output:instance initializer block invoked

74

constructor is invoked
instance initializer block invoked
constructor is invoked
In the above example, it seems that instance initializer block is firstly invoked but NO.
Instance intializer block is invoked at the time of object creation. The java compiler
copies the instance initializer block in the constructor after the first statement super().
So firstly, constructor is invoked. Let's understand it by the figure given below:

Note: The java compiler copies the code of instance initializer block in
every constructor.

Rules for instance initializer block :

75

There are mainly three rules for the instance initializer block. They are as follows:
1. The instance initializer block is created when instance of the class is created.
2. The instance initializer block is invoked after the parent class constructor is invoked
(i.e. after super() constructor call).
3. The instance initializer block comes in the order in which they appear.

Program of instance initializer block that is invoked


after super()
1. class A{
2. A(){
3. System.out.println("parent class constructor invoked");
4. }
5. }
6. class B2 extends A{
7. B2(){
8. super();
9. System.out.println("child class constructor invoked");
10. }
11.
12. {System.out.println("instance initializer block is invoked");}
13.
14. public static void main(String args[]){
15. B2 b=new B2();
16. }
17. }
Test it Now
Output:parent class constructor invoked
instance initializer block is invoked
child class constructor invoked

Another example of instance block


1. class A{
2. A(){
3. System.out.println("parent class constructor invoked");
4. }
5. }
6.
7. class B3 extends A{
8. B3(){
9. super();
10. System.out.println("child class constructor invoked");
11. }

76
12.
13. B3(int a){
14. super();
15. System.out.println("child class constructor invoked "+a);
16. }
17.
18. {System.out.println("instance initializer block is invoked");}
19.
20. public static void main(String args[]){
21. B3 b1=new B3();
22. B3 b2=new B3(10);
23. }
24. }
Test it Now
Output:parent class constructor invoked
instance initializer block is invoked
child class constructor invoked
parent class constructor invoked
instance initializer block is invoked
child class constructor invoked 10

Final Keyword In Java


1. Final variable
2. Final method
3. Final class
4. Is final method inherited ?
5. Blank final variable
6. Static blank final variable
7. Final parameter
8. Can you declare a final constructor
The final keyword in java is used to restrict the user. The final keyword can be used in
many context. Final can be:
1. variable
2. method
3. class
The final keyword can be applied with the variables, a final variable that have no value it is
called blank final variable or uninitialized final variable. It can be initialized in the
constructor only. The blank final variable can be static also which will be initialized in the

77

static block only. We will have detailed learning of these. Let's first learn the basics of final
keyword.

1) final variable
If you make any variable as final, you cannot change the value of final variable(It will be
constant).

Example of final variable


There is a final variable speedlimit, we are going to change the value of this variable, but It
can't be changed because final variable once assigned a value can never be changed.
1. class Bike9{
2. final int speedlimit=90;//final variable
3. void run(){
4.
speedlimit=400;
5. }
6. public static void main(String args[]){
7. Bike9 obj=new Bike9();
8. obj.run();
9. }
10. }//end of class
Test it Now
Output:Compile Time Error

2) final method
If you make any method as final, you cannot override it.

78

Example of final method


1. class Bike{
2.
final void run(){System.out.println("running");}
3. }
4.
5. class Honda extends Bike{
6.
void run(){System.out.println("running safely with 100kmph");}
7.
8.
public static void main(String args[]){
9.
Honda honda= new Honda();
10. honda.run();
11. }
12. }
Test it Now
Output:Compile Time Error

3) final class
If you make any class as final, you cannot extend it.

Example of final class


1. final class Bike{}
2.
3. class Honda1 extends Bike{
4.
void run(){System.out.println("running safely with 100kmph");}
5.
6.
public static void main(String args[]){
7.
Honda1 honda= new Honda();
8.
honda.run();
9.
}
10. }
Test it Now
Output:Compile Time Error

Q) Is final method inherited?


Ans) Yes, final method is inherited but you cannot override it. For Example:
1. class Bike{
2.
final void run(){System.out.println("running...");}
3. }
4. class Honda2 extends Bike{
5.
public static void main(String args[]){

79
6.
new Honda2().run();
7.
}
8. }
Test it Now
Output:running...

Q) What is blank or uninitialized final variable?


A final variable that is not initialized at the time of declaration is known as blank final
variable.
If you want to create a variable that is initialized at the time of creating object and once
initialized may not be changed, it is useful. For example PAN CARD number of an employee.
It can be initialized only in constructor.

Example of blank final variable


1.
2.
3.
4.
5.
6.

class Student{
int id;
String name;
final String PAN_CARD_NUMBER;
...
}

Que) Can we initialize blank final variable?


Yes, but only in constructor. For example:
1. class Bike10{
2.
final int speedlimit;//blank final variable
3.
4.
Bike10(){
5.
speedlimit=70;
6.
System.out.println(speedlimit);
7.
}
8.
9.
public static void main(String args[]){
10.
new Bike10();
11. }
12. }
Test it Now
Output:70

80

static blank final variable


A static final variable that is not initialized at the time of declaration is known as static blank
final variable. It can be initialized only in static block.

Example of static blank final variable


1. class A{
2.
static final int data;//static blank final variable
3.
static{ data=50;}
4.
public static void main(String args[]){
5.
System.out.println(A.data);
6. }
7. }

Q) What is final parameter?


If you declare any parameter as final, you cannot change the value of it.
1. class Bike11{
2.
int cube(final int n){
3.
n=n+2;//can't be changed as n is final
4.
n*n*n;
5.
}
6.
public static void main(String args[]){
7.
Bike11 b=new Bike11();
8.
b.cube(5);
9. }
10. }
Test it Now
Output:Compile Time Error

Q) Can we declare a constructor final?


No, because constructor is never inherited.
next>><<prev

Runtime Polymorphism in Java


1. Runtime Polymorphism
2. Upcasting
3. Example of Runtime Polymorphism

81

4. Runtime Polymorphism with data members


Runtime polymorphism or Dynamic Method Dispatch is a process in which a call to
an overridden method is resolved at runtime rather than compile-time.
In this process, an overridden method is called through the reference variable of a
superclass. The determination of the method to be called is based on the object being
referred to by the reference variable.
Let's first understand the upcasting before Runtime Polymorphism.

Upcasting
When reference variable of Parent class refers to the object of Child class, it is known as
upcasting. For example:

1. class A{}
2. class B extends A{}
1. A a=new B();//upcasting

Example of Runtime Polymorphism


In this example, we are creating two classes Bike and Splendar. Splendar class extends
Bike class and overrides its run() method. We are calling the run method by the
reference variable of Parent class. Since it refers to the subclass object and subclass
method overrides the Parent class method, subclass method is invoked at runtime.
Since method invocation is determined by the JVM not compiler, it is known as runtime
polymorphism.
1. class Bike{
2.
void run(){System.out.println("running");}

82
3. }
4. class Splender extends Bike{
5.
void run(){System.out.println("running safely with 60km");}
6.
7.
public static void main(String args[]){
8.
Bike b = new Splender();//upcasting
9.
b.run();
10. }
11. }
Test it Now
Output:running safely with 60km.

Real example of Java Runtime Polymorphism


Consider a scenario, Bank is a class that provides method to get the rate of interest. But,
rate of interest may differ according to banks. For example, SBI, ICICI and AXIS banks
could provide 8%, 7% and 9% rate of interest.

Note: It is also given in method overriding but there was no upcasting.


1.
2.
3.
4.
5.
6.
7.
8.
9.

class Bank{
int getRateOfInterest(){return 0;}
}
class SBI extends Bank{
int getRateOfInterest(){return 8;}
}
class ICICI extends Bank{

83
10. int getRateOfInterest(){return 7;}
11. }
12. class AXIS extends Bank{
13. int getRateOfInterest(){return 9;}
14. }
15.
16. class Test3{
17. public static void main(String args[]){
18. Bank b1=new SBI();
19. Bank b2=new ICICI();
20. Bank b3=new AXIS();
21. System.out.println("SBI Rate of Interest: "+b1.getRateOfInterest());
22. System.out.println("ICICI Rate of Interest: "+b2.getRateOfInterest());
23. System.out.println("AXIS Rate of Interest: "+b3.getRateOfInterest());
24. }
25. }
Test it Now
Output:
SBI Rate of Interest: 8
ICICI Rate of Interest: 7
AXIS Rate of Interest: 9

Runtime Polymorphism with data member


Method is overridden not the datamembers, so runtime polymorphism can't be
achieved by data members.
In the example given below, both the classes have a datamember speedlimit, we are
accessing the datamember by the reference variable of Parent class which refers to
the subclass object. Since we are accessing the datamember which is not overridden,
hence it will access the datamember of Parent class always.

Rule: Runtime polymorphism can't be achieved by data members.


1. class Bike{
2. int speedlimit=90;
3. }
4. class Honda3 extends Bike{
5. int speedlimit=150;
6.
7. public static void main(String args[]){
8.
Bike obj=new Honda3();
9.
System.out.println(obj.speedlimit);//90

84
10. }
Test it Now
Output:90

Runtime Polymorphism with Multilevel Inheritance


Let's see the simple example of Runtime Polymorphism with multilevel inheritance.
1. class Animal{
2. void eat(){System.out.println("eating");}
3. }
4.
5. class Dog extends Animal{
6. void eat(){System.out.println("eating fruits");}
7. }
8.
9. class BabyDog extends Dog{
10. void eat(){System.out.println("drinking milk");}
11.
12. public static void main(String args[]){
13. Animal a1,a2,a3;
14. a1=new Animal();
15. a2=new Dog();
16. a3=new BabyDog();
17.
18. a1.eat();
19. a2.eat();
20. a3.eat();
21. }
22. }
Test it Now
Output: eating
eating fruits
drinking Milk

Try for Output


1. class Animal{
2. void eat(){System.out.println("animal is eating...");}
3. }
4.
5. class Dog extends Animal{
6. void eat(){System.out.println("dog is eating...");}
7. }
8.
9. class BabyDog1 extends Dog{
10. public static void main(String args[]){

85
11. Animal a=new BabyDog1();
12. a.eat();
13. }}
Test it Now
Output: Dog is eating
Since, BabyDog is not overriding the eat() method, so eat() method of Dog class is
invoked.

Static Binding and Dynamic Binding

Connecting a method call to the method body is known as binding.


There are two types of binding
1. static binding (also known as early binding).
2. dynamic binding (also known as late binding).

Understanding Type
Let's understand the type of instance.

1) variables have a type


Each variable has a type, it may be primitive and non-primitive.
1. int data=30;
Here data variable is a type of int.

2) References have a type


1. class Dog{
2. public static void main(String args[]){
3.
Dog d1;//Here d1 is a type of Dog
4. }

86
5. }

3) Objects have a type


An object is an instance of particular java class,but it is also an instance of its superclass.
1. class Animal{}
2.
3. class Dog extends Animal{
4. public static void main(String args[]){
5.
Dog d1=new Dog();
6. }
7. }
Here d1 is an instance of Dog class, but it is also an instance of Animal.

static binding
When type of the object is determined at compiled time(by the compiler), it is known as
static binding.
If there is any private, final or static method in a class, there is static binding.

Example of static binding


1. class Dog{
2. private void eat(){System.out.println("dog is eating...");}
3.
4. public static void main(String args[]){
5.
Dog d1=new Dog();
6.
d1.eat();
7. }
8. }

Dynamic binding
When type of the object is determined at run-time, it is known as dynamic binding.

Example of dynamic binding


1. class Animal{
2. void eat(){System.out.println("animal is eating...");}
3. }
4.
5. class Dog extends Animal{

87
6. void eat(){System.out.println("dog is eating...");}
7.
8. public static void main(String args[]){
9.
Animal a=new Dog();
10. a.eat();
11. }
12. }
Test it Now
Output:dog is eating...
In the above example object type cannot be determined by the compiler, because the
instance of Dog is also an instance of Animal.So compiler doesn't know its type, only its
base type.

Java instanceof
1. java instanceof
2. Example of instanceof operator
3. Applying the instanceof operator with a variable the have null value
4. Downcasting with instanceof operator
5. Downcasting without instanceof operator
The java instanceof operator is used to test whether the object is an instance of the
specified type (class or subclass or interface).
The instanceof in java is also known as type comparison operator because it compares the
instance with type. It returns either true or false. If we apply the instanceof operator with
any variable that has null value, it returns false.

Simple example of java instanceof


Let's see the simple example of instance operator where it tests the current class.
1. class Simple1{
2. public static void main(String args[]){
3. Simple1 s=new Simple1();
4. System.out.println(s instanceof Simple);//true
5. }
6. }
Test it Now
Output:true

88

An object of subclass type is also a type of parent class. For example, if Dog extends Animal
then object of Dog can be referred by either Dog or Animal class.

Another example of java instanceof operator


1. class Animal{}
2. class Dog1 extends Animal{//Dog inherits Animal
3.
4. public static void main(String args[]){
5. Dog1 d=new Dog1();
6. System.out.println(d instanceof Animal);//true
7. }
8. }
Test it Now
Output:true

instanceof in java with a variable that have null value


If we apply instanceof operator with a variable that have null value, it returns false. Let's
see the example given below where we apply instanceof operator with the variable that
have null value.
1. class Dog2{
2. public static void main(String args[]){
3.
Dog2 d=null;
4.
System.out.println(d instanceof Dog2);//false
5. }
6. }
Test it Now
Output:false

Downcasting with java instanceof operator


When Subclass type refers to the object of Parent class, it is known as downcasting. If we
perform it directly, compiler gives Compilation error. If you perform it by typecasting,
ClassCastException is thrown at runtime. But if we use instanceof operator, downcasting is
possible.
1. Dog d=new Animal();//Compilation error

89

If we perform downcasting by typecasting, ClassCastException is thrown at runtime.


1. Dog d=(Dog)new Animal();
2. //Compiles successfully but ClassCastException is thrown at runtime

Possibility of downcasting with instanceof


Let's see the example, where downcasting is possible by instanceof operator.
1. class Animal { }
2.
3. class Dog3 extends Animal {
4.
static void method(Animal a) {
5.
if(a instanceof Dog3){
6.
Dog3 d=(Dog3)a;//downcasting
7.
System.out.println("ok downcasting performed");
8.
}
9.
}
10.
11. public static void main (String [] args) {
12.
Animal a=new Dog3();
13.
Dog3.method(a);
14. }
15.
16. }
Test it Now
Output:ok downcasting performed

Downcasting without the use of java instanceof


Downcasting can also be performed without the use of instanceof operator as displayed in
the following example:
1. class Animal { }
2. class Dog4 extends Animal {
3.
static void method(Animal a) {
4.
Dog4 d=(Dog4)a;//downcasting
5.
System.out.println("ok downcasting performed");
6.
}
7.
public static void main (String [] args) {
8.
Animal a=new Dog4();
9.
Dog4.method(a);
10. }
11. }
Test it Now
Output:ok downcasting performed

90

Let's take closer look at this, actual object that is referred by a, is an object of Dog class. So
if we downcast it, it is fine. But what will happen if we write:
1. Animal a=new Animal();
2. Dog.method(a);
3. //Now ClassCastException but not in case of instanceof operator

Understanding Real use of instanceof in java


Let's see the real use of instanceof keyword by the example given below.
1. interface Printable{}
2. class A implements Printable{
3. public void a(){System.out.println("a method");}
4. }
5. class B implements Printable{
6. public void b(){System.out.println("b method");}
7. }
8.
9. class Call{
10. void invoke(Printable p){//upcasting
11. if(p instanceof A){
12. A a=(A)p;//Downcasting
13. a.a();
14. }
15. if(p instanceof B){
16. B b=(B)p;//Downcasting
17. b.b();
18. }
19.
20. }
21. }//end of Call class
22.
23. class Test4{
24. public static void main(String args[]){
25. Printable p=new B();
26. Call c=new Call();
27. c.invoke(p);
28. }
29. }
Test it Now
Output: b method

Abstract class in Java


A class that is declared with abstract keyword, is known as abstract class in java. It can
have abstract and non-abstract methods (method with body).

91

Before learning java abstract class, let's understand the abstraction in java first.

Abstraction in Java
Abstraction is a process of hiding the implementation details and showing only
functionality to the user.
Another way, it shows only important things to the user and hides the internal details for
example sending sms, you just type the text and send the message. You don't know the
internal processing about the message delivery.
Abstraction lets you focus on what the object does instead of how it does it.

Ways to achieve Abstaction


There are two ways to achieve abstraction in java
1. Abstract class (0 to 100%)
2. Interface (100%)

Abstract class in Java


A class that is declared as abstract is known as abstract class. It needs to be extended
and its method implemented. It cannot be instantiated.

Example abstract class


1. abstract class A{}

abstract method
A method that is declared as abstract and does not have implementation is known as
abstract method.

Example abstract method


1. abstract void printStatus();//no body and abstract

92

Example of abstract class that has abstract method


In this example, Bike the abstract class that contains only one abstract method run. It
implementation is provided by the Honda class.
1. abstract class Bike{
2.
abstract void run();
3. }
4.
5. class Honda4 extends Bike{
6. void run(){System.out.println("running safely..");}
7.
8. public static void main(String args[]){
9. Bike obj = new Honda4();
10. obj.run();
11. }
12. }
Test it Now
running safely..

Understanding the real scenario of abstract class


In this example, Shape is the abstract class, its implementation is provided by the
Rectangle and Circle classes. Mostly, we don't know about the implementation class (i.e.
hidden to the end user) and object of the implementation class is provided by the factory
method.
A factory method is the method that returns the instance of the class. We will learn about
the factory method later.
In this example, if you create the instance of Rectangle class, draw() method of Rectangle
class will be invoked.

File: TestAbstraction1.java
1.
2.
3.
4.
5.
6.
7.
8.

abstract class Shape{


abstract void draw();
}
//In real scenario, implementation is provided by others i.e. unknown by end user
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle");}
}

93
9. class Circle1 extends Shape{
10. void draw(){System.out.println("drawing circle");}
11. }
12.
13. //In real scenario, method is called by programmer or user
14. class TestAbstraction1{
15. public static void main(String args[]){
16. Shape s=new Circle1();//In real scenario, object is provided through method e.g. getShape
() method
17. s.draw();
18. }
19. }
Test it Now
drawing circle

Another example of abstract class in java


File: TestBank.java
1. abstract class Bank{
2. abstract int getRateOfInterest();
3. }
4.
5. class SBI extends Bank{
6. int getRateOfInterest(){return 7;}
7. }
8. class PNB extends Bank{
9. int getRateOfInterest(){return 7;}
10. }
11.
12. class TestBank{
13. public static void main(String args[]){
14. Bank b=new SBI();//if object is PNB, method of PNB will be invoked
15. int interest=b.getRateOfInterest();
16. System.out.println("Rate of Interest is: "+interest+" %");
17. }}
Test it Now
Rate of Interest is: 7 %

Abstract class having constructor, data member,


methods etc.
An abstract class can have data member, abstract method, method body, constructor and
even main() method.

94
File: TestAbstraction2.java
1. //example of abstract class that have method body
2. abstract class Bike{
3.
Bike(){System.out.println("bike is created");}
4.
abstract void run();
5.
void changeGear(){System.out.println("gear changed");}
6. }
7.
8. class Honda extends Bike{
9. void run(){System.out.println("running safely..");}
10. }
11. class TestAbstraction2{
12. public static void main(String args[]){
13. Bike obj = new Honda();
14. obj.run();
15. obj.changeGear();
16. }
17. }
Test it Now
bike is created
running safely..
gear changed

Rule: If there is any abstract method in a class, that class must be abstract.
1. class Bike12{
2. abstract void run();
3. }
Test it Now
compile time error

Rule: If you are extending any abstract class that have abstract method, you must
either provide the implementation of the method or make this class abstract.

Another real scenario of abstract class


The abstract class can also be used to provide some implementation of the interface. In
such case, the end user may not be forced to override all the methods of the interface.

95

Note: If you are beginner to java, learn interface first and skip this example.
1. interface A{
2. void a();
3. void b();
4. void c();
5. void d();
6. }
7.
8. abstract class B implements A{
9. public void c(){System.out.println("I am C");}
10. }
11.
12. class M extends B{
13. public void a(){System.out.println("I am a");}
14. public void b(){System.out.println("I am b");}
15. public void d(){System.out.println("I am d");}
16. }
17.
18. class Test5{
19. public static void main(String args[]){
20. A a=new M();
21. a.a();
22. a.b();
23. a.c();
24. a.d();
25. }}
Test it Now
Output:I am a
I am b
I am c
I am d

Interface in Java
1. Interface
2. Example of Interface
3. Multiple inheritance by Interface
4. Why multiple inheritance is supported in Interface while it is not supported in case of class.
5. Marker Interface
6. Nested Interface
An interface in java is a blueprint of a class. It has static constants and abstract methods
only.

96

The interface in java is a mechanism to achieve fully abstraction. There can be only
abstract methods in the java interface not method body. It is used to achieve fully
abstraction and multiple inheritance in Java.
Java Interface also represents IS-A relationship.
It cannot be instantiated just like abstract class.

Why use Java interface?


There are mainly three reasons to use interface. They are given below.

It is used to achieve fully abstraction.


By interface, we can support the functionality of multiple inheritance.
It can be used to achieve loose coupling.

The java compiler adds public and abstract keywords before the interface method
and public, static and final keywords before data members.
In other words, Interface fields are public, static and final bydefault, and methods are public
and abstract.

97

Understanding relationship between classes and


interfaces
As shown in the figure given below, a class extends another class, an interface extends
another interface but a class implements an interface.

98

Simple example of Java interface


In this example, Printable interface have only one method, its implementation is provided
in the A class.
1. interface printable{
2. void print();
3. }
4.
5. class A6 implements printable{
6. public void print(){System.out.println("Hello");}
7.
8. public static void main(String args[]){
9. A6 obj = new A6();
10. obj.print();
11. }
12. }
Test it Now
Output:Hello

Multiple inheritance in Java by interface


If a class implements multiple interfaces, or an interface extends multiple interfaces i.e.
known as multiple inheritance.

99

1. interface Printable{
2. void print();
3. }
4.
5. interface Showable{
6. void show();
7. }
8.
9. class A7 implements Printable,Showable{
10.
11. public void print(){System.out.println("Hello");}
12. public void show(){System.out.println("Welcome");}
13.
14. public static void main(String args[]){
15. A7 obj = new A7();
16. obj.print();
17. obj.show();
18. }
19. }
Test it Now
Output:Hello
Welcome

Q) Multiple inheritance is not supported through class in java but it


is possible by interface, why?
As we have explained in the inheritance chapter, multiple inheritance is not supported in
case of class. But it is supported in case of interface because there is no ambiguity as
implementation is provided by the implementation class. For example:

100
1. interface Printable{
2. void print();
3. }
4.
5. interface Showable{
6. void print();
7. }
8.
9. class testinterface1 implements Printable,Showable{
10.
11. public void print(){System.out.println("Hello");}
12.
13. public static void main(String args[]){
14. testinterface1 obj = new testinterface1();
15. obj.print();
16. }
17. }
Test it Now
Hello
As you can see in the above example, Printable and Showable interface have same methods
but its implementation is provided by class A, so there is no ambiguity.

Interface inheritance
A class implements interface but one interface extends another interface .
1. interface Printable{
2. void print();
3. }
4. interface Showable extends Printable{
5. void show();
6. }
7. class Testinterface2 implements Showable{
8.
9. public void print(){System.out.println("Hello");}
10. public void show(){System.out.println("Welcome");}
11.
12. public static void main(String args[]){
13. Testinterface2 obj = new Testinterface2();
14. obj.print();
15. obj.show();
16. }
17. }
Test it Now
Hello

101

Welcome

Q) What is marker or tagged interface?


An interface that have no member is known as marker or tagged interface. For example:
Serializable, Cloneable, Remote etc. They are used to provide some essential information to
the JVM so that JVM may perform some useful operation.
1. //How Serializable interface is written?
2. public interface Serializable{
3. }

Nested Interface in Java


Note: An interface can have another interface i.e. known as nested interface. We will learn it
in detail in the nested classes chapter. For example:
1. interface printable{
2. void print();
3. interface MessagePrintable{
4.
void msg();
5. }
6. }

Java Package
1. Java Package
2. Example of package
3. Accessing package
1. By import packagename.*
2. By import packagename.classname
3. By fully qualified name
4. Subpackage
5. Sending class file to another directory
6. -classpath switch
7. 4 ways to load the class file or jar file
8. How to put two public class in a package
9. Static Import
10. Package class

102

A java package is a group of similar types of classes, interfaces and sub-packages.


Package in java can be categorized in two form, built-in package and user-defined package.
There are many built-in packages such as java, lang, awt, javax, swing, net, io, util, sql etc.
Here, we will have the detailed learning of creating and using user-defined packages.

Advantage of Java Package


1) Java package is used to categorize the classes and interfaces so that they can be easily
maintained.
2) Java package provides access protection.
3) Java package removes naming collision.

103

Simple example of java package


The package keyword is used to create a package in java.
1.
2.
3.
4.
5.
6.
7.

//save as Simple.java
package mypack;
public class Simple{
public static void main(String args[]){
System.out.println("Welcome to package");
}
}

How to compile java package


If you are not using any IDE, you need to follow the syntax given below:
1. javac -d directory javafilename
For example
1. javac -d . Simple.java
The -d switch specifies the destination where to put the generated class file. You can use
any directory name like /home (in case of Linux), d:/abc (in case of windows) etc. If you
want to keep the package within the same directory, you can use . (dot).

How to run java package program


You need to use fully qualified name e.g. mypack.Simple etc to run the class.

To Compile: javac -d . Simple.java


To Run: java mypack.Simple
Output:Welcome to package
The -d is a switch that tells the compiler where to put the class file i.e. it represents
destination. The . represents the current folder.

104

How to access package from another package?


There are three ways to access the package from outside the package.
1. import package.*;
2. import package.classname;
3. fully qualified name.

1) Using packagename.*
If you use package.* then all the classes and interfaces of this package will be accessible
but not subpackages.
The import keyword is used to make the classes and interface of another package
accessible to the current package.

Example of package that import the packagename.*


1. //save by A.java
2.
3. package pack;
4. public class A{
5.
public void msg(){System.out.println("Hello");}
6. }
1. //save by B.java
2.
3. package mypack;
4. import pack.*;
5.
6. class B{
7.
public static void main(String args[]){
8.
A obj = new A();
9.
obj.msg();
10. }
11. }
Output:Hello

2) Using packagename.classname
If you import package.classname then only declared class of this package will be accessible.

105

Example of package by import package.classname


1. //save by A.java
2.
3. package pack;
4. public class A{
5.
public void msg(){System.out.println("Hello");}
6. }
1. //save by B.java
2.
3. package mypack;
4. import pack.A;
5.
6. class B{
7.
public static void main(String args[]){
8.
A obj = new A();
9.
obj.msg();
10. }
11. }
Output:Hello

3) Using fully qualified name


If you use fully qualified name then only declared class of this package will be accessible.
Now there is no need to import. But you need to use fully qualified name every time when
you are accessing the class or interface.
It is generally used when two packages have same class name e.g. java.util and java.sql
packages contain Date class.

Example of package by import fully qualified name


1.
2.
3.
4.
5.
6.
1.
2.
3.
4.
5.
6.
7.
8.

//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
class B{
public static void main(String args[]){
pack.A obj = new pack.A();//using fully qualified name
obj.msg();
}

106
9. }
Output:Hello

Note: If you import a package, subpackages will not be imported.


If you import a package, all the classes and interface of that package will be imported
excluding the classes and interfaces of the subpackages. Hence, you need to import the
subpackage as well.

Note: Sequence of the program must be package then import then class.

Subpackage in java
Package inside the package is called the subpackage. It should be created to categorize
the package further.
Let's take an example, Sun Microsystem has definded a package named java that contains
many classes like System, String, Reader, Writer, Socket etc. These classes represent a
particular group e.g. Reader and Writer classes are for Input/Output operation, Socket and
ServerSocket classes are for networking etc and so on. So, Sun has subcategorized the java
package into subpackages such as lang, net, io etc. and put the Input/Output related
classes in io package, Server and ServerSocket classes in net packages and so on.

107

The standard of defining package is domain.company.package e.g.


com.javatpoint.bean or org.sssit.dao.

Example of Subpackage
1. package com.javatpoint.core;
2. class Simple{
3.
public static void main(String args[]){
4.
System.out.println("Hello subpackage");
5.
}
6. }
To Compile: javac -d . Simple.java
To Run: java com.javatpoint.core.Simple
Output:Hello subpackage

How to send the class file to another directory or drive?


There is a scenario, I want to put the class file of A.java source file in classes folder of c:
drive. For example:

108
1.
2.
3.
4.
5.
6.
7.
8.

//save as Simple.java
package mypack;
public class Simple{
public static void main(String args[]){
System.out.println("Welcome to package");
}
}

To Compile:
e:\sources> javac -d c:\classes Simple.java

To Run:
To run this program from e:\source directory, you need to set classpath of the directory
where the class file resides.
e:\sources> set classpath=c:\classes;.;
e:\sources> java mypack.Simple

Another way to run this program by -classpath switch of java:


The -classpath switch can be used with javac and java tool.
To run this program from e:\source directory, you can use -classpath switch of java that
tells where to look for class file. For example:
e:\sources> java -classpath c:\classes mypack.Simple
Output:Welcome to package

Ways to load the class files or jar files


There are two ways to load the class files temporary and permanent.

Temporary
o By setting the classpath in the command prompt
o By -classpath switch
Permanent
o By setting the classpath in the environment variables
o By creating the jar file, that contains all the class files, and copying the jar file
in the jre/lib/ext folder.

109

Rule: There can be only one public class in a java source file and it must be saved
by the public class name.
1.
2.
3.
4.
5.

//save as C.java otherwise Compilte Time Error


class A{}
class B{}
public class C{}

How to put two public classes in a package?


If you want to put two public classes in a package, have two java source files containing
one public class, but keep the package name same. For example:
1.
2.
3.
4.
1.
2.
3.
4.

//save as A.java
package javatpoint;
public class A{}
//save as B.java
package javatpoint;
public class B{}

Static Import:
The static import feature of Java 5 facilitate the java programmer to access any static
member of a class directly. There is no need to qualify it by the class name.

Advantage of static import:

Less coding is required if you have access any static member of a class oftenly.

Disadvantage of static import:

If you overuse the static import feature, it makes the program unreadable and
unmaintainable.

Simple Example of static import


1. import static java.lang.System.*;

110
2. class StaticImportExample{
3.
public static void main(String args[]){
4.
5.
out.println("Hello");//Now no need of System.out
6.
out.println("Java");
7.
8. }
9. }
10.
Test it Now
Output:Hello
Java

What is the difference between import and static import?


The import allows the java programmer to access classes of a package without package
qualification whereas the static import feature allows to access the static members of a
class without the class qualification. The import provides accessibility to classes and
interface whereas static import provides accessibility to static members of the class.

Autoboxing and Unboxing:


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

Advantage of Autoboxing and Unboxing:


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

Simple Example of Autoboxing in java:


1.
2. class BoxingExample1{
3.
public static void main(String args[]){
4.
int a=50;
5.
Integer a2=new Integer(a);//Boxing
6.
7.
Integer a3=5;//Boxing
8.

111
9.
System.out.println(a2+" "+a3);
10. }
11. }
12.
Test it Now
Output:50 5

download this example

Simple Example of Unboxing in java:


The automatic conversion of wrapper class type into corresponding primitive type, is known
as Unboxing. Let's see the example of unboxing:
1.
2. class UnboxingExample1{
3.
public static void main(String args[]){
4.
Integer i=new Integer(50);
5.
int a=i;
6.
7.
System.out.println(a);
8. }
9. }
10.
Test it Now
Output:50

Autoboxing and Unboxing with comparison operators


Autoboxing can be performed with comparison operators. Let's see the example of
boxing with comparison operator:
1.
2. class UnboxingExample2{
3.
public static void main(String args[]){
4.
Integer i=new Integer(50);
5.
6.
if(i<100){
//unboxing internally
7.
System.out.println(i);
8.
}
9. }
10. }
11.
Test it Now

112

Output:50

Autoboxing and Unboxing with method overloading


In method overloading, boxing and unboxing can be performed. There are some rules for
method overloading with boxing:

Widening beats boxing


Widening beats varargs
Boxing beats varargs

1) Example of Autoboxing where widening beats boxing


If there is possibility of widening and boxing, widening beats boxing.
1.
2. class Boxing1{
3.
static void m(int i){System.out.println("int");}
4.
static void m(Integer i){System.out.println("Integer");}
5.
6.
public static void main(String args[]){
7.
short s=30;
8.
m(s);
9. }
10. }
11.
Test it Now
Output:int

2) Example of Autoboxing where widening beats varargs


If there is possibility of widening and varargs, widening beats var-args.
1.
2. class Boxing2{
3.
static void m(int i, int i2){System.out.println("int int");}
4.
static void m(Integer... i){System.out.println("Integer...");}
5.
6.
public static void main(String args[]){
7.
short s1=30,s2=40;
8.
m(s1,s2);
9. }
10. }
11.
Test it Now

113

Output:int int

3) Example of Autoboxing where boxing beats varargs


Let's see the program where boxing beats variable argument:
1.
2. class Boxing3{
3.
static void m(Integer i){System.out.println("Integer");}
4.
static void m(Integer... i){System.out.println("Integer...");}
5.
6.
public static void main(String args[]){
7.
int a=30;
8.
m(a);
9. }
10. }
11.
Test it Now
Output:Integer

Method overloading with Widening and Boxing


Widening and Boxing can't be performed as given below:
1.
2. class Boxing4{
3.
static void m(Long l){System.out.println("Long");}
4.
5.
public static void main(String args[]){
6.
int a=30;
7.
m(a);
8. }
9. }
10.
Test it Now
Output:Compile Time Error

Access Modifiers in java


1. private access modifier
2. Role of private constructor
3. default access modifier
4. protected access modifier
5. public access modifier
6. Applying access modifier with method overriding

114

There are two types of modifiers in java: access modifiers and non-access modifiers.
The access modifiers in java specifies accessibility (scope) of a data member, method,
constructor or class.
There are 4 types of java access modifiers:
1.
2.
3.
4.

private
default
protected
public

There are many non-access modifiers such as static, abstract, synchronized, native, volatile,
transient etc. Here, we will learn access modifiers.

1) private access modifier


The private access modifier is accessible only within class.

Simple example of private access modifier


In this example, we have created two classes A and Simple. A class contains private data
member and private method. We are accessing these private members from outside the
class, so there is compile time error.
1. class A{
2. private int data=40;
3. private void msg(){System.out.println("Hello java");}
4. }
5.
6. public class Simple{
7. public static void main(String args[]){
8.
A obj=new A();
9.
System.out.println(obj.data);//Compile Time Error
10. obj.msg();//Compile Time Error
11. }
12. }

Role of Private Constructor


If you make any class constructor private, you cannot create the instance of that class
from outside the class. For example:
1. class A{

115
2.
3.
4.
5.
6.
7.
8.
9.

private A(){}//private constructor


void msg(){System.out.println("Hello java");}
}
public class Simple{
public static void main(String args[]){
A obj=new A();//Compile Time Error
}
}

Note: A class cannot be private or protected except nested class.

2) default access modifier


If you don't use any modifier, it is treated as default bydefault. The default modifier is
accessible only within package.

Example of default access modifier


In this example, we have created two packages pack and mypack. We are accessing the
A class from outside its package, since A class is not public, so it cannot be accessed
from outside the package.
1.
2.
3.
4.
5.
1.
2.
3.
4.
5.
6.
7.
8.
9.

//save by A.java
package pack;
class A{
void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();//Compile Time Error
obj.msg();//Compile Time Error
}
}
In the above example, the scope of class A and its method msg() is default so it cannot be
accessed from outside the package.

116

3) protected access modifier


The protected access modifier is accessible within package and outside the package but
through inheritance only.
The protected access modifier can be applied on the data member, method and constructor.
It can't be applied on the class.

Example of protected access modifier


In this example, we have created the two packages pack and mypack. The A class of pack
package is public, so can be accessed from outside the package. But msg method of this
package is declared as protected, so it can be accessed from outside the class only through
inheritance.
1. //save by A.java
2. package pack;
3. public class A{
4. protected void msg(){System.out.println("Hello");}
5. }
1. //save by B.java
2. package mypack;
3. import pack.*;
4.
5. class B extends A{
6.
public static void main(String args[]){
7.
B obj = new B();
8.
obj.msg();
9.
}
10. }
Output:Hello

4) public access modifier


The public access modifier is accessible everywhere. It has the widest scope among all
other modifiers.

Example of public access modifier


1.
2.
3.
4.
5.

//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}

117
6. }
1. //save by B.java
2.
3. package mypack;
4. import pack.*;
5.
6. class B{
7.
public static void main(String args[]){
8.
A obj = new A();
9.
obj.msg();
10. }
11. }
Output:Hello

Understanding all java access modifiers


Let's understand the access modifiers by a simple table.

Access Modifier

within class

within package

outside package by subclass only

outside package

Private

Default

Protected

Public

Java access modifiers with method overriding


If you are overriding any method, overridden method (i.e. declared in subclass) must not be
more restrictive.
1.
2.
3.
4.
5.
6.
7.

class A{
protected void msg(){System.out.println("Hello java");}
}
public class Simple extends A{
void msg(){System.out.println("Hello java");}//C.T.Error
public static void main(String args[]){

118
8.
Simple obj=new Simple();
9.
obj.msg();
10. }
11. }
The default modifier is more restrictive than protected. That is why there is compile time
error.

Encapsulation in Java
Encapsulation in java is a process of wrapping code and data together into a single unit,
for example capsule i.e. mixed of several medicines.

We can create a fully encapsulated class in java by making all the data members of the
class private. Now we can use setter and getter methods to set and get the data in it.
The Java Bean class is the example of fully encapsulated class.

Advantage of Encapsulation in java


By providing only setter or getter method, you can make the class read-only or writeonly.
It provides you the control over the data. Suppose you want to set the value of id i.e.
greater than 100 only, you can write the logic inside the setter method.

Simple example of encapsulation in java


Let's see the simple example of encapsulation that has only one field with its setter and
getter methods.
1.
2.
3.
4.
5.
6.

//save as Student.java
package com.javatpoint;
public class Student{
private String name;
public String getName(){

119
7. return name;
8. }
9. public void setName(String name){
10. this.name=name
11. }
12. }
1. //save as Test.java
2. package com.javatpoint;
3. class Test{
4. public static void main(String[] args){
5. Student s=new Student();
6. s.setname("vijay");
7. System.out.println(s.getName());
8. }
9. }
Compile By: javac -d . Test.java
Run By: java com.javatpoint.Test
Output: vijay

Object class in Java


The Object class is the parent class of all the classes in java bydefault. In other words, it is
the topmost class of java.
The Object class is beneficial if you want to refer any object whose type you don't know.
Notice that parent class reference variable can refer the child class object, know as
upcasting.
Let's take an example, there is getObject() method that returns an object but it can be of
any type like Employee,Student etc, we can use Object class reference to refer that object.
For example:
1. Object obj=getObject();//we don't what object would be returned from this method
The Object class provides some common behaviours to all the objects such as object can be
compared, object can be cloned, object can be notified etc.

120

Methods of Object class


The Object class provides many methods. They are as follows:

Method
public final ClassgetClass()

Description
returns the Class class object of this object. The
Class class can further be used to get the metadata
of this class.

public int hashCode()

returns the hashcode number for this object.

public boolean equals(Object obj)

compares the given object to this object.

protected Object clone() throws

creates and returns the exact copy (clone) of this

CloneNotSupportedException

object.

public String toString()

returns the string representation of this object.

public final void notify()

wakes up single thread, waiting on this object's


monitor.

121

wakes up all the threads, waiting on this object's

public final void notifyAll()

monitor.

public final void wait(long

causes the current thread to wait for the specified

timeout)throws InterruptedException

milliseconds, until another thread notifies (invokes


notify() or notifyAll() method).

public final void wait(long timeout,int

causes the current thread to wait for the specified

nanos)throws InterruptedException

miliseconds and nanoseconds, until another thread


notifies (invokes notify() or notifyAll() method).

public final void wait()throws

causes the current thread to wait, until another

InterruptedException

thread notifies (invokes notify() or notifyAll()


method).

protected void finalize()throws

is invoked by the garbage collector before object is

Throwable

being garbage collected.

We will have the detailed learning of these methods in next chapters.

Object Cloning in Java

The object cloning is a way to create exact copy


of an object. For this purpose, clone() method of Object class is used to clone an object.
The java.lang.Cloneable interface must be implemented by the class whose object clone
we want to create. If we don't implement Cloneable interface, clone() method
generatesCloneNotSupportedException.

122

The clone() method is defined in the Object class. Syntax of the clone() method is as
follows:
1. protected Object clone() throws CloneNotSupportedException

Why use clone() method ?


The clone() method saves the extra processing task for creating the exact copy of an
object. If we perform it by using the new keyword, it will take a lot of processing to be
performed that is why we use object cloning.

Advantage of Object cloning


Less processing task.

Example of clone() method (Object cloning)


Let's see the simple example of object cloning
1. class Student18 implements Cloneable{
2. int rollno;
3. String name;
4.
5. Student18(int rollno,String name){
6. this.rollno=rollno;
7. this.name=name;
8. }
9.
10. public Object clone()throws CloneNotSupportedException{
11. return super.clone();
12. }
13.
14. public static void main(String args[]){
15. try{
16. Student18 s1=new Student18(101,"amit");
17.
18. Student18 s2=(Student18)s1.clone();
19.
20. System.out.println(s1.rollno+" "+s1.name);
21. System.out.println(s2.rollno+" "+s2.name);
22.
23. }catch(CloneNotSupportedException c){}
24.
25. }
26. }
Test it Now

123

Output:101 amit
101 amit

download the example of object cloning


As you can see in the above example, both reference variables have the same value. Thus,
the clone() copies the values of an object to another. So we don't need to write explicit code
to copy the value of an object to another.
If we create another object by new keyword and assign the values of another object to this
one, it will require a lot of processing on this object. So to save the extra processing task
we use clone() method.

Java Array
Normally, array is a collection of similar type of elements that have contiguous memory
location.
Java array is an object the contains elements of similar data type. It is a data structure
where we store similar elements. We can store only fixed set of elements in a java array.
Array in java is index based, first element of the array is stored at 0 index.

Advantage of Java Array

Code Optimization: It makes the code optimized, we can retrieve or sort the data
easily.
Random access: We can get any data located at any index position.

Disadvantage of Java Array

Size Limit: We can store only fixed size of elements in the array. It doesn't grow its
size at runtime. To solve this problem, collection framework is used in java.

124

Types of Array in java


There are two types of array.

Single Dimensional Array


Multidimensional Array

Single Dimensional Array in java


Syntax to Declare an Array in java
1. dataType[] arr; (or)
2. dataType []arr; (or)
3. dataType arr[];

Instantiation of an Array in java


1. arrayRefVar=new datatype[size];

Example of single dimensional java array


Let's see the simple example of java array, where we are going to declare, instantiate,
initialize and traverse an array.
1. class Testarray{
2. public static void main(String args[]){
3.
4. int a[]=new int[5];//declaration and instantiation
5. a[0]=10;//initialization
6. a[1]=20;
7. a[2]=70;
8. a[3]=40;
9. a[4]=50;
10.
11. //printing array
12. for(int i=0;i<a.length;i++)//length is the property of array
13. System.out.println(a[i]);
14.
15. }}
Test it Now
Output: 10
20
70
40
50

125

Declaration, Instantiation and Initialization of Java Array


We can declare, instantiate and initialize the java array together by:
1. int a[]={33,3,4,5};//declaration, instantiation and initialization
Let's see the simple example to print this array.
1. class Testarray1{
2. public static void main(String args[]){
3.
4. int a[]={33,3,4,5};//declaration, instantiation and initialization
5.
6. //printing array
7. for(int i=0;i<a.length;i++)//length is the property of array
8. System.out.println(a[i]);
9.
10. }}
Test it Now
Output:33
3
4
5

Passing Array to method in java


We can pass the java array to method so that we can reuse the same logic on any array.
Let's see the simple example to get minimum number of an array using method.
1. class Testarray2{
2. static void min(int arr[]){
3. int min=arr[0];
4. for(int i=1;i<arr.length;i++)
5. if(min>arr[i])
6.
min=arr[i];
7.
8. System.out.println(min);
9. }
10.

126
11. public static void main(String args[]){
12.
13. int a[]={33,3,4,5};
14. min(a);//passing array to method
15.
16. }}
Test it Now
Output:3

Multidimensional array in java


In such case, data is stored in row and column based index (also known as matrix form).

Syntax to Declare Multidimensional Array in java


1.
2.
3.
4.

dataType[][] arrayRefVar; (or)


dataType [][]arrayRefVar; (or)
dataType arrayRefVar[][]; (or)
dataType []arrayRefVar[];

Example to instantiate Multidimensional Array in java


1. int[][] arr=new int[3][3];//3 row and 3 column

Example to initialize Multidimensional Array in java


1.
2.
3.
4.
5.
6.
7.
8.
9.

arr[0][0]=1;
arr[0][1]=2;
arr[0][2]=3;
arr[1][0]=4;
arr[1][1]=5;
arr[1][2]=6;
arr[2][0]=7;
arr[2][1]=8;
arr[2][2]=9;

Example of Multidimensional java array


Let's see the simple example to declare, instantiate, initialize and print the 2Dimensional
array.
1.
2.
3.
4.
5.
6.
7.
8.

class Testarray3{
public static void main(String args[]){
//declaring and initializing 2D array
int arr[][]={{1,2,3},{2,4,5},{4,4,5}};
//printing 2D array
for(int i=0;i<3;i++){

127
9. for(int j=0;j<3;j++){
10. System.out.print(arr[i][j]+" ");
11. }
12. System.out.println();
13. }
14.
15. }}
Test it Now
Output:1 2 3
2 4 5
4 4 5

What is class name of java array?


In java, array is an object. For array object, an proxy class is created whose name can be
obtained by getClass().getName() method on the object.
1. class Testarray4{
2. public static void main(String args[]){
3.
4. int arr[]={4,4,5};
5.
6. Class c=arr.getClass();
7. String name=c.getName();
8.
9. System.out.println(name);
10.
11. }}
Test it Now
Output:I

Copying a java array


We can copy an array to another by the arraycopy method of System class.

Syntax of arraycopy method


1. public static void arraycopy(
2. Object src, int srcPos,Object dest, int destPos, int length
3. )

Example of arraycopy method


1. class TestArrayCopyDemo {
2.
public static void main(String[] args) {

128
3.
4.
5.
6.
7.
8.
9.
}
10. }
Test

char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',


'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
System.out.println(new String(copyTo));
it Now

Output:caffein

Addition of 2 matrices in java


Let's see a simple example that adds two matrices.
1. class Testarray5{
2. public static void main(String args[]){
3. //creating two matrices
4. int a[][]={{1,3,4},{3,4,5}};
5. int b[][]={{1,3,4},{3,4,5}};
6.
7. //creating another matrix to store the sum of two matrices
8. int c[][]=new int[2][3];
9.
10. //adding and printing addition of 2 matrices
11. for(int i=0;i<2;i++){
12. for(int j=0;j<3;j++){
13. c[i][j]=a[i][j]+b[i][j];
14. System.out.print(c[i][j]+" ");
15. }
16. System.out.println();//new line
17. }
18.
19. }}
Test it Now
Output:2 6 8
6 8 10
next>><<prev

Call by Value and Call by Reference in Java


There is only call by value in java, not call by reference. If we call a method passing
a value, it is known as call by value. The changes being done in the called method, is

129

not affected in the calling method.

Example of call by value in java


In case of call by value original value is not changed. Let's take a simple example:
1. class Operation{
2. int data=50;
3.
4. void change(int data){
5. data=data+100;//changes will be in the local variable only
6. }
7.
8. public static void main(String args[]){
9.
Operation op=new Operation();
10.
11. System.out.println("before change "+op.data);
12. op.change(500);
13. System.out.println("after change "+op.data);
14.
15. }
16. }

download this example


Output:before change 50
after change 50

Another Example of call by value in java


In case of call by reference original value is changed if we made changes in the called
method. If we pass object in place of any primitive value, original value will be changed.
In this example we are passing object as a value. Let's take a simple example:
1. class Operation2{
2. int data=50;
3.
4. void change(Operation2 op){
5. op.data=op.data+100;//changes will be in the instance variable
6. }
7.
8.
9. public static void main(String args[]){
10. Operation2 op=new Operation2();
11.
12. System.out.println("before change "+op.data);

130
13. op.change(op);//passing object
14. System.out.println("after change "+op.data);
15.
16. }
17. }

download this example


Output:before change 50
after change 150

strictfp keyword
The strictfp keyword ensures that you will get the same result on every platform if you
perform operations in the floating-point variable. The precision may differ from platform
to platform that is why java programming language have provided the strictfp keyword,
so that you get same result on every platform. So, now you have better control over the
floating-point arithmetic.

Legal code for strictfp keyword


The strictfp keyword can be applied on methods, classes and interfaces.
1.
1.
1.
2.
3.

strictfp class A{}//strictfp applied on class


strictfp interface M{}//strictfp applied on interface
class A{
void m(){}//strictfp applied on method
}

Illegal code for strictfp keyword


The strictfp keyword can be applied on abstract methods, variables or constructors.
1.
2.
3.
1.
2.
3.
1.
2.
3.

class B{
strictfp abstract void m();//Illegal combination of modifiers
}
class B{
strictfp int data=10;//modifier strictfp not allowed here
}
class B{
strictfp B(){}//modifier strictfp not allowed here
}

Creating API Document | javadoc tool

131

We can create document api in java by the help of javadoc tool. In the java file, we must
use the documentation comment /**... */ to post information for the class, method,
constructor, fields etc.
Let's see the simple class that contains documentation comment.
1.
2.
3.
4.
5.
6.
7.

package com.abc;
/** This class is a user-defined class that contains one methods cube.*/
public class M{
/** The cube method prints cube of the given number */
public static void cube(int n){System.out.println(n*n*n);}
}
To create the document API, you need to use the javadoc tool followed by java file name.
There is no need to compile the javafile.
On the command prompt, you need to write:
javadoc M.java
to generate the document api. Now, there will be created a lot of html files. Open the
index.html file to get the information about the classes.

Java Command Line Arguments


1. Command Line Argument
2. Simple example of command-line argument
3. Example of command-line argument that prints all the values
The java command-line argument is an argument i.e. passed at the time of running the java
program.
The arguments passed from the console can be received in the java program and it can be
used as an input.
So, it provides a convenient way to check the behavior of the program for the different
values. You can pass N (1,2,3 and so on) numbers of arguments from the command
prompt.

132

Simple example of command-line argument in java


In this example, we are receiving only one argument and printing it. To run this java
program, you must pass at least one argument from the command prompt.
1.
2.
3.
4.
5.
1.
2.

class CommandLineExample{
public static void main(String args[]){
System.out.println("Your first argument is: "+args[0]);
}
}
compile by > javac CommandLineExample.java
run by > java CommandLineExample sonoo
Output: Your first argument is: sonoo

Example of command-line argument that prints all the values


In this example, we are printing all the arguments passed from the command-line. For
this purpose, we have traversed the array using for loop.
1.
2.
3.
4.
5.
6.
7.
8.
1.
2.

class A{
public static void main(String args[]){
for(int i=0;i<args.length;i++)
System.out.println(args[i]);
}
}
compile by > javac A.java
run by > java A sonoo jaiswal 1 3 abc
Output: sonoo
jaiswal
1
3
abc

Java String
1. Java String Handling
2. How to create string object
1. String literal
2. new keyword

133

Java String provides a lot of concepts that can be performed on a string such as compare,
concat, equals, split, length, replace, compareTo, intern, substring etc.
In java, string is basically an object that represents sequence of char values.
An array of characters works same as java string. For example:
1. char[] ch={'j','a','v','a','t','p','o','i','n','t'};
2. String s=new String(ch);
is same as:
1. String s="javatpoint";
The java.lang.String class
implements Serializable, Comparable and CharSequence interfaces.
The java String is immutable i.e. it cannot be changed but a new instance is created. For
mutable class, you can use StringBuffer and StringBuilder class.
We will discuss about immutable string later. Let's first understand what is string in java
and how to create the string object.

What is String in java


Generally, string is a sequence of characters. But in java, string is an object that represents
a sequence of characters. String class is used to create string object.

How to create String object?


There are two ways to create String object:
1. By string literal
2. By new keyword

1) String Literal
Java String literal is created by using double quotes. For Example:

134
1. String s="welcome";
Each time you create a string literal, the JVM checks the string constant pool first. If the
string already exists in the pool, a reference to the pooled instance is returned. If string
doesn't exist in the pool, a new string instance is created and placed in the pool. For
example:
1. String s1="Welcome";
2. String s2="Welcome";//will not create new instance

In the above example only one object will be created. Firstly JVM will not find any string
object with the value "Welcome" in string constant pool, so it will create a new object. After
that it will find the string with the value "Welcome" in the pool, it will not create new object
but will return the reference to the same instance.

135

Note: String objects are stored in a special memory area known as string constant
pool.

Why java uses concept of string literal?


To make Java more memory efficient (because no new objects are created if it exists
already in string constant pool).

2) By new keyword
1. String s=new String("Welcome");//creates two objects and one reference variable
In such case, JVM will create a new string object in normal(non pool) heap memory and the
literal "Welcome" will be placed in the string constant pool. The variable s will refer to the
object in heap(non pool).

Java String Example


1. public class StringExample{
2. public static void main(String args[]){
3. String s1="java";//creating string by java string literal
4.
5. char ch[]={'s','t','r','i','n','g','s'};
6. String s2=new String(ch);//converting char array to string
7.
8. String s3=new String("example");//creating java string by new keyword
9.
10. System.out.println(s1);
11. System.out.println(s2);
12. System.out.println(s3);
13. }}
Test it Now
java
strings
example

136

Java String class methods


The java.lang.String class provides many useful methods to perform operations on
sequence of char values.

No.
1

Method
char charAt(int index)

Description
returns char value for the particular
index

int length()

returns string length

static String format(String format, Object... args)

returns formatted string

static String format(Locale l, String format, Object...

returns formatted string with given

args)

locale

String substring(int beginIndex)

returns substring for given begin

index

String substring(int beginIndex, int endIndex)

returns substring for given begin


index and end index

boolean contains(CharSequence s)

returns true or false after matching


the sequence of char value

static String join(CharSequence delimiter,

returns a joined string

CharSequence... elements)

static String join(CharSequence delimiter, Iterable<?

returns a joined string

extends CharSequence> elements)

10

boolean equals(Object another)

checks the equality of string with


object

137

11

boolean isEmpty()

checks if string is empty

12

String concat(String str)

concatinates specified string

13

String replace(char old, char new)

replaces all occurrences of specified


char value

14

15

String replace(CharSequence old, CharSequence

replaces all occurrences of specified

new)

CharSequence

String trim()

returns trimmed string omitting


leading and trailing spaces

16

String split(String regex)

returns splitted string matching


regex

17

String split(String regex, int limit)

returns splitted string matching


regex and limit

18

String intern()

returns interned string

19

int indexOf(int ch)

returns specified char value index

20

int indexOf(int ch, int fromIndex)

returns specified char value index


starting with given index

21

int indexOf(String substring)

returns specified substring index

22

int indexOf(String substring, int fromIndex)

returns specified substring index


starting with given index

Do You Know ?

Why String objects are immutable?

138

How to create an immutable class?


What is string constant pool?
What code is written by the compiler if you concat any string by + (string
concatenation operator)?
What is the difference between StringBuffer and StringBuilder class?

What we will learn in String Handling ?

Concept of String
Immutable String
String Comparison
String Concatenation
Concept of Substring
String class methods and its usage
StringBuffer class
StringBuilder class
Creating Immutable class
toString() method
StringTokenizer class

Immutable String in Java


In java, string objects are immutable. Immutable simply means unmodifiable or
unchangeable.
Once string object is created its data or state can't be changed but a new string object is
created.
Let's try to understand the immutability concept by the example given below:
1. class Testimmutablestring{
2. public static void main(String args[]){
3.
String s="Sachin";
4.
s.concat(" Tendulkar");//concat() method appends the string at the end
5.
System.out.println(s);//will print Sachin because strings are immutable objects
6. }
7. }
Test it Now
Output:Sachin
Now it can be understood by the diagram given below. Here Sachin is not changed but a
new object is created with sachintendulkar. That is why string is known as immutable.

139

As you can see in the above figure that two objects are created but s reference variable still
refers to "Sachin" not to "Sachin Tendulkar".
But if we explicitely assign it to the reference variable, it will refer to "Sachin Tendulkar"
object.For example:
1. class Testimmutablestring1{
2. public static void main(String args[]){
3.
String s="Sachin";
4.
s=s.concat(" Tendulkar");
5.
System.out.println(s);
6. }
7. }
Test it Now
Output:Sachin Tendulkar

140

In such case, s points to the "Sachin Tendulkar". Please notice that still sachin object is not
modified.

Why string objects are immutable in java?


Because java uses the concept of string literal.Suppose there are 5 reference variables,all
referes to one object "sachin".If one reference variable changes the value of the object,
it will be affected to all the reference variables. That is why string objects are immutable
in java.

String comparison in Java

We can compare two given strings on the basis of content and reference.
It is used in authentication (by equals() method), sorting (by compareTo()
method), reference matching (by == operator) etc.
There are three ways to compare String objects:
1. By equals() method
2. By = = operator
3. By compareTo() method

1) By equals() method
equals() method compares the original content of the string.It compares values of string

141

for equality.String class provides two methods:

public boolean equals(Object another){} compares this string to the specified


object.
public boolean equalsIgnoreCase(String another){} compares this String to
another String, ignoring case.

1. class Teststringcomparison1{
2. public static void main(String args[]){
3.
4.
String s1="Sachin";
5.
String s2="Sachin";
6.
String s3=new String("Sachin");
7.
String s4="Saurav";
8.
9.
System.out.println(s1.equals(s2));//true
10. System.out.println(s1.equals(s3));//true
11. System.out.println(s1.equals(s4));//false
12. }
13. }
Test it Now
Output:true
true
false
1. //Example of equalsIgnoreCase(String) method
2. class Teststringcomparison2{
3. public static void main(String args[]){
4.
5.
String s1="Sachin";
6.
String s2="SACHIN";
7.
8.
System.out.println(s1.equals(s2));//false
9.
System.out.println(s1.equalsIgnoreCase(s3));//true
10. }
11. }
Test it Now
Output:false
true

2) By == operator
The = = operator compares references not values.
1. //<b><i>Example of == operator</i></b>
2.
3. class Teststringcomparison3{
4. public static void main(String args[]){

142
5.
6.
String s1="Sachin";
7.
String s2="Sachin";
8.
String s3=new String("Sachin");
9.
10. System.out.println(s1==s2);//true (because both refer to same instance)
11. System.out.println(s1==s3);//false(because s3 refers to instance created in nonpool)
12. }
13. }
Test it Now
Output:true
false

3) By compareTo() method:
compareTo() method compares values and returns an int which tells if the values
compare less than, equal, or greater than.
Suppose s1 and s2 are two string variables.If:

s1 == s2 :0
s1 > s2 :positive value
s1 < s2 :negative value

1. //<b><i>Example of compareTo() method:</i></b>


2.
3. class Teststringcomparison4{
4. public static void main(String args[]){
5.
6.
String s1="Sachin";
7.
String s2="Sachin";
8.
String s3="Ratan";
9.
10. System.out.println(s1.compareTo(s2));//0
11. System.out.println(s1.compareTo(s3));//1(because s1>s3)
12. System.out.println(s3.compareTo(s1));//-1(because s3 < s1 )
13. }
14. }
Test it Now
Output:0
1
-1

String Concatenation in Java

143

Concating strings form a new string i.e. the combination of multiple strings.
There are two ways to concat string objects:
1. By + (string concatenation) operator
2. By concat() method

1) By + (string concatenation) operator


String concatenation operator is used to add strings.For Example:
1. //Example of string concatenation operator
2.
3. class TestStringConcatenation1{
4. public static void main(String args[]){
5.
6.
String s="Sachin"+" Tendulkar";
7.
System.out.println(s);//Sachin Tendulkar
8. }
9. }
Test it Now
Output:Sachin Tendulkar
The compiler transforms this to:
1. String s=(new StringBuilder()).append("Sachin").append(" Tendulkar).toString();
String concatenation is implemented through the StringBuilder(or StringBuffer) class and
its append method.String concatenation operator produces a new string by appending
the second operand onto the end of the first operand.The string concatenation operator
can concat not only string but primitive values also.For Example:
1. class TestStringConcatenation2{
2. public static void main(String args[]){
3.
4.
String s=50+30+"Sachin"+40+40;
5.
System.out.println(s);//80Sachin4040
6. }
7. }
Test it Now
Output:80Sachin4040
Note:If either operand is a string, the resulting operation will be string concatenation. If
both operands are numbers, the operator will perform an addition.

144

2) By concat() method
concat() method concatenates the specified string to the end of current string.
Syntax:public String concat(String another){}
1. //<b><i>Example of concat(String) method</i></b>
2.
3. class TestStringConcatenation3{
4. public static void main(String args[]){
5.
6.
String s1="Sachin ";
7.
String s2="Tendulkar";
8.
9.
String s3=s1.concat(s2);
10.
11. System.out.println(s3);//Sachin Tendulkar
12. }
13. }
Test it Now
Output:Sachin Tendulkar

Substring in Java

A part of string is called substring. In other words, substring is a subset of another string.
In case of substring startIndex starts from 0 and endIndex starts from 1 or startIndex is
inclusive and endIndex is exclusive.

145

You can get substring from the given String object by one of the two methods:
1. public String substring(int startIndex): This method returns new String object
containing the substring of the given string from specified startIndex (inclusive).
2. public String substring(int startIndex,int endIndex): This method returns new
String object containing the substring of the given string from specified startIndex to
endIndex.

In case of string:

startIndex:starts from index 0(inclusive).


endIndex:starts from index 1(exclusive).

Example of java substring


1. //Example of substring() method
2.
3. public class TestSubstring{
4. public static void main(String args[]){
5.
6.
String s="Sachin Tendulkar";
7.
System.out.println(s.substring(6));//Tendulkar
8.
System.out.println(s.substring(0,6));//Sachin
9. }
10. }
Test it Now
Output:Tendulkar
Sachin

Java String class methods


The java.lang.String class provides a lot of methods to work on string. By the help of these
methods, we can perform operations on string such as trimming, concatenating, converting,
comparing, replacing strings etc.
Java String is a powerful concept because everything is treated as a string if you submit any
form in window based, web based or mobile application.
Let's see the important methods of String class.

146

Java String toUpperCase() and toLowerCase() method


The java string toUpperCase() method converts this string into uppercase letter and string
toLowerCase() method into lowercase letter.
1.
2.
3.
4.

String s="Sachin";
System.out.println(s.toUpperCase());//SACHIN
System.out.println(s.toLowerCase());//sachin
System.out.println(s);//Sachin(no change in original)
Test it Now
SACHIN
sachin
Sachin

Java String trim() method


The string trim() method eliminates white spaces before and after string.
1. String s=" Sachin ";
2. System.out.println(s);// Sachin
3. System.out.println(s.trim());//Sachin
Test it Now
Sachin
Sachin

Java String startsWith() and endsWith() method


1. String s="Sachin";
2. System.out.println(s.startsWith("Sa"));//true
3. System.out.println(s.endsWith("n"));//true
Test it Now
true
true

Java String charAt() method


The string charAt() method returns a character at specified index.
1. String s="Sachin";
2. System.out.println(s.charAt(0));//S

147
3. System.out.println(s.charAt(3));//h
Test it Now
S
h

Java String length() method


The string length() method returns length of the string.
1. String s="Sachin";
2. System.out.println(s.length());//6
Test it Now
6

Java String intern() method


A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String
object as determined by the equals(Object) method, then the string from the pool is
returned. Otherwise, this String object is added to the pool and a reference to this String
object is returned.
1. String s=new String("Sachin");
2. String s2=s.intern();
3. System.out.println(s2);//Sachin
Test it Now
Sachin

Java String valueOf() method


The string valueOf() method coverts given type such as int, long, float, double, boolean,
char and char array into string.
1. int a=10;
2. String s=String.valueOf(a);
3. System.out.println(s+10);
1010

148

StringBuffer class:
The StringBuffer class is used to created mutable (modifiable) string. The StringBuffer
class is same as String except it is mutable i.e. it can be changed.

Note: StringBuffer class is thread-safe i.e. multiple threads cannot


access it simultaneously .So it is safe and will result in an order.

Commonly used Constructors of StringBuffer class:


1. StringBuffer(): creates an empty string buffer with the initial capacity of 16.
2. StringBuffer(String str): creates a string buffer with the specified string.
3. StringBuffer(int capacity): creates an empty string buffer with the specified
capacity as length.

Commonly used methods of StringBuffer class:


1. public synchronized StringBuffer append(String s): is used to append the
specified string with this string. The append() method is overloaded like
append(char), append(boolean), append(int), append(float), append(double) etc.
2. public synchronized StringBuffer insert(int offset, String s): is used to
insert the specified string with this string at the specified position. The insert()
method is overloaded like insert(int, char), insert(int, boolean), insert(int, int),
insert(int, float), insert(int, double) etc.
3. public synchronized StringBuffer replace(int startIndex, int endIndex,
String str): is used to replace the string from specified startIndex and endIndex.
4. public synchronized StringBuffer delete(int startIndex, int endIndex): is
used to delete the string from specified startIndex and endIndex.
5. public synchronized StringBuffer reverse(): is used to reverse the string.
6. public int capacity(): is used to return the current capacity.
7. public void ensureCapacity(int minimumCapacity): is used to ensure the
capacity at least equal to the given minimum.
8. public char charAt(int index): is used to return the character at the specified
position.
9. public int length(): is used to return the length of the string i.e. total number of
characters.
10. public String substring(int beginIndex): is used to return the substring from
the specified beginIndex.
11. public String substring(int beginIndex, int endIndex): is used to return the

149
substring from the specified beginIndex and endIndex.

What is mutable string?


A string that can be modified or changed is known as mutable string. StringBuffer and
StringBuilder classes are used for creating mutable string.

simple example of StringBuffer class by append() method


The append() method concatenates the given argument with this string.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello ");
sb.append("Java");//now original string is changed
System.out.println(sb);//prints Hello Java
}
}

Example of insert() method of StringBuffer class


The insert() method inserts the given string with this string at the given position.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello ");
sb.insert(1,"Java");//now original string is changed
System.out.println(sb);//prints HJavaello
}
}

Example of replace() method of StringBuffer class


The replace() method replaces the given string from the specified beginIndex and
endIndex.
1.
2.
3.
4.
5.
6.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.replace(1,3,"Java");

150
7. System.out.println(sb);//prints HJavalo
8. }
9. }

Example of delete() method of StringBuffer class


The delete() method of StringBuffer class deletes the string from the specified
beginIndex to endIndex.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.delete(1,3);
System.out.println(sb);//prints Hlo
}
}

Example of reverse() method of StringBuffer class


The reverse() method of StringBuilder class reverses the current string.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.reverse();
System.out.println(sb);//prints olleH
}
}

Example of capacity() method of StringBuffer class


The capacity() method of StringBuffer class returns the current capacity of the buffer.
The default capacity of the buffer is 16. If the number of character increases from its
current capacity, it increases the capacity by (oldcapacity*2)+2. For example if your
current capacity is 16, it will be (16*2)+2=34.
1.
2.
3.
4.
5.
6.
7.

class A{
public static void main(String args[]){
StringBuffer sb=new StringBuffer();
System.out.println(sb.capacity());//default 16
sb.append("Hello");

151
8. System.out.println(sb.capacity());//now 16
9.
10. sb.append("java is my favourite language");
11. System.out.println(sb.capacity());//now (16*2)+2=34 i.e (oldcapacity*2)+2
12. }
13. }

Example of ensureCapacity() method of StringBuffer class


The ensureCapacity() method of StringBuffer class ensures that the given capacity is the
minimum to the current capacity. If it is greater than the current capacity, it increases
the capacity by (oldcapacity*2)+2. For example if your current capacity is 16, it will be
(16*2)+2=34.
1. class A{
2. public static void main(String args[]){
3.
4. StringBuffer sb=new StringBuffer();
5. System.out.println(sb.capacity());//default 16
6.
7. sb.append("Hello");
8. System.out.println(sb.capacity());//now 16
9.
10. sb.append("java is my favourite language");
11. System.out.println(sb.capacity());//now (16*2)+2=34 i.e (oldcapacity*2)+2
12.
13. sb.ensureCapacity(10);//now no change
14. System.out.println(sb.capacity());//now 34
15.
16. sb.ensureCapacity(50);//now (34*2)+2
17. System.out.println(sb.capacity());//now 70
18.
19. }
20. }

StringBuilder class:
The StringBuilder class is used to create mutable (modifiable) string. The StringBuilder
class is same as StringBuffer class except that it is non-synchronized. It is available since
JDK1.5.

Commonly used Constructors of StringBuilder class:


1. StringBuilder(): creates an empty string Builder with the initial capacity of 16.
2. StringBuilder(String str): creates a string Builder with the specified string.
3. StringBuilder(int length): creates an empty string Builder with the specified

152
capacity as length.

Commonly used methods of StringBuilder class:


1. public StringBuilder append(String s): is used to append the specified string
with this string. The append() method is overloaded like append(char),
append(boolean), append(int), append(float), append(double) etc.
2. public StringBuilder insert(int offset, String s): is used to insert the specified
string with this string at the specified position. The insert() method is overloaded
like insert(int, char), insert(int, boolean), insert(int, int), insert(int, float),
insert(int, double) etc.
3. public StringBuilder replace(int startIndex, int endIndex, String str): is
used to replace the string from specified startIndex and endIndex.
4. public StringBuilder delete(int startIndex, int endIndex): is used to delete
the string from specified startIndex and endIndex.
5. public StringBuilder reverse(): is used to reverse the string.
6. public int capacity(): is used to return the current capacity.
7. public void ensureCapacity(int minimumCapacity): is used to ensure the
capacity at least equal to the given minimum.
8. public char charAt(int index): is used to return the character at the specified
position.
9. public int length(): is used to return the length of the string i.e. total number of
characters.
10. public String substring(int beginIndex): is used to return the substring from
the specified beginIndex.
11. public String substring(int beginIndex, int endIndex): is used to return the
substring from the specified beginIndex and endIndex.

simple program of StringBuilder class by append() method


The append() method concatenates the given argument with this string.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello ");
sb.append("Java");//now original string is changed
System.out.println(sb);//prints Hello Java
}
}

153

Example of insert() method of StringBuilder class


The insert() method inserts the given string with this string at the given position.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello ");
sb.insert(1,"Java");//now original string is changed
System.out.println(sb);//prints HJavaello
}
}

Example of replace() method of StringBuilder class


The replace() method replaces the given string from the specified beginIndex and
endIndex.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.replace(1,3,"Java");
System.out.println(sb);//prints HJavalo
}
}

Example of delete() method of StringBuilder class


The delete() method of StringBuilder class deletes the string from the specified
beginIndex to endIndex.
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.delete(1,3);
System.out.println(sb);//prints Hlo
}
}

Example of reverse() method of StringBuilder class


The reverse() method of StringBuilder class reverses the current string.

154
1.
2.
3.
4.
5.
6.
7.
8.
9.

class A{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.reverse();
System.out.println(sb);//prints olleH
}
}

Example of capacity() method of StringBuilder class


The capacity() method of StringBuilder class returns the current capacity of the Builder.
The default capacity of the Builder is 16. If the number of character increases from its
current capacity, it increases the capacity by (oldcapacity*2)+2. For example if your
current capacity is 16, it will be (16*2)+2=34.
1. class A{
2. public static void main(String args[]){
3.
4. StringBuilder sb=new StringBuilder();
5. System.out.println(sb.capacity());//default 16
6.
7. sb.append("Hello");
8. System.out.println(sb.capacity());//now 16
9.
10. sb.append("java is my favourite language");
11. System.out.println(sb.capacity());//now (16*2)+2=34 i.e (oldcapacity*2)+2
12. }
13. }

Example of ensureCapacity() method of StringBuilder class


The ensureCapacity() method of StringBuilder class ensures that the given capacity is the
minimum to the current capacity. If it is greater than the current capacity, it increases
the capacity by (oldcapacity*2)+2. For example if your current capacity is 16, it will be
(16*2)+2=34.
1. class A{
2. public static void main(String args[]){
3.
4. StringBuilder sb=new StringBuilder();
5. System.out.println(sb.capacity());//default 16
6.
7. sb.append("Hello");
8. System.out.println(sb.capacity());//now 16
9.
10. sb.append("java is my favourite language");

155
11. System.out.println(sb.capacity());//now (16*2)+2=34 i.e (oldcapacity*2)+2
12.
13. sb.ensureCapacity(10);//now no change
14. System.out.println(sb.capacity());//now 34
15.
16. sb.ensureCapacity(50);//now (34*2)+2
17. System.out.println(sb.capacity());//now 70
18.
19. }
20. }

How to create Immutable class?


There are many immutable classes like String, Boolean, Byte, Short, Integer, Long, Float,
Double etc. In short, all the wrapper classes and String class is immutable. We can also
create immutable class by creating final class that have final data members as the
example given below:

Example to create Immutable class


In this example, we have created a final class named Employee. It have one final
datamember, a parameterized constructor and getter method.
1. public final class Employee{
2. final String pancardNumber;
3.
4. public Employee(String pancardNumber){
5. this.pancardNumber=pancardNumber;
6. }
7.
8. public String getPancardNumber(){
9. return pancardNumber;
10. }
11.
12. }

The above class is immutable because:

The instance variable of the class is final i.e. we cannot change the value of it
after creating an object.
The class is final so we cannot create the subclass.
There is no setter methods i.e. we have no option to change the value of the
instance variable.

These points makes this class as immutable.

156

Understanding toString() method


If you want to represent any object as a string, toString() method comes into existence.
The toString() method returns the string representation of the object.
If you print any object, java compiler internally invokes the toString() method on the object.
So overriding the toString() method, returns the desired output, it can be the state of an
object etc. depends on your implementation.

Advantage of the toString() method


By overriding the toString() method of the Object class, we can return values of the
object, so we don't need to write much code.

Understanding problem without toString() method


Let's see the simple code that prints reference.
1. class Student{
2. int rollno;
3. String name;
4. String city;
5.
6. Student(int rollno, String name, String city){
7. this.rollno=rollno;
8. this.name=name;
9. this.city=city;
10. }
11.
12. public static void main(String args[]){
13. Student s1=new Student(101,"Raj","lucknow");
14. Student s2=new Student(102,"Vijay","ghaziabad");
15.
16. System.out.println(s1);//compiler writes here s1.toString()
17. System.out.println(s2);//compiler writes here s2.toString()
18. }
19. }
Output:Student@1fee6fc
Student@1eed786
As you can see in the above example, printing s1 and s2 prints the hashcode values of
the objects but I want to print the values of these objects. Since java compiler internally

157

calls toString() method, overriding this method will return the specified values. Let's
understand it with the example given below:

Example of toString() method


Now let's see the real example of toString() method.
1. class Student{
2. int rollno;
3. String name;
4. String city;
5.
6. Student(int rollno, String name, String city){
7. this.rollno=rollno;
8. this.name=name;
9. this.city=city;
10. }
11.
12. public String toString(){//overriding the toString() method
13. return rollno+" "+name+" "+city;
14. }
15. public static void main(String args[]){
16. Student s1=new Student(101,"Raj","lucknow");
17. Student s2=new Student(102,"Vijay","ghaziabad");
18.
19. System.out.println(s1);//compiler writes here s1.toString()
20. System.out.println(s2);//compiler writes here s2.toString()
21. }
22. }

download this example of toString method


Output:101 Raj lucknow
102 Vijay ghaziabad

StringTokenizer in Java
1. StringTokenizer
2. Methods of StringTokenizer
3. Example of StringTokenizer
The java.util.StringTokenizer class allows you to break a string into tokens. It is simple
way to break string.

158

It doesn't provide the facility to differentiate numbers, quoted strings, identifiers etc. like
StreamTokenizer class. We will discuss about the StreamTokenizer class in I/O chapter.

Constructors of StringTokenizer class


There are 3 constructors defined in the StringTokenizer class.

Constructor

Description

StringTokenizer(String str)

creates StringTokenizer with specified string.

StringTokenizer(String str,

creates StringTokenizer with specified string and delimeter.

String delim)

StringTokenizer(String str,

creates StringTokenizer with specified string, delimeter and

String delim, boolean

returnValue. If return value is true, delimiter characters are

returnValue)

considered to be tokens. If it is false, delimiter characters serve


to separate tokens.

Methods of StringTokenizer class


The 6 useful methods of StringTokenizer class are as follows:

Public method

Description

boolean hasMoreTokens()

checks if there is more tokens available.

String nextToken()

returns the next token from the StringTokenizer object.

String nextToken(String delim)

returns the next token based on the delimeter.

boolean hasMoreElements()

same as hasMoreTokens() method.

159

Object nextElement()

same as nextToken() but its return type is Object.

int countTokens()

returns the total number of tokens.

Simple example of StringTokenizer class


Let's see the simple example of StringTokenizer class that tokenizes a string "my name is
khan" on the basis of whitespace.
1. import java.util.StringTokenizer;
2. public class Simple{
3. public static void main(String args[]){
4.
StringTokenizer st = new StringTokenizer("my name is khan"," ");
5.
while (st.hasMoreTokens()) {
6.
System.out.println(st.nextToken());
7.
}
8.
}
9. }
Output:my
name
is
khan

Example of nextToken(String delim) method of StringTokenizer


class
1. import java.util.*;
2.
3. public class Test {
4.
public static void main(String[] args) {
5.
StringTokenizer st = new StringTokenizer("my,name,is,khan");
6.
7.
// printing next token
8.
System.out.println("Next token is : " + st.nextToken(","));
9.
}
10. }
Output:Next token is : my

StringTokenizer class is deprecated now. It is recommended to use split() method


of String class or regex (Regular Expression).

160

Java Regex
The Java Regex or Regular Expression is an API to define pattern for searching or
manipulating strings.
It is widely used to define constraint on strings such as password and email validation. After
learning java regex tutorial, you will be able to test your own regular expressions by the
Java Regex Tester Tool.
Java Regex API provides 1 interface and 3 classes in java.util.regex package.

java.util.regex package
It provides following classes and interface for regular expressions. The Matcher and Pattern
classes are widely used in java regular expression.
1.
2.
3.
4.

MatchResult interface
Matcher class
Pattern class
PatternSyntaxException class

Matcher class
It implements MatchResult interface. It is a regex engine i.e. used to perform match
operations on a character sequence.

No.

Method

Description

boolean matches()

test whether the regular expression matches the pattern.

boolean find()

finds the next expression that matches the pattern.

boolean find(int

finds the next expression that matches the pattern from the given

start)

start number.

161

Pattern class
It is the compiled version of a regular expression. It is used to define a pattern for the regex
engine.

No.
1

Method

Description

static Pattern compile(String

compiles the given regex and return the instance of

regex)

pattern.

Matcher matcher(CharSequence

creates a matcher that matches the given input with

input)

pattern.

static boolean matches(String

It works as the combination of compile and matcher

regex, CharSequence input)

methods. It compiles the regular expression and


matches the given input with the pattern.

String[] split(CharSequence input)

splits the given input string around matches of given


pattern.

String pattern()

returns the regex pattern.

Example of Java Regular Expressions


There are three ways to write the regex example in java.
1. import java.util.regex.*;
2. public class RegexExample1{
3. public static void main(String args[]){
4. //1st way
5. Pattern p = Pattern.compile(".s");//. represents single character
6. Matcher m = p.matcher("as");
7. boolean b = m.matches();
8.
9. //2nd way
10. boolean b2=Pattern.compile(".s").matcher("as").matches();
11.
12. //3rd way

162
13. boolean b3 = Pattern.matches(".s", "as");
14.
15. System.out.println(b+" "+b2+" "+b3);
16. }}
Test it Now

Output
true true true

Regular Expression . Example


The . (dot) represents a single character.
1.
2.
3.
4.
5.
6.
7.
8.
9.

import java.util.regex.*;
class RegexExample2{
public static void main(String args[]){
System.out.println(Pattern.matches(".s", "as"));//true (2nd char is s)
System.out.println(Pattern.matches(".s", "mk"));//false (2nd char is not s)
System.out.println(Pattern.matches(".s", "mst"));//false (has more than 2 char)
System.out.println(Pattern.matches(".s", "amms"));//false (has more than 2 char)
System.out.println(Pattern.matches("..s", "mas"));//true (3rd char is s)
}}
Test it Now

Regex Character classes


No.

Character Class

Description

[abc]

a, b, or c (simple class)

[^abc]

Any character except a, b, or c (negation)

[a-zA-Z]

a through z or A through Z, inclusive (range)

[a-d[m-p]]

a through d, or m through p: [a-dm-p] (union)

[a-z&&[def]]

d, e, or f (intersection)

163

[a-z&&[^bc]]

a through z, except for b and c: [ad-z] (subtraction)

[a-z&&[^m-p]]

a through z, and not m through p: [a-lq-z](subtraction)

Regular Expression Character classes Example


1.
2.
3.
4.
5.
6.

import java.util.regex.*;
class RegexExample3{
public static void main(String args[]){
System.out.println(Pattern.matches("[amn]", "abcd"));//false (not a or m or n)
System.out.println(Pattern.matches("[amn]", "a"));//true (among a or m or n)
System.out.println(Pattern.matches("[amn]", "ammmna"));//false (m and a comes more th
an once)
7. }}
Test it Now

Regex Quantifiers
The quantifiers specify the number of occurrences of a character.

Regex

Description

X?

X occurs once or not at all

X+

X occurs once or more times

X*

X occurs zero or more times

X{n}

X occurs n times only

X{n,}

X occurs n or more times

X{y,z}

X occurs at least y times but less than z times

164

Regular Expression Character classes and Quantifiers


Example
1.
2.
3.
4.
5.
6.

import java.util.regex.*;
class RegexExample4{
public static void main(String args[]){
System.out.println("? quantifier ....");
System.out.println(Pattern.matches("[amn]?", "a"));//true (a or m or n comes one time)
System.out.println(Pattern.matches("[amn]?", "aaa"));//false (a comes more than one time
)
7. System.out.println(Pattern.matches("[amn]?", "aammmnn"));//false (a m and n comes mor
e than one time)
8. System.out.println(Pattern.matches("[amn]?", "aazzta"));//false (a comes more than one ti
me)
9. System.out.println(Pattern.matches("[amn]?", "am"));//false (a or m or n must come one ti
me)
10.
11. System.out.println("+ quantifier ....");
12. System.out.println(Pattern.matches("[amn]+", "a"));//true (a or m or n once or more times
)
13. System.out.println(Pattern.matches("[amn]+", "aaa"));//true (a comes more than one time
)
14. System.out.println(Pattern.matches("[amn]+", "aammmnn"));//true (a or m or n comes mo
re than once)
15. System.out.println(Pattern.matches("[amn]+", "aazzta"));//false (z and t are not matching
pattern)
16.
17. System.out.println("* quantifier ....");
18. System.out.println(Pattern.matches("[amn]*", "ammmna"));//true (a or m or n may come
zero or more times)
19.
20. }}
Test it Now

Regex Metacharacters
The regular expression metacharacters work as a short codes.

Regex

Description

Any character (may or may not match terminator)

\d

Any digits, short of [0-9]

165

\D

Any non-digit, short for [^0-9]

\s

Any whitespace character, short for [\t\n\x0B\f\r]

\S

Any non-whitespace character, short for [^\s]

\w

Any word character, short for [a-zA-Z_0-9]

\W

Any non-word character, short for [^\w]

\b

A word boundary

\B

A non word boundary

Regular Expression Metacharacters Example


1.
2.
3.
4.
5.
6.
7.
8.

import java.util.regex.*;
class RegexExample5{
public static void main(String args[]){
System.out.println("metacharacters d....");\\d means digit

System.out.println(Pattern.matches("\\d", "abc"));//false (non-digit)


System.out.println(Pattern.matches("\\d", "1"));//true (digit and comes once)
System.out.println(Pattern.matches("\\d", "4443"));//false (digit but comes more than once
)
9. System.out.println(Pattern.matches("\\d", "323abc"));//false (digit and char)
10.
11. System.out.println("metacharacters D....");\\D means non-digit
12.
13. System.out.println(Pattern.matches("\\D", "abc"));//false (nondigit but comes more than once)
14. System.out.println(Pattern.matches("\\D", "1"));//false (digit)
15. System.out.println(Pattern.matches("\\D", "4443"));//false (digit)
16. System.out.println(Pattern.matches("\\D", "323abc"));//false (digit and char)
17. System.out.println(Pattern.matches("\\D", "m"));//true (non-digit and comes once)
18.
19. System.out.println("metacharacters D with quantifier....");
20. System.out.println(Pattern.matches("\\D*", "mak"));//true (nondigit and may come 0 or more times)
21.
22. }}
Test it Now

166

Regular Expression Question 1


1.
2.
3.
4.
5.
6.
7.
8.

/*Create a regular expression that accepts alpha numeric characters only. Its
length must be 6 characters long only.*/

import java.util.regex.*;
class RegexExample6{
public static void main(String args[]){
System.out.println(Pattern.matches("[a-zA-Z0-9]{6}", "arun32"));//true
System.out.println(Pattern.matches("[a-zA-Z09]{6}", "kkvarun32"));//false (more than 6 char)
9. System.out.println(Pattern.matches("[a-zA-Z0-9]{6}", "JA2Uk2"));//true
10. System.out.println(Pattern.matches("[a-zA-Z09]{6}", "arun$2"));//false ($ is not matched)
11. }}

Test it Now

Regular Expression Question 2


1. /*Create a regular expression that accepts 10 digit numeric characters
2. starting with 7, 8 or 9 only.*/
3.
4. import java.util.regex.*;
5. class RegexExample7{
6. public static void main(String args[]){
7. System.out.println("by character classes and quantifiers ...");
8. System.out.println(Pattern.matches("[789]{1}[0-9]{9}", "9953038949"));//true
9. System.out.println(Pattern.matches("[789][0-9]{9}", "9953038949"));//true
10.
11. System.out.println(Pattern.matches("[789][09]{9}", "99530389490"));//false (11 characters)
12. System.out.println(Pattern.matches("[789][09]{9}", "6953038949"));//false (starts from 6)
13. System.out.println(Pattern.matches("[789][0-9]{9}", "8853038949"));//true
14.
15. System.out.println("by metacharacters ...");
16. System.out.println(Pattern.matches("[789]{1}\\d{9}", "8853038949"));//true
17. System.out.println(Pattern.matches("[789]{1}\\d{9}", "3853038949"));//false (starts from
3)
18.
19. }}

Exception Handling in Java

167
1. Exception Handling
2. Advantage of Exception Handling
3. Hierarchy of Exception classes
4. Types of Exception
5. Scenarios where exception may occur
The exception handling in java is one of the powerful mechanism to handle the runtime
errors so that normal flow of the application can be maintained.
In this page, we will learn about java exception, its type and the difference between
checked and unchecked exceptions.

What is exception
Dictionary Meaning: Exception is an abnormal condition.
In java, exception is an event that disrupts the normal flow of the program. It is an object
which is thrown at runtime.

What is exception handling


Exception Handling is a mechanism to handle runtime errors such as ClassNotFound, IO,
SQL, Remote etc.

Advantage of Exception Handling


The core advantage of exception handling is to maintain the normal flow of the
application. Exception normally disrupts the normal flow of the application that is why we
use exception handling. Let's take a scenario:
1.
2.
3.
4.
5.
6.
7.
8.

statement
statement
statement
statement
statement
statement
statement
statement

1;
2;
3;
4;
5;//exception occurs
6;
7;
8;

168
9. statement 9;
10. statement 10;
Suppose there is 10 statements in your program and there occurs an exception at
statement 5, rest of the code will not be executed i.e. statement 6 to 10 will not run. If we
perform exception handling, rest of the exception will be executed. That is why we use
exception handling in java.

Do You Know ?

What is the difference between checked and unchecked exceptions ?


What happens behind the code int data=50/0; ?
Why use multiple catch block ?
Is there any possibility when finally block is not executed ?
What is exception propagation ?
What is the difference between throw and throws keyword ?
What are the 4 rules for using exception handling with method overriding ?

169

Hierarchy of Exception classes

Types of Exception
There are mainly two types of exceptions: checked and unchecked where error is considered
as unchecked exception. The sun microsystem says there are three types of exceptions:
1. Checked Exception
2. Unchecked Exception
3. Error

170

Difference between checked and unchecked


exceptions
1) Checked Exception
The classes that extend Throwable class except RuntimeException and Error are known as
checked exceptions e.g.IOException, SQLException etc. Checked exceptions are checked at
compile-time.

2) Unchecked Exception
The classes that extend RuntimeException are known as unchecked exceptions e.g.
ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc.
Unchecked exceptions are not checked at compile-time rather they are checked at runtime.

3) Error
Error is irrecoverable e.g. OutOfMemoryError, VirtualMachineError, AssertionError etc.

Common scenarios where exceptions may occur


There are given some scenarios where unchecked exceptions can occur. They are as
follows:

1) Scenario where ArithmeticException occurs


If we divide any number by zero, there occurs an ArithmeticException.
1. int a=50/0;//ArithmeticException

2) Scenario where NullPointerException occurs


If we have null value in any variable, performing any operation by the variable occurs an
NullPointerException.
1. String s=null;
2. System.out.println(s.length());//NullPointerException

171

3) Scenario where NumberFormatException occurs


The wrong formatting of any value, may occur NumberFormatException. Suppose I have a
string variable that have characters, converting this variable into digit will occur
NumberFormatException.
1. String s="abc";
2. int i=Integer.parseInt(s);//NumberFormatException

4) Scenario where ArrayIndexOutOfBoundsException occurs


If you are inserting any value in the wrong index, it would result
ArrayIndexOutOfBoundsException as shown below:
1. int a[]=new int[5];
2. a[10]=50; //ArrayIndexOutOfBoundsException

Use of try-catch block in Exception handling:


Five keywords used in Exception handling:
1.
2.
3.
4.
5.

try
catch
finally
throw
throws

try block
Enclose the code that might throw an exception in try block. It must be used within the
method and must be followed by either catch or finally block.

Syntax of try with catch block


1. try{
2. ...
3. }catch(Exception_class_Name reference){}

Syntax of try with finally block


1. try{

172
2. ...
3. }finally{}

catch block
Catch block is used to handle the Exception. It must be used after the try block.

Problem without exception handling


1. public class Testtrycatch1{
2.
public static void main(String args[]){
3.
int data=50/0;
4.
5.
System.out.println("rest of the code...");
6. }
7. }
Test it Now
Output:Exception in thread main java.lang.ArithmeticException:/ by zero

As displayed in the above example, rest of the code is not executed i.e. rest of the
code... statement is not printed. Let's see what happens behind the scene:

173

What happens behind the code int a=50/0;

The JVM firstly checks whether the exception is handled or not. If exception is not
handled, JVM provides a default exception handler that performs the following tasks:

Prints out exception description.


Prints the stack trace (Hierarchy of methods where the exception occurred).
Causes the program to terminate.

But if exception is handled by the application programmer, normal flow of the application
is maintained i.e. rest of the code is executed.

Solution by exception handling


1. public class Testtrycatch2{

174
2.
public static void main(String args[]){
3.
try{
4.
int data=50/0;
5.
6.
}catch(ArithmeticException e){System.out.println(e);}
7.
8.
System.out.println("rest of the code...");
9. }
10. }
Test it Now
Output:Exception in thread main java.lang.ArithmeticException:/ by zero
rest of the code...
Now, as displayed in the above example, rest of the code is executed i.e. rest of the
code... statement is printed.

Multiple catch block:


If you have to perform different tasks at the occrence of different Exceptions, use
multple catch block.
Example of multiple catch block
public class TestMultipleCatchBlock{
public static void main(String args[]){
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e){System.out.println("task1 is completed");}
catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");}
catch(Exception e){System.out.println("common task completed");}

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11. System.out.println("rest of the code...");
12. }
13. }
Test it Now
Output:task1 completed
rest of the code...

Rule:At a time only one Exception is occured and at a time only one catch block is
executed.
Rule:All catch blocks must be ordered from most specific to most general i.e. catch
for ArithmeticException must come before catch for Exception .
1. class TestMultipleCatchBlock1{

175
2.
public static void main(String args[]){
3.
try{
4.
int a[]=new int[5];
5.
a[5]=30/0;
6.
}
7.
catch(Exception e){System.out.println("common task completed");}
8.
catch(ArithmeticException e){System.out.println("task1 is completed");}
9.
catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");}
10.
11. System.out.println("rest of the code...");
12. }
13. }
Test it Now
Output:Compile-time error

Nested try block:


try block within a try block is known as nested try block.

Why use nested try block?


Sometimes a situation may arise where a part of a block may cause one error and the
entire block itself may cause another error. In such cases, exception handlers have to be
nested

Syntax:
1. ....
2. try
3. {
4.
statement 1;
5.
statement 2;
6.
try
7.
{
8.
statement 1;
9.
statement 2;
10.
}
11.
catch(Exception e)
12.
{
13.
}
14. }
15. catch(Exception e)
16. {
17. }
18. ....

176

Example:
Example of nested try block
1. class Excep6{
2. public static void main(String args[]){
3.
try{
4.
try{
5.
System.out.println("going to divide");
6.
int b =39/0;
7.
}catch(ArithmeticException e){System.out.println(e);}
8.
9.
try{
10.
int a[]=new int[5];
11.
a[5]=4;
12.
}catch(ArrayIndexOutOfBoundsException e){System.out.println(e);}
13.
14.
System.out.println("other statement);
15. }catch(Exception e){System.out.println("handeled");}
16.
17. System.out.println("normal flow..");
18. }
19. }

finally block
The finally block is a block that is always executed. It is mainly used to perform some
important tasks such as closing connection, stream etc.

177

Note:Before terminating the program, JVM executes finally block(if any).


Note:finally must be followed by try or catch block.

Why use finally block?

finally block can be used to put "cleanup" code such as closing a file,closing
connection etc.

case 1
Program in case exception does not occur

178
1. class TestFinallyBlock{
2.
public static void main(String args[]){
3.
try{
4.
int data=25/5;
5.
System.out.println(data);
6.
}
7.
catch(NullPointerException e){System.out.println(e);}
8.
9.
finally{System.out.println("finally block is always executed");}
10.
11. System.out.println("rest of the code...");
12. }
13. }
Test it Now
Output:5
finally block is always executed
rest of the code...

case 2
Program in case exception occured but not handled
1. class TestFinallyBlock1{
2.
public static void main(String args[]){
3.
try{
4.
int data=25/0;
5.
System.out.println(data);
6.
}
7.
catch(NullPointerException e){System.out.println(e);}
8.
9.
finally{System.out.println("finally block is always executed");}
10.
11. System.out.println("rest of the code...");
12. }
13. }
Test it Now
Output:finally block is always executed
Exception in thread main java.lang.ArithmeticException:/ by zero

case 3
Program in case exception occured and handled
1. public class TestFinallyBlock2{
2.
public static void main(String args[]){
3.
try{
4.
int data=25/0;
5.
System.out.println(data);
6.
}
7.
catch(ArithmeticException e){System.out.println(e);}

179
8.
9.
finally{System.out.println("finally block is always executed");}
10.
11. System.out.println("rest of the code...");
12. }
13. }
Test it Now
Output:Exception in thread main java.lang.ArithmeticException:/ by zero
finally block is always executed
rest of the code...

Rule: For each try block there can be zero or more catch blocks, but only one finally
block.
Note: The finally block will not be executed if program exits(either by calling
System.exit() or by causing a fatal error that causes the process to abort).

throw keyword
The throw keyword is used to explictily throw an exception.
We can throw either checked or uncheked exception. The throw keyword is mainly used
to throw custom exception. We will see custom exceptions later.

Example of throw keyword


In this example, we have created the validate method that takes integer value as a
parameter. If the age is less than 18, we are throwing the ArithmeticException otherwise
print a message welcome to vote.
1. public class TestThrow1{
2.
3.
static void validate(int age){
4.
if(age<18)
5.
throw new ArithmeticException("not valid");
6.
else
7.
System.out.println("welcome to vote");
8.
}
9.
10. public static void main(String args[]){
11.
validate(13);

180
12.
System.out.println("rest of the code...");
13. }
14. }
Test it Now
Output:Exception in thread main java.lang.ArithmeticException:not valid

Exception propagation:
An exception is first thrown from the top of the stack and if it is not caught, it drops
down the call stack to the previous method,If not caught there, the exception again
drops down to the previous method, and so on until they are caught or until they reach
the very bottom of the call stack.This is called exception propagation.

Rule: By default Unchecked Exceptions are forwarded in calling chain (propagated).


Program of Exception Propagation
1. class TestExceptionPropagation1{
2.
void m(){
3.
int data=50/0;
4.
}
5.
void n(){
6.
m();
7.
}
8.
void p(){
9.
try{
10.
n();
11. }catch(Exception e){System.out.println("exception handled");}
12. }
13. public static void main(String args[]){
14. TestExceptionPropagation1 obj=new TestExceptionPropagation1();
15. obj.p();
16. System.out.println("normal flow...");
17. }
18. }
Test it Now
Output:exception handled
normal flow...

181

In the above example exception occurs in m() method where it is not handled,so it is
propagated to previous n() method where it is not handled, again it is propagated to p()
method where exception is handled.
Exception can be handled in any method in call stack either in main() method,p()
method,n() method or m() method.

Rule: By default, Checked Exceptions are not forwarded in calling chain


(propagated).
Program which describes that checked exceptions are not propagated
1. class TestExceptionPropagation2{
2.
void m(){
3.
throw new java.io.IOException("device error");//checked exception
4.
}
5.
void n(){
6.
m();
7.
}
8.
void p(){
9.
try{
10.
n();
11. }catch(Exception e){System.out.println("exception handeled");}
12. }
13. public static void main(String args[]){
14. TestExceptionPropagation2 obj=new TestExceptionPropagation2();
15. obj.p();
16. System.out.println("normal flow");
17. }

182
18. }
Test it Now
Output:Compile Time Error

throws keyword
The throws keyword is used to declare an exception. It gives an information to the
programmer that there may occur an exception so it is better for the programmer to
provide the exception handling code so that normal flow can be maintained.
Exception Handling is mainly used to handle the checked exceptions. If there occurs any
unchecked exception such as NullPointerException, it is programmers fault that he is not
performing check up before the code being used.

Syntax of throws keyword:


1. void method_name() throws exception_class_name{
2. ...
3. }

Que) Which exception should we declare?


Ans) checked exception only, because:

unchecked Exception: under your control so correct your code.


error: beyond your control e.g. you are unable to do anything if there occurs
VirtualMachineError or StackOverflowError.

Advantage of throws keyword:


Now Checked Exception can be propagated (forwarded in call stack).

Program which describes that checked exceptions can be propagated by throws


keyword.
1. import java.io.IOException;
2. class Testthrows1{
3.
void m()throws IOException{
4.
throw new IOException("device error");//checked exception
5.
}
6.
void n()throws IOException{
7.
m();

183
8.
}
9.
void p(){
10. try{
11.
n();
12. }catch(Exception e){System.out.println("exception handled");}
13. }
14. public static void main(String args[]){
15. Testthrows1 obj=new Testthrows1();
16. obj.p();
17. System.out.println("normal flow...");
18. }
19. }
Test it Now
Output:exception handled
normal flow...

Rule: If you are calling a method that declares an exception, you


must either caught or declare the exception.
There are two cases:
1. Case1:You caught the exception i.e. handle the exception using try/catch.
2. Case2:You declare the exception i.e. specifying throws with the method.

Case1: You handle the exception

In case you handle the exception, the code will be executed fine whether exception
occurs during the program or not.

1. import java.io.*;
2. class M{
3. void method()throws IOException{
4.
throw new IOException("device error");
5. }
6. }
7.
8.
9. public class Testthrows2{
10. public static void main(String args[]){
11.
try{
12.
Testthrows2 t=new Testthrows2();
13.
t.method();
14.
}catch(Exception e){System.out.println("exception handled");}
15.
16.
System.out.println("normal flow...");
17. }
18. }
Test it Now

184

Output:exception handled
normal flow...

Case2: You declare the exception

A)In case you declare the exception, if exception does not occur, the code will be
executed fine.
B)In case you declare the exception if exception occures, an exception will be thrown
at runtime because throws does not handle the exception.

A)Program if exception does not occur


import java.io.*;
class M{
void method()throws IOException{
System.out.println("device operation performed");
}
}

1.
2.
3.
4.
5.
6.
7.
8.
9. class Testthrows3{
10. public static void main(String args[])throws IOException{//declare exception
11.
Testthrows3 t=new Testthrows3();
12.
t.method();
13.
14.
System.out.println("normal flow...");
15. }
16. }
Test it Now
Output:device operation performed
normal flow...
B)Program if exception occurs
1. import java.io.*;
2. class M{
3. void method()throws IOException{
4.
throw new IOException("device error");
5. }
6. }
7.
8.
9. class Testthrows4{
10. public static void main(String args[])throws IOException{//declare exception
11.
Testthrows4 t=new Testthrows4();
12.
t.method();
13.
14.
System.out.println("normal flow...");
15. }
16. }

185
Test it Now
Output:Runtime Exception

Difference between throw and throws:


throw keyword

throws keyword

1)throw is used to explicitly throw an exception.

throws is used to declare an exception.

2)checked exception can not be propagated

checked exception can be propagated with

without throws.

throws.

3)throw is followed by an instance.

throws is followed by class.

4)throw is used within the method.

throws is used with the method signature.

5)You cannot throw multiple exception

You can declare multiple exception e.g.


public void method()throws
IOException,SQLException.

Que) Can we rethrow an exception?


Yes by throwing same exception in catch block.

ExceptionHandling with MethodOverriding


There are many rules if we talk about methodoverriding with exception handling. The
Rules are as follows:

If the superclass method does not declare an exception


o If the superclass method does not declare an exception, subclass
overridden method cannot declare the checked exception but it can declare
unchecked exception.
If the superclass method declares an exception
o If the superclass method declares an exception, subclass overridden
method can declare same, subclass exception or no exception but cannot

186
declare parent exception.

If the superclass method does not declare an exception


1) Rule: If the superclass method does not declare an exception, subclass
overridden method cannot declare the checked exception.
1. import java.io.*;
2. class Parent{
3.
void msg(){System.out.println("parent");}
4. }
5.
6. class TestExceptionChild extends Parent{
7.
void msg()throws IOException{
8.
System.out.println("TestExceptionChild");
9.
}
10. public static void main(String args[]){
11. Parent p=new TestExceptionChild();
12. p.msg();
13. }
14. }
Test it Now
Output:Compile Time Error

2) Rule: If the superclass method does not declare an exception, subclass


overridden method cannot declare the checked exception but can declare
unchecked exception.
1. import java.io.*;
2. class Parent{
3.
void msg(){System.out.println("parent");}
4. }
5.
6. class TestExceptionChild1 extends Parent{
7.
void msg()throws ArithmeticException{
8.
System.out.println("child");
9.
}
10. public static void main(String args[]){
11. Parent p=new TestExceptionChild1();
12. p.msg();
13. }
14. }
Test it Now

187

Output:child

If the superclass method declares an exception


1) Rule: If the superclass method declares an exception, subclass overridden
method can declare same, subclass exception or no exception but cannot declare
parent exception.

Example in case subclass overridden method declares parent


exception
1. import java.io.*;
2. class Parent{
3.
void msg()throws ArithmeticException{System.out.println("parent");}
4. }
5.
6. class TestExceptionChild2 extends Parent{
7.
void msg()throws Exception{System.out.println("child");}
8.
9.
public static void main(String args[]){
10. Parent p=new TestExceptionChild2();
11. try{
12. p.msg();
13. }catch(Exception e){}
14. }
15. }
Test it Now
Output:Compile Time Error

Example in case subclass overridden method declares same


exception
1. import java.io.*;
2. class Parent{
3.
void msg()throws Exception{System.out.println("parent");}
4. }
5.
6. class TestExceptionChild3 extends Parent{
7.
void msg()throws Exception{System.out.println("child");}
8.
9.
public static void main(String args[]){
10. Parent p=new TestExceptionChild3();
11. try{
12. p.msg();
13. }catch(Exception e){}
14. }

188
15. }
Test it Now
Output:child

Example in case subclass overridden method declares subclass


exception
1. import java.io.*;
2. class Parent{
3.
void msg()throws Exception{System.out.println("parent");}
4. }
5.
6. class TestExceptionChild4 extends Parent{
7.
void msg()throws ArithmeticException{System.out.println("child");}
8.
9.
public static void main(String args[]){
10. Parent p=new TestExceptionChild4();
11. try{
12. p.msg();
13. }catch(Exception e){}
14. }
15. }
Test it Now
Output:child

Example in case subclass overridden method declares no


exception
1. import java.io.*;
2. class Parent{
3.
void msg()throws Exception{System.out.println("parent");}
4. }
5.
6. class TestExceptionChild5 extends Parent{
7.
void msg(){System.out.println("child");}
8.
9.
public static void main(String args[]){
10. Parent p=new TestExceptionChild5();
11. try{
12. p.msg();
13. }catch(Exception e){}
14. }
15. }
Test it Now
Output:child

189

Custom Exception
If you are creating your own Exception that is known as custom exception or user1.
2.
3.
4.
5.

defined exception.
class InvalidAgeException extends Exception{
InvalidAgeException(String s){
super(s);
}
}

1. class TestCustomException1{
2.
3.
static void validate(int age)throws InvalidAgeException{
4.
if(age<18)
5.
throw new InvalidAgeException("not valid");
6.
else
7.
System.out.println("welcome to vote");
8.
}
9.
10. public static void main(String args[]){
11.
try{
12.
validate(13);
13.
}catch(Exception m){System.out.println("Exception occured: "+m);}
14.
15.
System.out.println("rest of the code...");
16. }
17. }
Test it Now
Output:Exception occured: InvalidAgeException:not valid
rest of the code...

Java Inner Class


1. Java Inner classes
2. Advantage of Inner class
3. Difference between nested class and inner class
4. Types of Nested classes
Java inner class or nested class is a class i.e. declared inside the class or interface.
We use inner classes to logically group classes and interfaces in one place so that it can be
more readable and maintainable.
Additionally, it can access all the members of outer class including private data members
and methods.

190

Syntax of Inner class


1. class Java_Outer_class{
2. ...
3. class Java_Inner_class{
4.
...
5. }
6. ...
7. }

Advantage of java inner classes


There are basically three advantages of inner classes in java. They are as follows:
1) Nested classes represent a special type of relationship that is it can access all the
members (data members and methods) of outer class including private.
2) Nested classes are used to develop more readable and maintainable code because it
logically group classes and interfaces in one place only.
3) Code Optimization: It requires less code to write.

Do You Know ?

What is the internal code generated by the compiler for member inner class ?
What are the two ways to create annonymous inner class ?
Can we access the non-final local variable inside the local inner class ?
How to access the static nested class ?
Can we define an interface within the class ?
Can we define a class within the interface ?

Difference between nested class and inner class in


Java
Inner class is a part of nested class. Non-static nested classes are known as inner classes.

191

Types of Nested classes


There are two types of nested classes non-static and static nested classes.The non-static
nested classes are also known as inner classes.
1. non-static nested class(inner class)
o a)Member inner class
o b)Annomynous inner class
o c)Local inner class
2. static nested class

Type

Description

Member Inner Class

A class created within class and outside method.

Annonymous Inner

A class created for implementing interface or extending class. Its name is

Class

decided by the java compiler.

Local Inner Class

A class created within method.

Static Nested Class

A static class created within class.

Nested Interface

An interface created within class or interface.

1)Member inner class


A class that is declared inside a class but outside a method is known as member inner
class.

Invocation of Member Inner class


1. From within the class
2. From outside the class

Example of member inner class that is invoked inside a class


In this example, we are invoking the method of member inner class from the display
method of Outer class.

192
1. class TestMemberOuter1{
2. private int data=30;
3. class Inner{
4.
void msg(){System.out.println("data is "+data);}
5. }
6.
7. void display(){
8.
Inner in=new Inner();
9.
in.msg();
10. }
11. public static void main(String args[]){
12. TestMemberOuter1 obj=new TestMemberOuter1();
13. obj.display();
14. }
15. }
Test it Now
Output:data is 30

Internal code generated by the compiler for member inner class:


The java compiler creates a class file named Outer$Inner in this case. The Member inner
class have the reference of Outer class that is why it can access all the data members of
Outer class including private.
1. import java.io.PrintStream;
2.
3. class Outer$Inner
4. {
5.
final Outer this$0;
6.
Outer$Inner()
7.
{ super();
8.
this$0 = Outer.this;
9.
}
10.
11.
void msg()
12.
{
13.
System.out.println((new StringBuilder()).append("data is ")
14.
.append(Outer.access$000(Outer.this)).toString());
15.
}
16.
17. }

193

Example of member inner class that is invoked outside a class


In this example, we are invoking the msg() method of Inner class from outside the outer
class i.e. Test class.
1. <b><i>//Program of member inner class that is invoked outside a class</i></b>
2.
3. class Outer{
4.
private int data=30;
5.
class Inner{
6.
void msg(){System.out.println("data is"+data);}
7.
}
8. }
9.
10. class TestMemberInner{
11. public static void main(String args[]){
12. Outer obj=new Outer();
13. Outer.Inner in=obj.new Inner();
14. in.msg();
15. }
16. }
Test it Now
Output:data is 30

2)Annonymous inner class

194

A class that have no name is known as annomymous inner class.


Annonymous class can be created by:
1. Class (may be abstract class also).
2. Interface

Program of annonymous inner class by abstract class


1. abstract class Person{
2.
abstract void eat();
3. }
4.
5. class TestAnnonymousInner{
6. public static void main(String args[]){
7.
Person p=new Person(){
8.
void eat(){System.out.println("nice fruits");}
9.
};
10.
11. p.eat();
12. }
13. }
Test it Now
Output:nice fruits

What happens behind this code?


1.
Person p=new Person(){
2.
void eat(){System.out.println("nice fruits");}
3.
};
4.
5. }
6. }
1. A class is created but its name is decided by the compiler which extends the Person
class and provides the implementation of the eat() method.
2. An object of Annonymous class is created that is reffered by p reference variable of
Person type. As you know well that Parent class reference variable can refer the
object of Child class.

The internal code generated by the compiler for annonymous


inner class
1. import java.io.PrintStream;
2. static class Emp$1 extends Person
3. {
4.
Emp$1(){}
5.
6.
void eat()
7.
{

195
8.
System.out.println("nice fruits");
9.
}
10. }

Program of annonymous inner class by interface


1. interface Eatable{
2. void eat();
3. }
4.
5. class TestAnnonymousInner1{
6. public static void main(String args[]){
7.
8. Eatable e=new Eatable(){
9.
public void eat(){System.out.println("nice fruits");}
10. };
11. e.eat();
12. }
13. }
Test it Now
Output:nice fruits

What does the compiler for annonymous inner class created by


interface
It performs two main tasks behind this code:
1.
Eatable p=new Eatable(){
2.
void eat(){System.out.println("nice fruits");}
3.
};
4.
5. }
6. }
1. A class is created but its name is decided by the compiler which implements the
Eatable interface and provides the implementation of the eat() method.
2. An object of Annonymous class is created that is reffered by p reference variable of
Eatable type. As you know well that Parent class reference variable can refer the
object of Child class.

The internal code generated by the compiler for annonymous


inner class created by interface
1.
2.
3.
4.
5.
6.
7.

import java.io.PrintStream;
static class Emp$1 implements Eatable
{
Emp$1(){}
void eat(){System.out.println("nice fruits");}
}

196

3)Local inner class


A class that is created inside a method is known as local inner class. If you want to
invoke the methods of local inner class, you must instantiate this class inside the
method.

Program of local inner class


1. public class localInner1{
2. private int data=30;//instance variable
3. void display(){
4.
class Local{
5.
void msg(){System.out.println(data);}
6.
}
7.
Local l=new Local();
8.
l.msg();
9. }
10. public static void main(String args[]){
11. localInner1 obj=new localInner1();
12. obj.display();
13. }
14. }
Test it Now
Output:30

Internal code generated by the compiler for local inner class


In such case, compiler creates a class named Simple$1Local that have the reference of
the outer class.
1. import java.io.PrintStream;
2. class Simple$1Local
3. {
4.
final Simple this$0;
5.
6.
Simple$1Local()
7.
{
8.
super();
9.
this$0 = Simple.this;
10.
}
11.
void msg()
12.
{
13.
System.out.println(Simple.access$000(Simple.this));
14.
}
15.
16. }

197

Rule: Local variable can't be private, public or protected.

Rules for Local Inner class


1) Local inner class cannot be invoked from outside the method.
2) Local inner class cannot access non-final local variable.

Program of accessing non-final local variable in local inner class


1. class localInner2{
2. private int data=30;//instance variable
3. void display(){
4.
int value=50;//local variable must be final
5.
class Local{
6.
void msg(){System.out.println(value);}//C.T.Error
7.
}
8.
Local l=new Local();
9.
l.msg();
10. }
11. public static void main(String args[]){
12. localInner2 obj=new localInner2();
13. obj.display();
14. }
15. }
Test it Now
Output:Compile Time Error

Program of accessing final local variable in local inner class


1. class localInner3{
2. private int data=30;//instance variable
3. void display(){
4.
final int value=50;//local variable must be final
5.
class Local{
6.
void msg(){System.out.println(data+" "+value);}//ok
7.
}
8.
Local l=new Local();
9.
l.msg();
10. }
11. public static void main(String args[]){
12. localInner3 obj=new localInner3();
13. obj.display();
14. }
15. }
Test it Now

198

Output:30 50

4)static nested class


A static class that is created inside a class is known as static nested class. It cannot access
the non-static members.

It can access static data members of outer class including private.


static nested class cannot access non-static (instance) data member or method.

Program of static nested class that have instance method


1. class TestOuter1{
2.
static int data=30;
3.
4.
static class Inner{
5.
void msg(){System.out.println("data is "+data);}
6.
}
7.
8.
public static void main(String args[]){
9.
TestOuter1.Inner obj=new TestOuter1.Inner();
10. obj.msg();
11. }
12. }
Test it Now
Output:data is 30

In this example, you need to create the instance of static nested class because it has
instance method msg(). But you don't need to create the object of Outer class because
nested class is static and static properties, methods or classes can be accessed without
object.

Internal code generated by the compiler for static nested class


1. import java.io.PrintStream;
2.
3. static class Outer$Inner
4. {
5. Outer$Inner(){}
6.
7. void msg(){
8. System.out.println((new StringBuilder()).append("data is ")
9. .append(Outer.data).toString());
10. }
11.
12. }

199

Program of static nested class that have static method


1. class TestOuter2{
2.
static int data=30;
3.
4.
static class Inner{
5.
static void msg(){System.out.println("data is "+data);}
6.
}
7.
8.
public static void main(String args[]){
9.
TestOuter2.Inner.msg();//no need to create the instance of static nested class
10. }
11. }
Test it Now
Output:data is 30

Nested Interface
An interface which is declared within another interface or class is known as nested
interface. The nested interfaces are used to group related interfaces so that they can be
easy to maintain. The nested interface must be referred by the outer interface or class. It
can't be accessed directly.

Points to remember for nested interfaces


There are given some points that should be remembered by the java programmer.

Nested interface must be public if it is declared inside the interface but it can have
any access modifier if declared within the class.
Nested interfaces are declared static implicitely.

Syntax of nested interface which is declared within the interface


1. interface interface_name{
2. ...
3. interface nested_interface_name{
4.
...
5. }
6. }
7.

Syntax of nested interface which is declared within the class


1. class class_name{
2. ...

200
3. interface nested_interface_name{
4.
...
5. }
6. }
7.

Example of nested interface which is declared within the interface


In this example, we are going to learn how to declare the nested interface and how we
can access it.
1. interface Showable{
2.
void show();
3.
interface Message{
4.
void msg();
5.
}
6. }
7.
8. class TestNestedInterface1 implements Showable.Message{
9. public void msg(){System.out.println("Hello nested interface");}
10.
11. public static void main(String args[]){
12. Showable.Message message=new TestNestedInterface1();//upcasting here
13. message.msg();
14. }
15. }
Test it Now

download the example of nested interface


Output:hello nested interface
As you can see in the above example, we are acessing the Message interface by its outer
interface Showable because it cannot be accessed directly. It is just like almirah inside
the room, we cannot access the almirah directly because we must enter the room first.
In collection frameword, sun microsystem has provided a nested interface Entry. Entry is
the subinterface of Map i.e. accessed by Map.Entry.

Internal code generated by the java compiler for nested interface


Message
The java compiler internally creates public and static interface as displayed below:.
1. public static interface Showable$Message
2. {
3.
public abstract void msg();

201
4. }

Example of nested interface which is declared within the class


Let's see how can we define an interface inside the class and how can we access it.
1. class A{
2.
interface Message{
3.
void msg();
4.
}
5. }
6.
7. class TestNestedInterface2 implements A.Message{
8. public void msg(){System.out.println("Hello nested interface");}
9.
10. public static void main(String args[]){
11. A.Message message=new TestNestedInterface2();//upcasting here
12. message.msg();
13. }
14. }
Test it Now
Output:hello nested interface

Can we define a class inside the interface ?


Yes, Ofcourse! If we define a class inside the interface, java compiler creates a static
nested class. Let's see how can we define a class within the interface:
1. interface M{
2.
class A{}
3. }

Input and Output in Java


Input and Output (I/O) is used to process the input and produce the output based on the
input. Java uses the concept of stream to make I/O operations fast. java.io package
contains all the classes required for input and output operations.

Stream
A stream is a sequence of data.In Java a stream is composed of bytes. It's called a
stream because it's like a stream of water that continues to flow.

Three streams are created for us automatically:

202

1) System.out: standard output stream


2) System.in: standard input stream
3) System.err: standard error

Do You Know ?

How to write a common data to multiple files using single stream only ?
How can we access multiple files by single stream ?
How can we improve the performance of Input and Output operation ?
How many ways can we read data from the keyboard?
What is console class ?
How to compress and uncompress the data of a file?

OutputStream
Java application uses an output stream to write data to a destination, it may be a file,an
array,peripheral device or socket.

InputStream
Java application uses an input stream to read data from a source, it may be a file,an
array,peripheral device or socket.

203

OutputStream class
OutputStream class is an abstract class.It is the superclass of all classes representing an
output stream of bytes. An output stream accepts output bytes and sends them to some
sink.

Commonly used methods of OutputStream class


Method

Description

1) public void write(int)throws

is used to write a byte to the current output

IOException:

stream.

2) public void write(byte[])throws

is used to write an array of byte to the current

IOException:

output stream.

3) public void flush()throws IOException:

flushes the current output stream.

204

4) public void close()throws IOException:

is used to close the current output stream.

InputStream class
InputStream class is an abstract class.It is the superclass of all classes representing an
input stream of bytes.

Commonly used methods of InputStream class


Method

Description

1) public abstract int read()throws

reads the next byte of data from the input stream.It

IOException:

returns -1 at the end of file.

2) public int available()throws

returns an estimate of the number of bytes that can be

IOException:

read from the current input stream.

3) public void close()throws

is used to close the current input stream.

IOException:

205

FileInputStream and FileOutputStream (File


Handling):
FileInputStream and FileOutputStream classes are used to read and write data in file. In
another words, they are used for file handling in java.

FileOutputStream class:
A FileOutputStream is an output stream for writing data to a file.
If you have to write primitive values then use FileOutputStream.Instead, for characteroriented data, prefer FileWriter.But you can write byte-oriented as well as characteroriented data.

Example of FileOutputStream class:


1. //<b><i>Simple program of writing data into the file</i></b>
2.
3.
4. import java.io.*;
5. class Test{
6.
public static void main(String args[]){
7.
try{
8.
FileOutputstream fout=new FileOutputStream("abc.txt");

206
9.
String s="Sachin Tendulkar is my favourite player";
10.
11.
byte b[]=s.getBytes();
12.
fout.write(b);
13.
14.
fout.close();
15.
16.
System.out.println("success...");
17.
}catch(Exception e){system.out.println(e);}
18. }
19. }
Output:success...

FileInputStream class:
A FileInputStream obtains input bytes from a file.It is used for reading streams of raw bytes
such as image data. For reading streams of characters, consider using FileReader.
It should be used to read byte-oriented data.For example, to read image etc.

Example of FileInputStream class:


1. //<b><i>Simple program of reading data from the file</i></b>
2.
3. import java.io.*;
4. class SimpleRead{
5. public static void main(String args[]){
6.
try{
7.
FileInputStream fin=new FileInputStream("abc.txt");
8.
int i;
9.
while((i=fr.read())!=-1)
10.
System.out.println((char)i);
11.

207
12.
fin.close();
13. }catch(Exception e){system.out.println(e);}
14. }
15. }
Output:Sachin is my favourite player.

Example of Reading the data of current java file and writing it


into another file
We can read the data of any file using the FileInputStream class whether it is java file,
image file, video file etc. In this example, we are reading the data of C.java file and writing
it into another file M.java.
1. import java.io.*;
2.
3. class C{
4. public static void main(String args[])throws Exception{
5.
6. FileInputStream fin=new FileInputStream("C.java");
7. FileOutputStream fout=new FileOutputStream("M.java");
8.
9. int i=0;
10. while((i=fin.read())!=-1){
11. fout.write((byte)i);
12. }
13.
14. fin.close();
15. }
16. }

ByteArrayOutputStream class:

208

In this stream, the data is written into a byte array. The buffer automatically grows as data
is written to it.
Closing a ByteArrayOutputStream has no effect.

Commonly used Constructors of ByteArrayOutputStream class:


1) ByteArrayOutputStream():creates a new byte array output stream with the initial
capacity of 32 bytes, though its size increases if necessary.
2) ByteArrayOutputStream(int size):creates a new byte array output stream, with a
buffer capacity of the specified size, in bytes.

Commonly used Methods of ByteArrayOutputStream class:


1) public synchronized void writeTo(OutputStream out) throws
IOException: writes the complete contents of this byte array output stream to the
specified output stream.

Example of ByteArrayOutputStream class:


1. //<b><i>Simple program of writing data by ByteArrayOutputStream class</i></b>
2.
3.
4. import java.io.*;
5. class S{
6. public static void main(String args[])throws Exception{
7.
8.
FileOutputStream fout1=new FileOutputStream("f1.txt");
9.
FileOutputStream fout2=new FileOutputStream("f2.txt");
10.
11. ByteArrayOutputStream bout=new ByteArrayOutputStream();
12. bout.write(239);
13.
14. bout.writeTo(fout1);
15. bout.writeTo(fout2);
16.
17. bout.flush();
18.
19. bout.close();//has no effect
20. System.out.println("success...");
21. }
22. }
Output:success...

209

SequenceInputStream class:
SequenceInputStream class is used to read data from multiple streams.

Constructors of SequenceInputStream class:


1) SequenceInputStream(InputStream s1, InputStream s2):creates a new input
stream by reading the data of two input stream in order, first s1 and then s2.
2) SequenceInputStream(Enumeration e):creates a new input stream by reading
the data of an enumeration whose type is InputStream.

Simple example of SequenceInputStream class


In this example, we are printing the data of two files f1.txt and f2.txt.
1. //Program of SequenceInputStream that reads data of 2 files
2.
3. import java.io.*;
4. class Simple{
5.
public static void main(String args[])throws Exception{
6.

210
7.
FileinputStream fin1=new FileinputStream("f1.txt");
8.
FileinputStream fin2=new FileinputStream("f2.txt");
9.
10. SequenceinputStream sis=new SequenceinputStream(fin1,fin2);
11. int i;
12. while((i=sis.read())!=-1)
13. {
14.
System.out.println((char)i);
15. }
16. }
17. }

Example of SequenceInputStream class that reads the data


from two files and write it into another
In this example, we are writing the data of two files f1.txt and f2.txt into another file
named f3.txt.
1. //reading data of 2 files and writing it into one file
2.
3. import java.io.*;
4. class Simple{
5.
public static void main(String args[])throws Exception{
6.
7.
FileinputStream fin1=new FileinputStream("f1.txt");
8.
FileinputStream fin2=new FileinputStream("f2.txt");
9.
10. FileOutputStream fout=new FileOutputStream("f3.txt");
11.
12. SequenceinputStream sis=new SequenceinputStream(fin1,fin2);
13. int i;
14. while((i.sisread())!=-1)
15. {
16.
fout.write(i);
17. }
18. sis.close();
19. fout.close();
20. fin.close();
21. fin.close();
22.
23. }
24. }

Example of SequenceInputStream class that reads the data


from multiple files using enumeration
If we need to read the data from more than two files, we need to have these information

211

in the Enumeration object. Enumeration object can be get by calling elements method of
the Vector class. Let's see the simple example where we are reading the data from the 4
files.
1. import java.io.*;
2. import java.util.*;
3.
4. class B{
5. public static void main(String args[])throws IOException{
6.
7. //creating the FileInputStream objects for all the files
8. FileInputStream fin=new FileInputStream("A.java");
9. FileInputStream fin2=new FileInputStream("abc2.txt");
10. FileInputStream fin3=new FileInputStream("abc.txt");
11. FileInputStream fin4=new FileInputStream("B.java");
12.
13. //creating Vector object to all the stream
14. Vector v=new Vector();
15. v.add(fin);
16. v.add(fin2);
17. v.add(fin3);
18. v.add(fin4);
19.
20. //creating enumeration object by calling the elements method
21. Enumeration e=v.elements();
22.
23. //passing the enumeration object in the constructor
24. SequenceInputStream bin=new SequenceInputStream(e);
25. int i=0;
26.
27. while((i=bin.read())!=-1){
28. System.out.print((char)i);
29. }
30.
31. bin.close();
32. fin.close();
33. fin2.close();
34. }
35. }

BufferedOutputStream class:
BufferedOutputStream used an internal buffer. It adds more efficiency than to write data
directly into a stream. So, it makes the performance fast.

212

Example of BufferedOutputStream class:


In this example, we are writing the textual information in the BufferedOutputStream object
which is connected to the FileOutputStream object. The flush() flushes the data of one
stream and send it into another. It is required if you have connected the one stream with
another.
1. import java.io.*;
2. class Test{
3. public static void main(String args[])throws Exception{
4.
5.
FileOutputStream fout=new FileOutputStream("f1.txt");
6.
BufferedOutputStream bout=new BufferedOutputStream(fout);
7.
8.
String s="Sachin is my favourite player";
9.
byte b[]=s.getBytes();
10. bout.write(b);
11.
12. bout.flush();
13. bout.close();
14. System.out.println("success");
15. }
16. }
Output:success...

Example of BufferedInputStream class:


1. //<b><i>Simple program of reading data from the file using buffer</i></b>
2.
3. import java.io.*;
4. class SimpleRead{
5. public static void main(String args[]){
6.
try{
7.
8.
FileInputStream fin=new FileInputStream("f1.txt");
9.
BufferedInputStream bin=new BufferedInputStream(fin);
10.
int i;
11.
while((i=bin.read())!=-1)
12.
System.out.println((char)i);
13.
14.
fin.close();
15. }catch(Exception e){system.out.println(e);}
16. }
17. }
Output:Sachin is my favourite player

213

next>><<prev

FileWriter class:
FileWriter class is used to write character-oriented data to the file. Sun Microsystem has
suggested not to use the FileInputStream and FileOutputStream classes if you have to
read and write the textual information.

Example of FileWriter class:


In this example, we are writing the data in the file abc.txt.
1. import java.io.*;
2. class Simple{
3. public static void main(String args[]){
4.
try{
5.
FileWriter fw=new FileWriter("abc.txt");
6.
fw.write("my name is sachin");
7.
fw.flush();
8.
9.
fw.close();
10. }catch(Exception e){System.out.println(e);}
11. System.out.println("success");
12. }
13. }
Output:success...

FileReader class:
FileReader class is used to read data from the file.

Example of FileReader class:


In this example, we are reading the data from the file abc.txt file.
1. import java.io.*;
2. class Simple{
3. public static void main(String args[])throws Exception{
4.
5.
FileReader fr=new FileReader("abc.txt");
6.
int i;
7.
while((i=fr.read())!=-1)
8.
System.out.println((char)i);
9.

214
10. fr.close();
11. }
12. }

Output:my name is sachin

CharArrayWriter class:
The CharArrayWriter class can be used to write data to multiple files. This class implements
the Appendable interface. Its buffer automatically grows when data is written in this stream.
Calling the close() method on this object has no effect.

Example of CharArrayWriter class:


In this example, we are writing a common data to 4 files a.txt, b.txt, c.txt and d.txt.
1. import java.io.*;
2. class Simple{
3. public static void main(String args[])throws Exception{
4.
5.
CharArrayWriter out=new CharArrayWriter();
6.
out.write("my name is");
7.
8.
FileWriter f1=new FileWriter("a.txt");
9.
FileWriter f2=new FileWriter("b.txt");
10. FileWriter f3=new FileWriter("c.txt");
11. FileWriter f4=new FileWriter("d.txt");
12.
13. out.writeTo(f1);
14. out.writeTo(f2);
15. out.writeTo(f3);
16. out.writeTo(f4);
17.
18.
19. f1.close();
20. f2.close();
21. f3.close();
22. f4.close();
23. }
24. }

Reading data from keyboard:


There are many ways to read data from the keyboard. For example:

InputStreamReader
Console
Scanner

215

DataInputStream etc.

InputStreamReader class:
InputStreamReader class can be used to read data from keyboard.It performs two tasks:

connects to input stream of keyboard


converts the byte-oriented stream into character-oriented stream

BufferedReader class:
BufferedReader class can be used to read data line by line by readLine() method.

Example of reading data from keyboard by InputStreamReader


and BufferdReader class:
In this example, we are connecting the BufferedReader stream with the InputStreamReader
stream for reading the line by line data from the keyboard.
1. //<b><i>Program of reading data</i></b>
2.
3. import java.io.*;
4. class G5{
5. public static void main(String args[])throws Exception{
6.
7. InputStreamReader r=new InputStreamReader(System.in);
8. BufferedReader br=new BufferedReader(r);
9.
10. System.out.println("Enter your name");
11. String name=br.readLine();
12. System.out.println("Welcome "+name);
13. }
14. }
Output:Enter your name
Amit
Welcome Amit

216

Another Example of reading data from keyboard by


InputStreamReader and BufferdReader class until the user
writes stop
In this example, we are reading and printing the data until the user prints stop.
1. import java.io.*;
2. class G5{
3. public static void main(String args[])throws Exception{
4.
5. InputStreamReader r=new InputStreamReader(System.in);
6. BufferedReader br=new BufferedReader(r);
7.
8. String name="";
9.
10. while(name.equals("stop")){
11. System.out.println("Enter data: ");
12. name=br.readLine();
13. System.out.println("data is: "+name);
14. }
15.
16. br.close();
17. r.close();
18. }
19. }
Output:Enter data: Amit
data is: Amit
Enter data: 10
data is: 10

217

Enter data: stop


data is: stop

Console class (I/O)


The Console class can be used to get input from the keyboard.

How to get the object of Console class?


System class provides a static method named console() that returns the unique instance
of Console class.

Syntax:
1. public static Console console(){}

Commonly used methods of Console class:


1) public String readLine(): is used to read a single line of text from the console.
2) public String readLine(String fmt,Object... args): it provides a formatted prompt
then reads the single line of text from the console.
3) public char[] readPassword(): is used to read password that is not being
displayed on the console.
4) public char[] readPassword(String fmt,Object... args): it provides a formatted
prompt then reads the password that is not being displayed on the console.

Example of Console class that reads name of user:


1. import java.io.*;
2. class A{
3. public static void main(String args[]){
4.
5. Console c=System.console();
6.
7. System.out.println("Enter your name");
8. String n=c.readLine();
9. System.out.println("Welcome "+n);
10.
11. }
12. }

218

Example of Console class that reads password:


1. import java.io.*;
2. class A{
3. public static void main(String args[]){
4.
5. Console c=System.console();
6.
7. System.out.println("Enter password");
8. char[] ch=c.readPassword();
9.
10. System.out.println("Password is");
11. for(char ch2:ch)
12. System.out.print(ch2);
13.
14. }
15. }

java.util.Scanner class:
There are various ways to read input from the keyboard, the java.util.Scanner class is one
of them. The Scanner class breaks the input into tokens using a delimiter which is
whitespace bydefault. It provides many methods to read and parse various primitive values.

Commonly used methods of Scanner class:


There is a list of commonly used Scanner class methods:

public String next(): it returns the next token from the scanner.
public String nextLine(): it moves the scanner position to the next line and
returns the value as a string.
public byte nextByte(): it scans the next token as a byte.
public short nextShort(): it scans the next token as a short value.
public int nextInt(): it scans the next token as an int value.
public long nextLong(): it scans the next token as a long value.
public float nextFloat(): it scans the next token as a float value.
public double nextDouble(): it scans the next token as a double value.

Example of java.util.Scanner class:


Let's see the simple example of the Scanner class which reads the int, string and double
value as an input:
1. import java.util.Scanner;
2. class ScannerTest{

219
3. public static void main(String args[]){
4.
5.
Scanner sc=new Scanner(System.in);
6.
7.
System.out.println("Enter your rollno");
8.
int rollno=sc.nextInt();
9.
System.out.println("Enter your name");
10. String name=sc.next();
11. System.out.println("Enter your fee");
12. double fee=sc.nextDouble();
13.
14. System.out.println("Rollno:"+rollno+" name:"+name+" fee:"+fee);
15.
16. }
17. }

download this scanner example


Output:Enter your rollno
111
Enter your name
Ratan
Enter
450000
Rollno:111 name:Ratan fee:450000

java.io.PrintStream class:
The PrintStream class provides methods to write data to another stream. The
PrintStream class automatically flushes the data so there is no need to call flush()
method. Moreover, its methods don't throw IOException.

Commonly used methods of PrintStream class:


There are many methods in PrintStream class. Let's see commonly used methods of
PrintStream class:

public
public
public
public
public
public
public

void
void
void
void
void
void
void

print(boolean b): it prints the specified boolean value.


print(char c): it prints the specified char value.
print(char[] c): it prints the specified character array values.
print(int i): it prints the specified int value.
print(long l): it prints the specified long value.
print(float f): it prints the specified float value.
print(double d): it prints the specified double value.

220

public void print(String s): it prints the specified string value.


public void print(Object obj): it prints the specified object value.
public void println(boolean b): it prints the specified boolean value and
terminates the line.
public void println(char c): it prints the specified char value and terminates
the line.
public void println(char[] c): it prints the specified character array values
and terminates the line.
public void println(int i): it prints the specified int value and terminates the
line.
public void println(long l): it prints the specified long value and terminates
the line.
public void println(float f): it prints the specified float value and terminates
the line.
public void println(double d): it prints the specified double value and
terminates the line.
public void println(String s): it prints the specified string value and
terminates the line./li>
public void println(Object obj): it prints the specified object value and
terminates the line.
public void println(): it terminates the line only.
public void printf(Object format, Object... args): it writes the formatted
string to the current stream.
public void printf(Locale l, Object format, Object... args): it writes the
formatted string to the current stream.
public void format(Object format, Object... args): it writes the formatted
string to the current stream using specified format.
public void format(Locale l, Object format, Object... args): it writes the
formatted string to the current stream using specified format.

Example of java.io.PrintStream class:


In this example, we are simply printing integer and string values.
1. import java.io.*;
2. class PrintStreamTest{
3. public static void main(String args[])throws Exception{
4.
5.
FileOutputStream fout=new FileOutputStream("mfile.txt");
6.
PrintStream pout=new PrintStream(fout);
7.
pout.println(1900);
8.
pout.println("Hello Java");
9.
pout.println("Welcome to Java");
10. pout.close();
11. fout.close();
12.
13. }

221
14. }

download this PrintStream example

Example of printf() method of java.io.PrintStream class:


Let's see the simple example of printing integer value by format specifier.
1. class PrintStreamTest{
2. public static void main(String args[]){
3.
int a=10;
4.
System.out.printf("%d",a);//Note, out is the object of PrintStream class
5.
6. }
7. }
Output:10

Compressing and Uncompressing File


The DeflaterOutputStream and InflaterInputStream classes provide mechanism to compress
and uncompress the data in the deflate compression format.

DeflaterOutputStream class:
The DeflaterOutputStream class is used to compress the data in the deflate compression
format. It provides facility to the other compression filters, such as GZIPOutputStream.

Example of Compressing file using DeflaterOutputStream class


In this example, we are reading data of a file and compressing it into another file using
DeflaterOutputStream class. You can compress any file, here we are compressing the
Deflater.java file
1.
2.
3.
4.
5.
6.
7.
8.

import java.io.*;
import java.util.zip.*;
class Compress{
public static void main(String args[]){
try{
FileInputStream fin=new FileInputStream("Deflater.java");

222
9.
10. FileOutputStream fout=new FileOutputStream("def.txt");
11. DeflaterOutputStream out=new DeflaterOutputStream(fout);
12.
13. int i;
14. while((i=fin.read())!=-1){
15. out.write((byte)i);
16. out.flush();
17. }
18.
19. fin.close();
20. out.close();
21.
22. }catch(Exception e){System.out.println(e);}
23. System.out.println("rest of the code");
24. }
25. }

download this example

InflaterInputStream class:
The InflaterInputStream class is used to uncompress the file in the deflate compression
format. It provides facility to the other uncompression filters, such as GZIPInputStream
class.

Example of uncompressing file using InflaterInputStream class


In this example, we are decompressing the compressed file def.txt into D.java .
1. import java.io.*;
2. import java.util.zip.*;
3.
4. class UnCompress{
5. public static void main(String args[]){
6.
7. try{
8. FileInputStream fin=new FileInputStream("def.txt");
9. InflaterInputStream in=new InflaterInputStream(fin);
10.
11. FileOutputStream fout=new FileOutputStream("D.java");
12.
13. int i;
14. while((i=in.read())!=-1){
15. fout.write((byte)i);
16. fout.flush();
17. }
18.

223
19. fin.close();
20. fout.close();
21. in.close();
22.
23. }catch(Exception e){System.out.println(e);}
24. System.out.println("rest of the code");
25. }
26. }

Java Reflection API


Java Reflection is a process of examining or modifying the run time behavior of a class at
run time.
The java.lang.Class class provides many methods that can be used to get metadata,
examine and change the run time behavior of a class.
The java.lang and java.lang.reflect packages provide classes for java reflection.

Where it is used
The Reflection API is mainly used in:

IDE (Integrated Development Environment) e.g. Eclipse, MyEclipse, NetBeans etc.


Debugger
Test Tools etc.

Do You Know ?

How
How
How
How

many ways we can get the instance of Class class ?


to create the javap tool ?
to create the appletviewer tool ?
to access the private method from outside the class ?

java.lang.Class class
The java.lang.Class class performs mainly two tasks:

provides methods to get the metadata of a class at run time.


provides methods to examine and change the run time behavior of a class.

224

Commonly used methods of Class class:


Method

Description

1) public String getName()

returns the class name

2) public static Class forName(String className)throws

loads the class and

ClassNotFoundException

returns the reference of


Class class.

3) public Object newInstance()throws

creates new instance.

InstantiationException,IllegalAccessException

4) public boolean isInterface()

checks if it is interface.

5) public boolean isArray()

checks if it is array.

6) public boolean isPrimitive()

checks if it is primitive.

7) public Class getSuperclass()

returns the superclass


class reference.

8) public Field[] getDeclaredFields()throws SecurityException

returns the total number


of fields of this class.

9) public Method[] getDeclaredMethods()throws SecurityException

returns the total number


of methods of this class.

10) public Constructor[] getDeclaredConstructors()throws

returns the total number

SecurityException

of constructors of this
class.

11) public Method getDeclaredMethod(String name,Class[]

returns the method class

225

parameterTypes)throws NoSuchMethodException,SecurityException

instance.

How to get the object of Class class?


There are 3 ways to get the instance of Class class. They are as follows:

forName() method of Class class


getClass() method of Object class
the .class syntax

1) forName() method of Class class

is used to load the class dynamically.


returns the instance of Class class.
It should be used if you know the fully qualified name of class.This cannot be used
for primitive types.

Let's see the simple example of forName() method.


1. class Simple{}
2.
3. class Test{
4. public static void main(String args[]){
5.
Class c=Class.forName("Simple");
6.
System.out.println(c.getName());
7. }
8. }
Output:Simple

2) getClass() method of Object class


It returns the instance of Class class. It should be used if you know the type. Moreover, it
can be used with primitives.
1. class Simple{}
2.
3. class Test{
4.
void printName(Object obj){
5.
Class c=obj.getClass();
6.
System.out.println(c.getName());
7.
}
8.
public static void main(String args[]){
9.
Simple s=new Simple();
10.

226
11. Test t=new Test();
12. t.printName(s);
13. }
14. }
15.
Output:Simple

3) The .class syntax


If a type is available but there is no instance then it is possible to obtain a Class by
appending ".class" to the name of the type.It can be used for primitive data type also.
1. class Test{
2.
public static void main(String args[]){
3.
Class c = boolean.class;
4.
System.out.println(c.getName());
5.
6.
Class c2 = Test.class;
7.
System.out.println(c2.getName());
8. }
9. }
Output:boolean
Test

Determining the class object


Following methods of Class class is used to determine the class object:
1) public boolean isInterface(): determines if the specified Class object represents an
interface type.
2) public boolean isArray(): determines if this Class object represents an array class.
3) public boolean isPrimitive(): determines if the specified Class object represents a
primitive type.

Let's see the simple example of reflection api to determine the object type.
1. class Simple{}
2. interface My{}
3.
4. class Test{

227
5. public static void main(String args[]){
6.
try{
7.
Class c=Class.forName("Simple");
8.
System.out.println(c.isInterface());
9.
10. Class c2=Class.forName("My");
11. System.out.println(c2.isInterface());
12.
13. }catch(Exception e){System.out.println(e);}
14.
15. }
16. }

newInstance() method
The newInstance() method of Class class and Constructor class is used to create a new
instance of the class.
The newInstance() method of Class class can invoke zero-argument constructor whereas
newInstance() method of Constructor class can invoke any number of arguments. So
Constructor class is preferred over Class class.

Syntax of newInstance() method of Class class


public T newInstance()throws InstantiationException,IllegalAccessException
Here T is the generic version. You can think it like Object class. You will learn about generics
later.

Example of newInstance() method


Let's see the simple example to use newInstance() method.
1. class Simple{

228
2. void message(){System.out.println("Hello Java");}
3. }
4.
5. class Test{
6. public static void main(String args[]){
7.
try{
8.
Class c=Class.forName("Simple");
9.
Simple s=(Simple)c.newInstance();
10. s.message();
11.
12. }catch(Exception e){System.out.println(e);}
13.
14. }
15. }
Output:Hello java

Understanding javap tool


The javap command disassembles a class file. The javap command displays information
about the fields,constructors and methods present in a class file.

Syntax to use javap tool


Let's see how to use javap tool or command.
1. javap fully_class_name

Example to use javap tool


1. javap java.lang.Object
Output:
1. Compiled from "Object.java"
2. public class java.lang.Object {
3.
public java.lang.Object();
4.
public final native java.lang.Class<?> getClass();
5.
public native int hashCode();
6.
public boolean equals(java.lang.Object);
7.
protected native java.lang.Object clone() throws java.lang.CloneNotSupportedException
;
8.
public java.lang.String toString();
9.
public final native void notify();
10. public final native void notifyAll();
11. public final native void wait(long) throws java.lang.InterruptedException;
12. public final void wait(long, int) throws java.lang.InterruptedException;
13. public final void wait() throws java.lang.InterruptedException;
14. protected void finalize() throws java.lang.Throwable;
15. static {};
16. }

229

Another example to use javap tool for your class


Let's use the javap command for our java file.
1.
2.
3.
4.
5.

class Simple{
public static void main(String args[]){
System.out.println("hello java");
}
}
Now let's use the javap tool to disassemble the class file.

1. javap Simple
Output:
1. Compiled from ".java"
2. class Simple {
3.
Simple();
4.
public static void main(java.lang.String[]);
5. }

javap -c command
You can use the javap -c command to see disassembled code. The code that reflects the
java bytecode.
1. javap -c Simple
Output:
1. Compiled from ".java"
2. class Simple {
3.
Simple();
4.
Code:
5.
0: aload_0
6.
1: invokespecial #1
// Method java/lang/Object."<init>":()V
7.
4: return
8.
9.
public static void main(java.lang.String[]);
10.
Code:
11.
0: getstatic
#2
// Field java/lang/System.out:Ljava/io/PrintStream;
12.
3: ldc
#3
// String hello java
13.
5: invokevirtual #4
// Method java/io/PrintStream.println:(Ljava/lang/Strin
g;)V
14.
8: return
15. }

230

Options of javap tool


The important options of javap tool are as follows.

Option

Description

-help

prints the help message.

-l

prints line number and local variable

-c

disassembles the code

-s

prints internal type signature

-sysinfo

shows system info (path, size, date, MD5 hash)

-constants

shows static final constants

-version

shows version information

How to call private method from another class in java


You can call the private method from outside the class by changing the runtime behaviour
of the class.
By the help of java.lang.Class class and java.lang.reflect.Method class, we can call
private method from any other class.

Required methods of Method class


1) public void setAccessible(boolean status) throws SecurityException sets the
accessibility of the method.
2) public Object invoke(Object method, Object... args) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException is
used to invoke the method.

231

Required method of Class class


1) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws
NoSuchMethodException,SecurityException:returns a Method object that reflects the
specified declared method of the class or interface represented by this Class object.

Example of calling private method from another class


Let's see the simple example to call private method from another class.

File: A.java
1. public class A {
2.
private void message(){System.out.println("hello java"); }
3. }

File: MethodCall.java
1. import java.lang.reflect.Method;
2. public class MethodCall{
3. public static void main(String[] args)throws Exception{
4.
5.
Class c = Class.forName("A");
6.
Object o= c.newInstance();
7.
Method m =c.getDeclaredMethod("message", null);
8.
m.setAccessible(true);
9.
m.invoke(o, null);
10. }
11. }
Output:hello java

Another example to call parameterized private method from


another class
Let's see the example to call parameterized private method from another class

File: A.java
1. class A{
2. private void cube(int n){System.out.println(n*n*n);}
3. }

File: M.java
1. import java.lang.reflect.*;

232
2. class M{
3. public static void main(String args[])throws Exception{
4. Class c=A.class;
5. Object obj=c.newInstance();
6.
7. Method m=c.getDeclaredMethod("cube",new Class[]{int.class});
8. m.setAccessible(true);
9. m.invoke(obj,4);
10. }}
Output:64

Collections in Java
1. Java Collection Framework
2. Hierarchy of Collection Framework
3. Collection interface
4. Iterator interface
Collections in java is a framework that provides an architecture to store and manipulate
the group of objects.
All the operations that you perform on a data such as searching, sorting, insertion,
manipulation, deletion etc. can be performed by Java Collections.
Java Collection simply means a single unit of objects. Java Collection framework provides
many interfaces (Set, List, Queue, Deque etc.) and classes (ArrayList, Vector, LinkedList,
PriorityQueue, HashSet, LinkedHashSet, TreeSet etc).

What is Collection in java


Collection represents a single unit of objects i.e. a group.

What is framework in java

provides readymade architecture.


represents set of classes and interface.
is optional.

What is Collection framework


Collection framework represents a unified architecture for storing and manipulating group of
object. It has:
1. Interfaces and its implementations i.e. classes

233
2. Algorithm

Do You Know ?

What are the two ways to iterate the elements of a collection ?


What is the difference between ArrayList and LinkedList classes in collection
framework?
What is the difference between ArrayList and Vector classes in collection framework?
What is the difference between HashSet and HashMap classes in collection
framework?
What is the difference between HashMap and Hashtable class?
What is the difference between Iterator and Enumeration interface in collection
framework?
How can we sort the elements of an object. What is the difference between
Comparable and Comparator interfaces?
What does the hashcode() method ?

li>What is the difference between java collection and java collections ?

Hierarchy of Collection Framework


Let us see the hierarchy of collection framework.The java.util package contains all the
classes and interfaces for Collection framework.

234

Methods of Collection interface


There are many methods declared in the Collection interface. They are as follows:

No.
1

Method
public boolean add(Object

Description
is used to insert an element in this collection.

element)

public boolean addAll(collection

is used to insert the specified collection elements in the

235

c)

invoking collection.

public boolean remove(Object

is used to delete an element from this collection.

element)

public boolean

is used to delete all the elements of specified collection

removeAll(Collection c)

from the invoking collection.

public boolean

is used to delete all the elements of invoking collection

retainAll(Collection c)

except the specified collection.

public int size()

return the total number of elements in the collection.

public void clear()

removes the total no of element from the collection.

public boolean contains(object

is used to search an element.

element)

public boolean

is used to search the specified collection in this

containsAll(Collection c)

collection.

10

public Iterator iterator()

returns an iterator.

11

public Object[] toArray()

converts collection into array.

12

public boolean isEmpty()

checks if collection is empty.

13

public boolean equals(Object

matches two collection.

element)

14

public int hashCode()

returns the hashcode number for collection.

236

Iterator interface
Iterator interface provides the facility of iterating the elements in forward direction only.

Methods of Iterator interface


There are only three methods in the Iterator interface. They are:
1. public boolean hasNext() it returns true if iterator has more elements.
2. public object next() it returns the element and moves the cursor pointer to the
next element.
3. public void remove() it removes the last elements returned by the iterator. It is
rarely used.

What we are going to learn in Java Collections Framework


1. ArrayList class
2. LinkedList class
3. ListIterator interface
4. HashSet class
5. LinkedHashSet class
6. TreeSet class
7. PriorityQueue class
8. Map interface
9. HashMap class
10. LinkedHashMap class
11. TreeMap class
12. Hashtable class
13. Sorting
14. Comparable interface
15. Comparator interface
16. Properties class in Java

Java ArrayList class

uses a dynamic array for storing the elements.It extends AbstractList class and
implements List interface.
can contain duplicate elements.
maintains insertion order.
not synchronized.
random access because array works at the index basis.
manipulation slow because a lot of shifting needs to be occurred if any element is
removed from the array list.

237

Java Non-generic Vs Generic Collection


Java collection framework was non-generic before JDK 1.5. Since 1.5, it is generic.
Java new generic collection allows you to have only one type of object in collection. Now it is
type safe so typecasting is not required at run time.
Let's see the old non-generic example of creating java collection.
1. ArrayList al=new ArrayList();//creating old non-generic arraylist
Let's see the new generic example of creating java collection.
1. ArrayList<String> al=new ArrayList<String>();//creating new generic arraylist
In generic collection, we specify the type in angular braces. Now ArrayList is forced to have
only specified type of objects in it. If you try to add another type of object, it gives compile
time error.
For more information of java generics, click here Java Generics Tutorial.

Example of Java ArrayList class


1. import java.util.*;
2. class TestCollection1{
3. public static void main(String args[]){
4.
5.
ArrayList<String> al=new ArrayList<String>();//creating arraylist
6.
al.add("Ravi");//adding object in arraylist
7.
al.add("Vijay");
8.
al.add("Ravi");
9.
al.add("Ajay");
10.
11. Iterator itr=al.iterator();//getting Iterator from arraylist to traverse elements
12. while(itr.hasNext()){
13. System.out.println(itr.next());
14. }
15. }
16. }
Test it Now
Ravi

238

Vijay
Ravi
Ajay

Two ways to iterate the elements of collection in java


1. By Iterator interface.
2. By for-each loop.
In the above example, we have seen traversing ArrayList by Iterator. Let's see the example
to traverse ArrayList elements using for-each loop.

Iterating the elements of Collection by for-each loop


1. import java.util.*;
2. class TestCollection2{
3. public static void main(String args[]){
4.
ArrayList<String> al=new ArrayList<String>();
5.
al.add("Ravi");
6.
al.add("Vijay");
7.
al.add("Ravi");
8.
al.add("Ajay");
9.
for(String obj:al)
10.
System.out.println(obj);
11. }
12. }
Test it Now
Ravi
Vijay
Ravi
Ajay

User-defined class objects in Java ArrayList


1. class Student{
2.
int rollno;
3.
String name;
4.
int age;
5.
Student(int rollno,String name,int age){
6.
this.rollno=rollno;
7.
this.name=name;
8.
this.age=age;
9.
}
10. }
1. import java.util.*;
2. public class TestCollection3{
3. public static void main(String args[]){
4.
//Creating user-defined class objects

239
5.
Student s1=new Student(101,"Sonoo",23);
6.
Student s2=new Student(102,"Ravi",21);
7.
Student s2=new Student(103,"Hanumat",25);
8.
9.
ArrayList<Student> al=new ArrayList<Student>();//creating arraylist
10. al.add(s1);//adding Student class object
11. al.add(s2);
12. al.add(s3);
13.
14. Iterator itr=al.iterator();
15. //traversing elements of ArrayList object
16. while(itr.hasNext()){
17.
Student st=(Student)itr.next();
18.
System.out.println(st.rollno+" "+st.name+" "+st.age);
19. }
20. }
21. }
Test it Now
101 Sonoo 23
102 Ravi 21
103 Hanumat 25

Example of addAll(Collection c) method


1. import java.util.*;
2. class TestCollection4{
3. public static void main(String args[]){
4.
5.
ArrayList<String> al=new ArrayList<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ajay");
9.
10. ArrayList<String> al2=new ArrayList<String>();
11. al2.add("Sonoo");
12. al2.add("Hanumat");
13.
14. al.addAll(al2);
15.
16. Iterator itr=al.iterator();
17. while(itr.hasNext()){
18. System.out.println(itr.next());
19. }
20. }
21. }
Test it Now
Ravi
Vijay

240

Ajay
Sonoo
Hanumat

Example of removeAll() method


1. import java.util.*;
2. class TestCollection5{
3. public static void main(String args[]){
4.
5.
ArrayList<String> al=new ArrayList<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ajay");
9.
10. ArrayList<String> al2=new ArrayList<String>();
11. al2.add("Ravi");
12. al2.add("Hanumat");
13.
14. al.removeAll(al2);
15.
16. System.out.println("iterating the elements after removing the elements of al2...");
17. Iterator itr=al.iterator();
18. while(itr.hasNext()){
19. System.out.println(itr.next());
20. }
21.
22. }
23. }
Test it Now
iterating the elements after removing the elements of al2...
Vijay
Ajay

Example of retainAll() method


1. import java.util.*;
2. class TestCollection6{
3. public static void main(String args[]){
4.
5.
ArrayList<String> al=new ArrayList<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ajay");
9.
10. ArrayList<String> al2=new ArrayList<String>();
11. al2.add("Ravi");

241
12. al2.add("Hanumat");
13.
14. al.retainAll(al2);
15.
16. System.out.println("iterating the elements after retaining the elements of al2...");
17. Iterator itr=al.iterator();
18. while(itr.hasNext()){
19. System.out.println(itr.next());
20. }
21. }
22. }
Test it Now
iterating the elements after retaining the elements of al2...
Ravi

LinkedList class:

uses doubly linked list to store the elements. It extends the AbstractList class and
implements List and Deque interfaces.
can contain duplicate elements.
maintains insertion order.
not synchronized.
No random access.
manipulation fast because no shifting needs to be occurred.
can be used as list, stack or queue.

Example of LinkedList:
1. import java.util.*;
2. public class TestCollection7{
3. public static void main(String args[]){
4.
5.
LinkedList<String> al=new LinkedList<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ravi");
9.
al.add("Ajay");
10.
11. Iterator<String> itr=al.iterator();

242
12. while(itr.hasNext()){
13. System.out.println(itr.next());
14. }
15. }
16. }
Test it Now
Output:Ravi
Vijay
Ravi
Ajay

List Interface:
List Interface is the subinterface of Collection.It contains methods to insert and delete
elements in index basis.It is a factory of ListIterator interface.

Commonly used methods of List Interface:


1.
2.
3.
4.
5.
6.
7.

public
public
public
public
public
public
public

void add(int index,Object element);


boolean addAll(int index,Collection c);
object get(int Index position);
object set(int index,Object element);
object remove(int index);
ListIterator listIterator();
ListIterator listIterator(int i);

ListIterator Interface:
ListIterator Interface is used to traverse the element in backward and forward direction.

Commonly used methods of ListIterator Interface:


1.
2.
3.
4.

public
public
public
public

boolean hasNext();
Object next();
boolean hasPrevious();
Object previous();

Example of ListIterator Interface:


1. import java.util.*;
2. public class TestCollection8{
3. public static void main(String args[]){

243
4.
5. ArrayList<String> al=new ArrayList<String>();
6. al.add("Amit");
7. al.add("Vijay");
8. al.add("Kumar");
9. al.add(1,"Sachin");
10.
11. System.out.println("element at 2nd position: "+al.get(2));
12.
13. ListIterator<String> itr=al.listIterator();
14.
15. System.out.println("traversing elements in forward direction...");
16. while(itr.hasNext()){
17. System.out.println(itr.next());
18. }
19.
20.
21. System.out.println("traversing elements in backward direction...");
22. while(itr.hasPrevious()){
23. System.out.println(itr.previous());
24. }
25. }
26. }
Test it Now
Output:element at 2nd position: Vijay
traversing elements in forward direction...
Amit
Sachin
Vijay
Kumar
traversing elements in backward direction...
Kumar
Vijay
Sachin
Amit

Difference between List and Set:


List can contain duplicate elements whereas Set contains unique elements only.

244

HashSet class:

uses hashtable to store the elements.It extends AbstractSet class and implements
Set interface.
contains unique elements only.

Hierarchy of HashSet class:

Example of HashSet class:


1. import java.util.*;
2. class TestCollection9{
3. public static void main(String args[]){
4.
5.
HashSet<String> al=new HashSet<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ravi");
9.
al.add("Ajay");
10.
11. Iterator<String> itr=al.iterator();
12. while(itr.hasNext()){
13. System.out.println(itr.next());
14. }
15. }

245
16. }
Test it Now
Output:Ajay
Vijay
Ravi

LinkedHashSet class:

contains unique elements only like HashSet. It extends HashSet class and
implements Set interface.
maintains insertion order.

Hierarchy of LinkedHashSet class:

246

Example of LinkedHashSet class:


1. import java.util.*;
2. class TestCollection10{
3. public static void main(String args[]){
4.
5.
LinkedHashSet<String> al=new LinkedHashSet<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ravi");
9.
al.add("Ajay");
10.
11. Iterator<String> itr=al.iterator();
12. while(itr.hasNext()){
13. System.out.println(itr.next());
14. }
15. }
16. }
Test it Now
Output:>Ravi
Vijay
Ajay

TreeSet class:

contains unique elements only like HashSet. The TreeSet class implements
NavigableSet interface that extends the SortedSet interface.
maintains ascending order.

Hierarchy of TreeSet class:

247

Example of TreeSet class:


1. import java.util.*;
2. class TestCollection11{
3. public static void main(String args[]){
4.
5.
TreeSet<String> al=new TreeSet<String>();
6.
al.add("Ravi");
7.
al.add("Vijay");
8.
al.add("Ravi");
9.
al.add("Ajay");
10.
11. Iterator<String> itr=al.iterator();
12. while(itr.hasNext()){
13. System.out.println(itr.next());
14. }
15. }
16. }
Test it Now
Output:Ajay
Ravi

248

Vijay

Queue Interface:
The Queue interface basically orders the element in FIFO(First In First Out)manner.

Methods of Queue Interface :


1.
2.
3.
4.
5.
6.

public
public
public
public
public
public

boolean add(object);
boolean offer(object);
remove();
poll();
element();
peek();

PriorityQueue class:
The PriorityQueue class provides the facility of using queue. But it does not orders the
elements in FIFO manner.

Example of PriorityQueue:
1. import java.util.*;
2. class TestCollection12{
3. public static void main(String args[]){
4.
5. PriorityQueue<String> queue=new PriorityQueue<String>();
6. queue.add("Amit");
7. queue.add("Vijay");
8. queue.add("Karan");
9. queue.add("Jai");
10. queue.add("Rahul");
11.
12. System.out.println("head:"+queue.element());
13. System.out.println("head:"+queue.peek());
14.
15. System.out.println("iterating the queue elements:");
16. Iterator itr=queue.iterator();
17. while(itr.hasNext()){
18. System.out.println(itr.next());
19. }
20.
21. queue.remove();
22. queue.poll();
23.
24. System.out.println("after removing two elements:");

249
25. Iterator<String> itr2=queue.iterator();
26. while(itr2.hasNext()){
27. System.out.println(itr2.next());
28. }
29.
30. }
31. }
Test it Now
Output:head:Amit
head:Amit
iterating the queue elements:
Amit
Jai
Karan
Vijay
Rahul
after removing two elements:
Karan
Rahul
Vijay

5 Steps to connect to the database in java


1. 5 Steps to connect to the database in java
1. Register the driver class
2. Create the connection object
3. Create the Statement object
4. Execute the query
5. Close the connection object
There are 5 steps to connect any java application with the database in java using JDBC.
They are as follows:

Register the driver class


Creating connection
Creating statement
Executing queries
Closing connection

250

1) Register the driver class


The forName() method of Class class is used to register the driver class. This method is
used to dynamically load the driver class.

Syntax of forName() method


1. public static void forName(String className)throws ClassNotFoundException

Example to register the OracleDriver class


1. Class.forName("oracle.jdbc.driver.OracleDriver");

2) Create the connection object


The getConnection() method of DriverManager class is used to establish connection with
the database.

Syntax of getConnection() method


1. 1) public static Connection getConnection(String url)throws SQLException
2. 2) public static Connection getConnection(String url,String name,String password)
3. throws SQLException

Example to establish connection with the Oracle database


1. Connection con=DriverManager.getConnection(
2. "jdbc:oracle:thin:@localhost:1521:xe","system","password");

3) Create the Statement object


The createStatement() method of Connection interface is used to create statement. The
object of statement is responsible to execute queries with the database.

Syntax of createStatement() method


1. public Statement createStatement()throws SQLException

Example to create the statement object


1. Statement stmt=con.createStatement();

4) Execute the query


The executeQuery() method of Statement interface is used to execute queries to the
database. This method returns the object of ResultSet that can be used to get all the

251

records of a table.

Syntax of executeQuery() method


1. public ResultSet executeQuery(String sql)throws SQLException

Example to execute query


1.
2.
3.
4.
5.

ResultSet rs=stmt.executeQuery("select * from emp");


while(rs.next()){
System.out.println(rs.getInt(1)+" "+rs.getString(2));
}

5) Close the connection object


By closing connection object statement and ResultSet will be closed automatically. The
close() method of Connection interface is used to close the connection.

Syntax of close() method


1. public void close()throws SQLException

Example to close connection


1. con.close();

Example to connect to the Oracle database


For connecting java application with the oracle database, you need to follow 5 steps to
perform database connectivity. In this example we are using Oracle10g as the database.
So we need to know following informations for the oracle database:
1. Driver class: The driver class for the oracle database
is oracle.jdbc.driver.OracleDriver.
2. Connection URL: The connection URL for the oracle10G database
is jdbc:oracle:thin:@localhost:1521:xe where jdbc is the API, oracle is the
database, thin is the driver, localhost is the server name on which oracle is
running, we may also use IP address, 1521 is the port number and XE is the
Oracle service name. You may get all these informations from the tnsnames.ora
file.
3. Username: The default username for the oracle database is system.
4. Password: Password is given by the user at the time of installing the oracle
database.

252

Let's first create a table in oracle database.


1. create table emp(id number(10),name varchar2(40),age number(3));

Example to Connect Java Application with Oracle database


In this example, system is the username and oracle is the password of the Oracle database.
1. import java.sql.*;
2. class OracleCon{
3. public static void main(String args[]){
4. try{
5. //step1 load the driver class
6. Class.forName("oracle.jdbc.driver.OracleDriver");
7.
8. //step2 create the connection object
9. Connection con=DriverManager.getConnection(
10. "jdbc:oracle:thin:@localhost:1521:xe","system","oracle");
11.
12. //step3 create the statement object
13. Statement stmt=con.createStatement();
14.
15. //step4 execute query
16. ResultSet rs=stmt.executeQuery("select * from emp");
17. while(rs.next())
18. System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
19.
20. //step5 close the connection object
21. con.close();
22.
23. }catch(Exception e){ System.out.println(e);}
24.
25. }
26. }

download this example


The above example will fetch all the records of emp table.

To connect java application with the Oracle database ojdbc14.jar file is required to be
loaded.

download the jar file ojdbc14.jar

253

Two ways to load the jar file:


1. paste the ojdbc14.jar file in jre/lib/ext folder
2. set classpath

1) paste the ojdbc14.jar file in JRE/lib/ext folder:


Firstly, search the ojdbc14.jar file then go to JRE/lib/ext folder and paste the jar file
here.

2) set classpath:
There are two ways to set the classpath:

temporary
permanent

How to set the temporary classpath:


Firstly, search the ojdbc14.jar file then open command prompt and write:
1. C:>set classpath=c:\folder\ojdbc14.jar;.;

How to set the permanent classpath:


Go to environment variable then click on new tab. In variable name write classpath and
in variable value paste the path to ojdbc14.jar by appending ojdbc14.jar;.; as
C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar;.;
To see the slides of seting parmanent path click here

Example to connect to the mysql database


For connecting java application with the mysql database, you need to follow 5 steps to
perform database connectivity.
In this example we are using MySql as the database. So we need to know following
informations for the mysql database:
1. Driver class: The driver class for the mysql database is com.mysql.jdbc.Driver.
2. Connection URL: The connection URL for the mysql database
is jdbc:mysql://localhost:3306/sonoo where jdbc is the API, mysql is the
database, localhost is the server name on which mysql is running, we may also use
IP address, 3306 is the port number and sonoo is the database name. We may use
any database, in such case, you need to replace the sonoo with your database name.

254
3. Username: The default username for the mysql database is root.
4. Password: Password is given by the user at the time of installing the mysql
database. In this example, we are going to use root as the password.
Let's first create a table in the mysql database, but before creating table, we need to create
database first.
1. create database sonoo;
2. use sonoo;
3. create table emp(id int(10),name varchar(40),age int(3));

Example to Connect Java Application with mysql database


In this example, sonoo is the database name, root is the username and password.
1. import java.sql.*;
2. class MysqlCon{
3. public static void main(String args[]){
4. try{
5. Class.forName("com.mysql.jdbc.Driver");
6.
7. Connection con=DriverManager.getConnection(
8. "jdbc:mysql://localhost:3306/sonoo","root","root");
9.
10. //here sonoo is database name, root is username and password
11.
12. Statement stmt=con.createStatement();
13.
14. ResultSet rs=stmt.executeQuery("select * from emp");
15.
16. while(rs.next())
17. System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
18.
19. con.close();
20.
21. }catch(Exception e){ System.out.println(e);}
22.
23. }
24. }

download this example


The above example will fetch all the records of emp table.

255

To connect java application with the mysql database mysqlconnector.jar file is required to
be loaded.

download the jar file mysql-connector.jar

Two ways to load the jar file:


1. paste the mysqlconnector.jar file in jre/lib/ext folder
2. set classpath

1) paste the mysqlconnector.jar file in JRE/lib/ext folder:


Download the mysqlconnector.jar file. Go to jre/lib/ext folder and paste the jar file here.

2) set classpath:
There are two ways to set the classpath:

temporary
permament

How to set the temporary classpath


open comman prompt and write:
1. C:>set classpath=c:\folder\mysql-connector-java-5.0.8-bin.jar;.;

How to set the permanent classpath


Go to environment variable then click on new tab. In variable name write classpath and in
variable value paste the path to the mysqlconnector.jar file by appending
mysqlconnector.jar;.; as C:\folder\mysql-connector-java-5.0.8-bin.jar;.;

Enum
An enum is a data type which contains fixed set of constants. It can be used for days of the
week (SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY and SATURDAY) ,
directions (NORTH, SOUTH, EAST and WEST) etc. The enum constants are static and final
implicitely. It is available from Java 5. Enums can be thought of as classes that have fixed
set of constants.

Points to remember for Enum:

256
1.
2.
3.
4.
5.

enum improves type safety


enum can be easily used in switch
enum can be traversed
enum can have fields, constructors and methods
enum may implement many interfaces but cannot extend any class because it
internally extends Enum class

Simple Example of enum in java:


1.
2. class EnumExample1{
3.
4. public enum Season { WINTER, SPRING, SUMMER, FALL }
5.
6. public static void main(String[] args) {
7. for (Season s : Season.values())
8. System.out.println(s);
9.
10. }}
11.
Test it Now
Output:WINTER
SPRING
SUMMER
FALL

download this enum example

What is the purpose of values() method in enum?


The java compiler internally adds the values() method when it creates an enum. The
values() method returns an array containing all the values of the enum.

Internal code generated by the compiler for the above example of


enum type
The java compiler internally creates a static and final class that extends the Enum class as
shown in the below example:
1. public static final class EnumExample1$Season extends Enum
2. {
3.
private EnumExample1$Season(String s, int i)

257
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35. }

{
super(s, i);
}
public static EnumExample1$Season[] values()
{
return (EnumExample1$Season[])$VALUES.clone();
}
public static EnumExample1$Season valueOf(String s)
{
return (EnumExample1$Season)Enum.valueOf(EnumExample1$Season, s);
}
public static final EnumExample1$Season WINTER;
public static final EnumExample1$Season SPRING;
public static final EnumExample1$Season SUMMER;
public static final EnumExample1$Season FALL;
private static final EnumExample1$Season $VALUES[];
static
{
WINTER = new EnumExample1$Season("WINTER", 0);
SPRING = new EnumExample1$Season("SPRING", 1);
SUMMER = new EnumExample1$Season("SUMMER", 2);
FALL = new EnumExample1$Season("FALL", 3);
$VALUES = (new EnumExample1$Season[] {
WINTER, SPRING, SUMMER, FALL
});
}

Defining enum:
The enum can be defined within or outside the class because it is similar to a class.

Example of enum that is defined outside the class:


1.
2. enum Season { WINTER, SPRING, SUMMER, FALL }
3.
4. class EnumExample2{
5. public static void main(String[] args) {
6.
7. Season s=Season.WINTER;
8. System.out.println(s);
9.
10. }}
11.
Test it Now

258

Output:WINTER

Example of enum that is defined within the class:


1.
2.
3.
4.
5.
6.
7.
8.
9.

class EnumExample3{
enum Season { WINTER, SPRING, SUMMER, FALL; }//semicolon(;) is optional here
public static void main(String[] args) {
Season s=Season.WINTER;//enum type is required to access WINTER
System.out.println(s);
}}
Test it Now
Output:WINTER

Initializing specific value to the enum constants:


The enum constants have initial value that starts from 0, 1, 2, 3 and so on. But we can
initialize the specific value to the enum constants by defining fields and constructors. As
specified earlier, Enum can have fields, constructors and methods.

Example of specifying initial value to the enum constants


1. class EnumExample4{
2. enum Season{
3. WINTER(5), SPRING(10), SUMMER(15), FALL(20);
4.
5. private int value;
6. private Season(int value){
7. this.value=value;
8. }
9. }
10. public static void main(String args[]){
11. for (Season s : Season.values())
12. System.out.println(s+" "+s.value);
13.
14. }}
15.
Test it Now

download this enum example


Output:WINTER 5
SPRING 10
SUMMER 15
FALL 20

259

Constructor of enum type is private if you don't declare private compiler


internally have private constructor
1.
2.
3.
4.
5.
6.
7.
8.

enum Season{
WINTER(10),SUMMER(20);
private int value;
Season(int value){
this.value=value;
}
}

Internal code generated by the compiler for the above example of


enum type
1. final class Season extends Enum
2. {
3.
4.
public static Season[] values()
5.
{
6.
return (Season[])$VALUES.clone();
7.
}
8.
9.
public static Season valueOf(String s)
10.
{
11.
return (Season)Enum.valueOf(Season, s);
12.
}
13.
14.
private Season(String s, int i, int j)
15.
{
16.
super(s, i);
17.
value = j;
18.
}
19.
20.
public static final Season WINTER;
21.
public static final Season SUMMER;
22.
private int value;
23.
private static final Season $VALUES[];
24.
25.
static
26.
{
27.
WINTER = new Season("WINTER", 0, 10);
28.
SUMMER = new Season("SUMMER", 1, 20);
29.
$VALUES = (new Season[] {
30.
WINTER, SUMMER
31.
});
32.
}
33. }

260

Can we create the instance of enum by new keyword?


No, because it contains private constructors only.

Can we have abstract method in enum?


Yes, ofcourse! we can have abstract methods and can provide the implementation of these
methods.

Applying enum on switch statement


We can apply enum on switch statement as in the given example:

Example of applying enum on switch statement


1. class EnumExample5{
2. enum Day{ SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
3.
4. public static void main(String args[]){
5.
6. Day day=Day.MONDAY;
7.
8. switch(day){
9. case SUNDAY:
10. System.out.println("sunday");
11. break;
12. case MONDAY:
13. System.out.println("monday");
14. break;
15. default:
16. System.out.println("other day");
17. }
18.
19. }}
20.
Test it Now

download this enum example


Output:monday

Java Annotations

261

Java Annotation is a tag that represents the metadata i.e. attached with class, interface,
methods or fields to indicate some additional information which can be used by java
compiler and JVM.
Annotations in java are used to provide additional information, so it is an alternative option
for XML and java marker interfaces.
First, we will learn some built-in annotations then we will move on creating and using
custom annotations.

Built-In Java Annotations


There are several built-in annotations in java. Some annotations are applied to java code
and some to other annotations.

Built-In Java Annotations used in java code

@Override
@SuppressWarnings
@Deprecated

Built-In Java Annotations used in other annotations

@Target
@Retention
@Inherited
@Documented

Understanding Built-In Annotations in java


Let's understand the built-in annotations first.

@Override
@Override annotation assures that the subclass method is overriding the parent class
method. If it is not so, compile time error occurs.

262

Sometimes, we does the silly mistake such as spelling mistakes etc. So, it is better to mark
@Override annotation that provides assurity that method is overridden.
1. class Animal{
2. void eatSomething(){System.out.println("eating something");}
3. }
4.
5. class Dog extends Animal{
6. @Override
7. void eatsomething(){System.out.println("eating foods");}//should be eatSomething
8. }
9.
10. class TestAnnotation1{
11. public static void main(String args[]){
12. Animal a=new Dog();
13. a.eatSomething();
14. }}
Test it Now
Output:Comple Time Error

@SuppressWarnings
@SuppressWarnings annotation: is used to suppress warnings issued by the compiler.
1. import java.util.*;
2. class TestAnnotation2{
3. @SuppressWarnings("unchecked")
4. public static void main(String args[]){
5.
6. ArrayList<String> list=new ArrayList<String>();
7. list.add("sonoo");
8. list.add("vimal");
9. list.add("ratan");
10.
11. for(Object obj:list)
12. System.out.println(obj);
13.
14. }}
Test it Now
Now no warning at compile time.
If you remove the @SuppressWarnings("unchecked") annotation, it will show warning at
compile time because we are using non-generic collection.

263

@Deprecated
@Deprecated annoation marks that this method is deprecated so compiler prints warning. It
informs user that it may be removed in the future versions. So, it is better not to use such
methods.
1. class A{
2. void m(){System.out.println("hello m");}
3.
4. @Deprecated
5. void n(){System.out.println("hello n");}
6. }
7.
8. class TestAnnotation3{
9. public static void main(String args[]){
10.
11. A a=new A();
12. a.n();
13. }}
Test it Now

At Compile Time:
Note: Test.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

At Runtime:
hello n

Custom Annotation
To create and use custom java annotation, visit the next page.

264

The Hello World Program


Java is an object oriented programming language. We write classes and build objects out of
them. A class is a blueprint or a representation of an object. It is an entity that doesn't really
exist while objects are those that exist in the memory of a computer. For example, a
drawing of a car on a paper might be considered to be a class and cars built of them are
objects. All objects built out of the same class are similar in the way that they possess the
same set of properties but these properties have different values for each of the object just
like a car having a colour which is different for each of the cars. And we have some
methods as a part of the class which are used to perform specific tasks. And above all, we
have constructors which are used to initialise the properties i.e. variables while creating an
object. Programming in java therefore revolves around classes which consist of
constructors, variables (also known as instance variables since each instances of the class
has its own copy of these variables) and methods (also known as functions). A class may
contain all of these three entities or one or more of them as per the requirement. We then
write test classes in which we create objects from the classes. However, when we write
simple programs as we would be doing now, we don't think of programming in an object
oriented way. We write a class, having a single method, 'main' which will be executed when
the
program
is
run.
Let's get started with our first program in which we print a single line of text "Hello World" on
the computer screen.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
This class (or program) written by us has a single method named main and does not consist
of any variables or constructors. The first line of the program declares the class which we
have named HelloWorld. You may use any name according to what the program does. The
naming of the programming serves as a means to identify the class and should reflect the
purpose of the class. For example, a class written to represent a car should be named as
'Car'
rather
than
as
'Book'.
The class declaration starts with the word public. It is an access specifier about which we
would look into later on. In addition to public, there are two other access specifiers, private
and protected. The next word is 'class' which is used to declare a class. The next word
'HelloWorld' is a name for our class. We can use any name but it needs to follow the rules

265

of naming identifiers. Class names, method names and variable names are known as
identifiers. They serve the purpose of representing elements in our program. When those
elements
are
required,
we
refer
to
them
by
their
names.
Following

are

the

rules

to

be

followed

while

naming

identifiers:

1. Identifiers may contain uppercase letters A-Z, lowercase letters a-z and the digits 0-9
2. The only allowed special characters are dollar $ and underscore _
3.
An
identifier
should
not
begin
with
a
number
4.
Spaces
should
not
be
used
5.
Keywords
cannot
be
used
as
identifiers
Keywords are reserved words in a programming language. They have special meanings.
The keywords which we have come across till now are 'public' and 'class'.
Next, we see an open brace { and its corresponding closing brace } can be seen in the last
line. Braces group things together. The braces here indicate that all of the code that
appears
within
it
is
a
part
of
the
class
HelloWorld.
Next we have the method declaration for the method 'main'. Every program which needs to
be run should have a main method. However, if a class is meant only to be used in other
programs and has no need to be run, it need not have a main method.
Just like a class declaration, a method declaration also has several parts. The first is the
keyword 'public', which is an access specifier. The next word 'static' is a keyword which is
used to tell that this method is accessible without creating an object of this class. That is the
reason why this particular method (main) is invoked directly when we run the program even
without creating an object. The next keyword is 'void'. Void states that this method does not
return any value. We shall see more about it later on. The next word 'main' is an identifier.
Just as we have named our class as HelloWorld, we have named our method as main. We
can use any name for a method, but if it is the one to be invoked when the program is run, it
should always be named as main with the specifiers public, static and void. Next we have a
pair of parentheses in which 'String args []' is written. 'String [] args' can also be written as
'String args []'. The square brackets can be placed either after the word String or the word
args. These are known as parameters. We shall look into them later on. Here again, we
have a pair of braces. These again indicate that the code that follows is a part of the method
main.
In this method, we have a single statement. Note that all statements in Java are terminated
by a semicolon. However, class and method declarations are not. This statement is used for
printing on the screen. System is a predefined class just like our HelloWorld class. 'out' is a

266

variable in that class which stores an object. Variables store information which can also be
objects. And print is a method of that class just like the method main in this class. Note that
a dot is used to refer to elements in a sequence just as a / separates the different parts in a
URL. We have accessed the member out of the class System without creating an object.
The reason is that out is defined as a static member. We shall see later on how objects are
created. And to invoke a method, we follow the method name by parentheses and the
required parameters are passed in it. Parameters are those values which are required by
the method to perform its task. The method println () prints something on the screen but it
needs to know what exactly it needs to print. This is passed as a parameter. Note that the
sentence which we pass should be enclosed in double quotes. This is known as a String - a
sequence
of
characters.
When we run this program, the text "Hello World" is displayed on the screen. Change "Hello
World!" in the program to something else and it will be displayed on the screen.
So, in conclusion, when we wish to write a program, its structure should look in the following
way:
public class <class name> {
public static void main(String[] args) {
<statements>
}
}
Replace <class name> with the name that you wish to give to your program or class and
replace statements with those required to perform the task. Everything else remains the
same for simple and small programs. At this point of time, it would be helpful to know a few
things. The first is that Java is a case sensitive language. Uppercase and lowercase letters
are different. Change public in the first line of the program to Public and compile the
program. You will be receiving compilation errors. There is no need to panic about
remembering the case in which different parts of the program are to be written. All keywords
are written in lower case and identifiers such as System (a predefined class) follow certain
conventions
which
we
shall
see
later
on.
And another thing is that Java is a free form language. You can write your program in as
many lines as you want. For example you could have written the first line of the program as
public
class
HelloWorld
{

267

The program still works! However, you can't split single words. For example, you can't write
'cla' on one line and 'ss' on the second line in the following way and expect the program to
compile.
cla
ss
We can state a simple rule that in place of a single space, we can insert as many spaces or
even a new line. And moreover, we can insert spaces and new lines before and after
separators. We have the following separators in Java . , ; { } [ ] ( )
We could have written the System.out.println() statement as:
System
.
out .
println (
"Hello World!";
)
;
However, here again "Hello World!" should be written on a single line. Strings in Java
should begin and end on the same line.

Variables and Data Types


Programs are often required to store information. For example, to write a program that adds
two numbers, we need to store the first number, the second number and the result. This is
accomplished by the use of variables. Variables represent memory area where the
information is stored. Following is the physical representation of a variable:

268

A variable has a name, a value and a data type. A variable name is a symbolic
representation of the memory area in which the information would be stored. The value is
the actual data that is going to be stored. And a particular variable can only store one type
of information. It could either be an integer, a real number, a single character or a String.
This
is
specified
by
the
data
type.
In our example, we have a variable named firstNumber of type int and having a value 3. The
data type int is used to store integer values i.e. positive numbers, zero or negative
numbers.
In java we have primitive and reference data types. Primitive data types are the basic data
types which are not composed of any other data types while reference data types are those
which are composed of other data types. Reference data types may be classes or arrays.
We have already seen what a class is. We shall see later on how to create object from
these classes and assign their reference to a variable. Arrays are used to store groups of
data all of which have the same data type. We shall see more about arrays in a dedicated
chapter later on. The term reference also has the implication of being passed by reference,
which
too
which
be
looked
at
in
a
later
chapter.
For now, we will learn about the primitive data types. Java has eight primitive data types,
each of which is capable of storing a particular kind of information. In addition, each of them
also has a range of values which can be stored. Values outside this range cannot be stored
in a variable of that particular data type. The different data types, the amount of memory
required by them and the range of values which can be stored are specified in the table
below.
Data
type

Size in bits

Range (inclusive of both values)

Range ( in exponential
notation)

byte

- 128 to 127

- 27 to 27-1

short

16

- 32 768 to 32 767

- 215 to 215 -1

int

32

- 2 147 483 648 to 2 147 483 647

- 231 to 231 -1

long

64

- 9 223 372 036 854 775 808 to 9 223 372 036


854 775 807

- 263 to 263 -1

float

32

-3.4*10-38 to 3.4*1038

double

64

-1.7*10-308 to 1.7*10308

char

16

0 to 65536

boolean

Not properly
defined

true and false

We generally use the int data type for storing integers, the double data type for storing real

269

numbers which have a decimal or a fractional part, the boolean data type is used if the
stored values can be either true or false, yes or no, 0 or 1 and other similar pairs and finally
the char data type is used to store a single character.

Declaring, initialization and assignment


Before we use a variable in a program, it needs to be declared by specifying the data type
and name. Then, we may give a value to its which is known as initialisation. When we give
a value to it the subsequent time after the first time, it is known as assignment. Initialisation
and assignment are similar except that initialisation is done the first time and assignment
the
subsequent
time.
Both
of
them
have
the
same
syntax.
Following is the syntax for declaring a variable:
< Data type > < variable name >;
And a variable is either initialized or assigned in the following way:
< Variable name > = < value >;
We may combine the declaration and initialisation of a variable in the following way:
< Data type > < variable name > = < value >;
Now, going back to our example of adding two numbers, we need three variables- the first
two to store the two numbers that are to be added and the third to store the result. Let us
name these variables as firstNumber, secondNumber and result. Variable names should
follow the rules of identifiers. The following statements declare these three variables.
int firstNumber;
int secondNumber;
int result;
When we declare more than one variable of the same type, the declarations can be
combined into a single statement separating the variable names using a comma as shown
below.
int firstNumber, secondNumber, result;
And the next thing to be done is to initialise these variables. Let us initialise the numbers to
3 and 4. The following statement initialises firstNumber with 3.
firstNumber = 3;

270

The equal to sign ( = ) is known as the assignment operator. It assigns the value on the
right to a variable on the left. In this case, the value on the right, 3 is assigned to the
variable firstNumber which is stated on the left. The right hand side can also be an
expression. We will look at expressions shortly when dealing with the variable result. Now,
the variable secondNumber is initialised in the following way.
secondNumber = 4;
As already said, declaration and initialisation may be combined in the following way.
int firstNumber = 3; int secondNumber = 4;
Further, we may combine the declaration and initialisation of these three variables into a
single statement as all the three variables have the same data type.
int firstNumber = 3 , secondNumber = 4 , result;
It is to be noted that a variable cannot be declared more than once. If done so, a
compilation error would occur. Also, a variable can't be initialised without first declaring it.
Next, we need to assign the sum of the two numbers to the variable result. Here again, we
assign the result in the same way as we have done for the two numbers. But here, we do
not assign a number such as 3 or 4 but instead we add the two numbers. This results in an
expression. An expression is a combination of operators and operands. Operators are of
different types but for now, we shall be concerned about the mathematical operators +, -, * ,
/ and %. These have the same meaning as in mathematics. The last operator % is known
as the modulus operator which is used to find the remainder when dividing two numbers.
So, the statement for assigning a value to result would like
result = firstNumber + secondNumber ;
This initialisation could be combined with variable declaration in the following way.
int result = firstNumber + secondNumber ;
We could have done this assignment along with the assignment for firstNumber and
secondNumber in the following way but this isn't recommended.
int firstNumber = 3 , secondNumber = 4 , result= firstNumber + secondNumber;
It is always suggested that direct initialisation of variables be separated from the ones
where computation is required. And further, list all variables be listed on separate lines and
not grouped as shown above. Though either of the two ways is correct, we should try to
make
the
code
more
readable.

271

Lastly we need to print the result. For this, we use the println() statement in the following
way.
System.out.println ( "The result of adding "+ firstNumber + " and "+ secondNumber + " is "+
result );
Here, the plus sign acts as a concatenation operator. Concatenation refers to joining two
things. Here, we have joined different Strings and the variables. Wherever, the variable
name appears, it is substituted by its value. So firstNumber would be replaced with 3,
secondNumber by 4 and result by 7. Therefore, the following statement would be printed on
the screen.
The result of adding 3 and 4 is 7
Now, here is the final program for addition.
public class Addition {
public static void main (String args[] ) {
int firstNumber = 3;
int secondNumber = 4;
int result = firstNumber + secondNumber ;
System.out.println ( "The result of adding "+ firstNumber + " and "+ secondNumber + " is
"+ result );
}
}

More about Data Types


Here, we will discuss more about the data types we have seen in the previous article.

Storing integers
In the previous example, we have used the int data type to store integers. We may also use
the byte, short and the long data types to store integers depending on the maximum or the
minimum values that are going to be stored. Following statements initialise four variables of
different data tapes with integer values.
byte b = 3;
short c = 4;
int a = 34;
long d = 7L;

272

There is a need to mention how long integers are assigned to variables. An uppercase l or a
lowercase L should be appended to the end of the integer that is going to be stored. This is
because all integers are assumed to be of type int, unless specified as long. However, we
did not append anything to a byte or a short integer. This is because of implicit casting.
Casting refers to converting from one data type to another. 3 was automatically casted from
int to byte and similar was the case with short. In the case of long integers, we need the l to
specify that it is a long integer. if we omit the L at the end of 7 and compile the program, no
compilation errors would be generated. Now, change the value of 7 to something that can
be stored in a long variable but not an int variable and see what happens. A compilation
errors is generated!
long d = 10147483648;
This happens because, the number on the right is too big for an int. Whenever an integers
value if encountered in a program, it is considered as an int value. In the case of byte and
short, the numbers 3 and 4 are initially considered to be of type int but since they are
assigned to some other data type, they have been implicitly cast into byte and short
respectively. In the case of the long integer ( 7L ), we have specified that 7 is a long integer
using the letter L. This long integer was assigned to a long variable. If we had written 'long d
= 7;', the integer 7 is first taken as an int and then implicitly cast to long. In the case of the
number 10147483648, it is initially taken as an int value. But since 10147483648 is too long
for
an
int,
a
compilation
error
occurs.
When we wish to store the result of an expression in a byte or short, the result needs to be
explicitly cast to the corresponding data type. Following is the syntax for casting
( data type ) < variable, literal, or expression >
For example
byte a = 3;
byte b = 4;
byte c = ( byte ) ( a+b );
Note that a+b is written within parentheses. This is because, cast is applied on the variable,
or a literal immediately following the cast data type. To apply it on an expression, the
parentheses is required. ( A literal is a constant data item unlike a variable, such as 3 or 4).
In an arithmetic expression, bytes and shorts are converted to ints before performing any
operation using theose values. Therfore, a and b was first implicitly converted to an int, the
resulting int should be explictly cast to a byte.

Storing real numbers

273

Real numbers are those which have a fractional part i.e. a decimal part. Real numbers are
also known as floating point numbers. All real numbers are assumed to be of type double by
default. To store a real number in a float variable, an uppercase F or a lowercase f needs to
be appended at the end of the number.
float a = 3.4f;
float b = 34.7F;
double c = 64.7;
We generally use the double data type and not float. We may also represent the numbers in
exponential notation. A number A*10B is written is exponential notation as AeB or AEB.
Either an uppercase e or a lowercase E may be used. The number A is called the mantissa
and the number B is called the exponent. Both of them may be either positive or negative.
The following three statements are equivalent.
double a = 347.347;
double a = 3.47347E2;
double a = 3.47347e2;

boolean data type


A boolean data type can hold only two values- true or false. Following lines show example
usages.
boolean a = true;
boolean b = false;

The char data type


The char data type is used to store a single character such as 'a', 'Z', '9', '&', '$' and so on.
Character can be letters, digits or special symbols. A character can also be a non graphic
symbol such as a new line or a tab. Characters are always enclosed in single quotes. If we
wish to store the value 'A' in a variable x, we would write the following statement.
char x = 'A';
We can use a different variable name instead of x. for example, we could have used the
variable name 'firstChar' and written the statement as
char firstChar = 'A';
There is another way to initialise a character variable. We can assign the numbers between
0 and 65,536 ( both inclusive) to a char variable. Each of these numbers corresponds to a

274

particular variable. For example, the number 65 corresponds to uppercase A. so, the
following statement is equivalent to the above declaration.
char x = 65;
Note that we do not enclose these numbers in single quotes. This correspondence between
a number code and the graphic character is given by the Unicode. A small subset of these
codes is the ASCII codes which contains numbers between 0 and 127 ( both inclusive) the
ASCII
contains
the
most
commonly
used
symbols.
Following is a list of some of the most commonly used characters and their numeric
representation in either the Unicode or the ASCII code.
Characters

ASCII / Unicode

0-9

48 - 57

a-z

97 - 122

A-Z

65 - 90

Therefore, the number 67 corresponds to 'C', 48 to '0', 49 to '1'and so on.

The String data type


We also quite often use the String adapt type to store a word or sentence. String is a
reference data type and not a primitive data type. String is a class and the sentences are
the objects of that class. Strings are enclosed in double quotes. Following statements
shows the usage of the String data type.
String s ="Java is an object oriented programming language.";
The concatenation operator + may be used in Strings. Following shows an example.
int a = 3;
String str = "The value of a is " + a;
str now stores the String "The value of a is 3"

Displaying Information using print() and println() Methods


We have already seen how the println() method is used to print text on the screen. In
addition to the println() method, we have the print() and the format() methods which are
used for displaying data. The print() method is similar to the println() statement while the
format() method is something different.

275

Difference between print() and println()


The only difference between the print() and println() methods is that the println() statement
positions the cursor onto the next line after printing the desired text while the print() method
leaves the cursor on the same line. The difference is evident when we print text using more
than a single statement. The following statements use the print() method.
System.out.print("Hello ");
System.out.print("World ");
The output of these statements would be:
Hello World
After printing the word 'Hello', the cursor remained on the same line. That is why 'World'
was also displayed on the same line. If we use the println() statement, the output would be
different.
System.out.println("Hello ");
System.out.println("World ");
The output would be
Hello
World
After printing the word 'Hello', the cursor moved to the next line. That is why the word
'World' was printed on a new line.

Concatenation using + operator


We can use the concatenation operator + to join two or more Strings and print them. To
print the value of a variable, we simply state it within the parentheses. Look at the following
code for example:
int a=1;
String s = "World";
System.out.println(a+" "+"Hello "+s+"!");
The output would be
1 Hello World!
The expression within the parentheses is evaluated from left to right and particular care has
to be taken when including variables that store integers, real numbers and characters.

276

Including integers and real numbers in print statements


The order in which these variables that store integers and real numbers occur along with
the Strings can decide whether the integers would be printed directly or if they would be
added together with integers and then printed. When a String is added to any other data
type, the resultant value is a String. The other variable is also converted to a String and
then concatenated. However, when two integers are operated with a + sign, the + acts as
an addition operator and not a concatenation operator. The variables are considered as int's
and not Strings. Parentheses may be used just as in maths to alter the order in which
evaluation is performed. If the expression within the println() or print() method contains
parentheses, then the value within the parentheses is evaluated first. Consider the following
example:
int a = 3;
int b = 4;
System.out.println( a + b );
System.out.println( "3" + "4" );
System.out.println( "" + a + b );
System.out.println( 3 + 4 + a + " " + b + a );
System.out.println( "Result: " + a + b );
System.out.println( "Result: " + ( a + b ) );
The output would be
7
34
34
10 43
Result: 34
Result: 7

Expressions within the parentheses are evaluated from left to right. In the first println()
statement, both a and b are integers. Hence, they are added together and the result 7 is
displayed. In the second statement, the Strings "3" and "4" were joined by a + sign. It is to
be noted that, here 3 and 4 are Strings and not integers. In the third line, the empty String,
represented by the opening and closing quotes is added to the integer 3. Since a String was
added to the integer 3, the resultant value is a String "3" and not the integer 3. Next this
String is added to the integer 4. Therefore, the integer 4 is converted to the String "4" and
concatenated with the String "3" to give the String "34". In the fourth statement, starting
from the left as usual, we have the integers 3, 4 and a connected with a + sign. Hence, they
are all added to give 10, an integer. Now this integer is added to a String " " giving the
String "10 "and continuing in similar manner, we get the result "10 43". In a similar way, the

277

next statement gives the answer "Result: 34". In the last statement, parentheses have been
used to alter the order in which evaluation is performed. First, the expression within the
parentheses is evaluated. Hence, a + b is evaluated to give an integer 7, which is
concatenated with the String "Result: " to give the final String "Result: 7".

Printing characters
Whenever a char variable is passed as a parameter to the print() or println() methods, the
graphic representation is printed and not the numeric value. It does matter whether we have
initialised the char with a number or with a graphic symbol.
char a=65;
char b='A';
System.out.println(a);
System.out.println(b);
The output would be
A
A
If we want the numeric representation to be printed, we need to cast the variable into one of
the four integer types.
System.out.println((int)a);
The output would be
65
When an integer is added to a char, the char is implicitly casted to an integer.
System.out.println(b+1);
The output would be
66

Using escape sequences to print new lines and tabs


We can print new lines and tabs using escape sequences. Escape sequences are a
combination of a backslash character '\' followed by one or more letters. To print a new line,
we use the escape sequence '\n' and to print a tab ( a group of spaces), we use the escape
sequence '\t'.

278

Following examples shows the use of escape sequences.


String str="Hello World!"; System.out.println (str + "\nA new line+"\t" + "Tab"+"\n" + "A new
line");
The output would be
Hello World!
A new line Tab
A new line
Note that the escape characters can also be used in Strings that would be stored in a
variable. The escape sequences are single characters which can be stored in a char
variable. However, they are generally taken as Strings in order to avoid them being
converted to integers due to logical errors. Look at the following code where a logical error
exists. The intended output is the numbers 3,4 and 7 on different lines but the actual output
was something different since the escape sequence '\n' was converted into its numeric
value 10.
int a=3,b=4,c=7;
System.out.println(a+'\n'+ b+'\n'+ c);
The output is
34
The reason is that the char '\n' was converted into its numeric value 10. The logical errors
could have been avoided if the escape sequences were considered as Strings and not
chars.
System.out.println(a+"\n"+b+"\n"+c);
The output now would be
3
4
7

Displaying text using printf() method


In addition to the print() and println() methods, the printf () method is also quite frequently
used for displaying text that needs to be formatted. Formatting here neither refers to the font
size or the font colour but is related to how data is to be displayed. For example: the
number of decimal digits to be displayed, the alignment of the String and other similar things
are related to formatting data. The printf () method requires a format String and a set of

279

other arguments whose number depends on the format String. The format String is similar
to a normal String with the exception that it contains placeholders where appropriate data
items may be placed. These place holders state the type of data that is going to be placed
and also include any other necessary formatting details such as the number of decimal
digits to be displayed, the alignment of the text and so on. For example, consider the
following two equivalent statements assuming that the variable str holds the String "Java":
System.out.println ("Welcome to "+str);
System.out.printf ("Welcome to %s", str);
Both of the above statements print the String "Welcome to Java". However, the approach
taken varies. In the first statement, we have used concatenation while in the second case,
we have achieved the same result by inserting a placeholder for a String (%s) and then
stating the String that needs to be placed in that defined area. We may specify as many
placeholders as we wish and then state their values as arguments in the same order in
which they need to be placed in the empty placeholders. The first parameter in the printf()
method call is known as the format string. And the '%s' and any other similar entities are
known as format specifiers. The digit that follows the % sign ( in this case, an s) is known as
the conversion character. Format specifiers are provided with additional information
depending on the formatting that we wish to apply. Different format specifiers are used to
print different types of text. The table below summarises the most commonly used.
Format specifier

Description

%d

Displays a decimal (base 10 ) integer

%f

Display a floating point value in decimal format

%e or %E

Display a floating point number in exponential notation

%c or %C

Display characters

%s or %S

Display Strings

%b or %B

Display boolean values

%%

Display a % sign

Therefore, to print a short, byte, int or long data item, we use the %d format specifier. To
print float and double values, we use either %f or %e depending on the requirement of
output. To print boolean, char and String data items, we use %b, %c and %s specifiers
respectively.
The following code fragment shows the usage of these specifiers.
int day = 9;
String month = "March";
int year = 1993;

280

char grade='A';
int marks=99;
System.out.format("Born on %dth %s, %d\n", day,month,year);
System.out.format("Secured %d%% marks and %c grade", marks,grade);
The output would be:
Born on 9th March, 1993
Secured 99% marks and A grade
Note how %% was used to display a % sign. If we had simply written % to display a present
sign, it would have resulted in a compilation error. This is because a % sign needs to be
followed by a valid conversion character.
When we need to display data in the form of a table, the task might become cumbersome if
we manually insert the appropriate number of spaces to align the rows properly. For this
purpose, we can use the formatting capabilities provided by this method. The length of the
area in which the text is to be printed is known as the field width. We can specify the field
width by inserting a number between the % sign and the conversion character. If the data to
be printed is smaller, then the appropriate number of spaces are inserted and the data is
right justified. To left justify the data, we place a negative sign before the number. Field
width can be specified for printing any data type.
String name1="Sai";
String name2="Gautham";
int marks1=100;
int marks2=99;
System.out.format("%-10s - %4d\n",name1,marks1);
System.out.format("%-10s - %4d\n",name2,marks2);
The output would be
Sai
- 100
Gautham - 99

Note how the Strings were left justified and the integers right justified.
We can also specify the precision of the data to be printed. Precision defines the number of
decimal digits that are to be printed when we use it with a floating point number. Precision is
specified by placing a dot (.) followed by a number indicating the required precision.
System.out.format("%.3f",34.789456);

281

The output would be


34.789
Flags call also be provided in the format String to add further formatting. In addition, we can
format dates and times.

ava comments
Classes and programs written by you are used not just by yourself but by others too. Under
such circumstances, it may happen that certain portions of the code you have written may
not be easily understandable by others. This could be an algorithm that you have used or
an approach that is part of your class design. In order to explain all such aspects to
someone reading your code, Java provides comments. Comments are sentences which are
ignored by the compiler. These comments at times may also be helpful to you too,
especially in big projects where remembering the purpose of every variable and method
might be a difficult task. Java provides three types of comments: single line comments,
multiline comments and documentation comments. We will now see how these comments
can be incorporated in our program by taking the example of our Addition program which
we have written in the beginning of this tutorial.
Single line comments, as implied by the name span over a single line. They start and end
on the same line. Two forward slashes ( // )mark the beginning of a single line comment and
a new line ( obtained by pressing the enter key) marks its end.
int firstNumber = 3; // This is the first number
Multiline comments spread over many lines. They start with /* and end with */
/* This is
a multiline
comment */
Documentation comments start with /** and end with */. These are special types of
comments which are used to document a class. The documentation of a class gives details
about its variables, constructors and methods. We shall look into documentation comments
later on. For now, we shall see how we can use single line and multiline comments to
improve the readability of our program.
/*
This class is used to add
Two numbers
*/
public class Addition {

282

public static void main (String args[] ) {


int firstNumber = 3; // the first number
int secondNumber = 4; // the second number
int result = firstNumber + secondNumber ; // the sum of two numbers
System.out.println ( "The result of adding "+ firstNumber + " and "+ secondNumber + " is
"+ result );
} // end of main method
} // end of class
As you can see in the program above, we have use single line comments to describe the
purpose of the variables and also to state what a particular curly brace correspond to. We
often use shorter variable names in programs. In order to state the purpose of the variable,
we use comments. And in lengthier programs, it becomes difficult to comprehend to what a
particular closing brace corresponds to- the closing of a method, a class or some other
block. Hence, comments are also used to mark the end of blocks. Blocks are a group of
statements within a pair of curly braces. And we have used a multiline comment in the
beginning to state the purpose of this program.
When comments appear in Strings, they are not considered as comments. Instead, they
form a part of the String itself. Look at the example program below:
public class Example {
public static void main(String[] args){
String s="Hello! // This is not a comment";
System.out.println(s);
}
}
When this program is run, we get the output as:
Hello! // This is not a comment
The comment within the String was not parsed as a comment. Rather, it was a part of the
String itself.
When Unicode characters appear in comments, they are replaced by their corresponding
graphic symbol. As we have seen already, Unicode characters are represented by numbers
between 0 and 65536. We can also represent them by a backslash character followed by a
set of characters. For example, the Unicode character '\u000a' represents a new line.
Wherever, this Unicode character appears, it is replaced by a new line and then the code is
executed. Look at the following program for example:
public class surf {
public static void main(String[] args){

283

int i=3456; // I is set to 10 \u000a System.out.println(i);


}
}
The output would be
34
The reason is that \u000a was replaced by a new line and then the code was run.

Naming Conventions for Identifiers


If you have observed every program written by us closely, you would have noticed certain
similarities in the way we have named our classes and variables. We always started our
class name with a capital letter (HelloWorld, Addition). On the contrary, we have started a
variable name with a small letter and then capitalised every subsequent word (firstNumber,
secondNumber, result). These are the naming conventions which are followed by all.
Following these conventions also makes a language simpler. If you remember, you have
been said earlier while discussing about the case sensitivity of Java that there is no need to
panic about what words are to be capitalised and what shouldn't be capitalised. You now
need not spend time thinking if 's' in System should be capitalised or not. Since it is the
name of a class, the 's' has a need to be stated in capitals. These conventions have been
followed in the pre-defined classes of Java too. These classes together form the java API.
We shall learn more about the PAI later on. For now, we shall see the conventions that are
followed
while
naming
classes,
variables
and
methods.
The starting letter of each word in a class name is capitalised. All other letters are written in
lower
case.
Examples:
Addition,
Car,
HelloWorld
Method names follow a convention similar to that of class names except that the first letter
is not capitalised. Till now, we have come across only one method- main. We shall shortly
see how we can define as many methods as we want with any name that we wish.
Examples of some method names are main, drawShape, printString, add.
Variables follow conventions similar to that of method names. However, when we use an
identifier in a class, we can easily say if it is a method name or a variable name because of
the parentheses that are placed adjacent to method name. Remember that when we had
written result in the print() statement, we haven't appended a pair of parentheses at the
end.
System.out.println ("Result:"+ result);

284

However, when we have called the print(), println() and printf() methods, we have a pair of
parentheses at the end in which we have written the arguments. Not all methods require
arguments. We shall study more about methods in detail in a later chapter.
In addition to classes, variables and methods, we also have packages, final variables and
interfaces. The naming conventions for them will be stated when we come across them in
our
study.
Note that following conventions is not mandatory. You can name your class as 'helloWorld'
or 'HellOWoRLd' and the program still works. But following the conventions makes your
program looks professional and people going through your program wouldn't face any
difficulties trying to comprehend whether a particular identifier is a variable, a class, an
interface or some other entity.

Mathematical Operations in Java


We have already seen about mathematical calculations in Java. We will now recollect them
and then look at a few other aspects which we haven't discussed earlier.
The first thing is regarding the precedence of the five mathematical operators: + - / * and %.
/, * and % have a higher precedence than + and -. In order to raise the precedence of a
particular operator, we use parentheses. The expression within the parentheses is
evaluated before evaluating the rest of the expression. The remainder of the expression is
evaluated from left to right. We have seen how the precedence of operators can be raised
in the previous example when calculating the average.
double average = ( marks1 + marks2 + marks3 ) / 3.0;
Another important thing is regarding the data type of the result of an operation including two
operators and an operand. For example, the result of an expression involving two integers
is an integers and not a double. 5/4 gives 1 and not 1.25. The following shows the data type
of the result which depends on the data types of the operands.
Data type returned

Data type of operands

double

Atleast one operand is a double

float

Atleast one operand is a float but neither operand is a double

long

Atleast one operand is a long but neither operand is a float or a double

int

Atleast one operand is an int but neither operand is a float, a double or a long

Consider that we wish to accept two numbers from the user and divide them. Suppose that

285

we store the numbers in num1 and num2, the following expression would not give us the
required output:
double result = num1 / num2;
We cannot follow the technique which we have used for the computation of average. There
is no way by which we can add a decimal point followed by a zero since we are now dealing
with two variables and not constants. The solution lies in casting to a different data type.
Casting refers to the conversion of one data type to another data type. We have already
seen how we cast data when we were discussing about mathematical operation using byte
varaibles. we cast num1 to double and perform the division in the following way.
double result = (double) num1 / num2;

Taking Input from the User


In the addition program that we have written, we have initialised the variables firstNumber
and secondNumber with 3 and 4. Wouldn't it be better if you could ask your friend to enter
his own values and then display the sum of those two numbers? There are several ways to
do it in Java. But here, we shall look at one simple way by using the Scanner class. You
may not be able to understand every line of code that we would be writing here but still at
the end, you will know how you can take different types of input- integers, real numbers,
Strings from the user just like the way you are now capable of writing simple programs like
displaying 'Hello World!' and adding two numbers even when you could not fully understand
what public, static, void and other words meant. Things would become clearer as we
proceed to other topics. For now, we shall look at the Scanner class.
As already said, Java has a number of predefined classes which we can use. These
classes are just like the HelloWorld and Addition classes that we have written but they do
not contain a main method. Instead, they have some variables, constructors and some
different methods. With the help of constructors, we instantiate (create) objects from these
classes. We can create as many objects as we want from a single class and each of them
have their own set of instance variables. And, we call the methods of these objects to
perform tasks.
These predefined classes are organised in the form of packages. For now, you can think of
a package as a simple collection of classes. Before we can use the class, we need to either
import the entire package or the class. We import the Scanner class using the following
line.
import java.util.Scanner;

286

The import statement should be the first line in our program. And then as usual we write the
code for our class or program, similar to what we have done earlier.
import java.util.Scanner;
public class Addition {
public static void main(String[] args) {
// some code here
}
}
This is the structure of a class which we are already familiar with. Now, we need to write
some code in the main method to perform the intended task. Before we write the code, let
us look at how information can be passed from the keyboard to our program using the
Scanner class.
Information flows as a stream just like the way water flows through a hose. The System
class which we have used contains two pre-defined streams. One is the output stream (out)
which is connected the console. We have used it in our earlier programs to print information
on the screen. The other stream is the input stream (in) which is by default connected to the
keyboard. We need to obtain the stream and convert the information in that stream into
meaningful data like integers and Strings. The input stream object (in) is accessed by the
statement System.in 'System', as we have already said is a predefined class and 'in' is a
variable in that class which holds a reference to an input stream object. We now use this in
object to create a Scanner object. As we have already said, to create an object from a
class, we use the constructor of that class. The constructor just like methods may require
arguments. Remember that when we have used the print() or println() methods, we have
passed String arguments like 'HelloWorld'. A Scanner constructor requires an input stream
object as an argument. Therefore we pass the in object to the Scanner constructor and
create a Scanner object named s in the following way.
Scanner s = new Scanner ( System.in );
Note that s is an identifier- a variable name just like firstNumber and secondNumber. And
therforore you can give any name that you want. The proper way to access a variable of
another class (here, in) is to refer to its name by specifying the class name followed by a dot
operator and the variable name.
The keyword new is used to create an object. We will learn more about creating objects
later on. If you have understood all that has been stated till now, it's a good thing. If you
haven't, do not bother. Simply remember that the obove statement is used to create a
Scanner object named s.

287

The Scanner class has several methods which are used to take different types of inputs.
They are listed in the table below.
Method

Description

nextByte()

Accept a byte

nextShort()

Accept a short

nextInt()

Accept an int

nextLong()

Accept a long

next()

Accept a single word

nextLine()

Accept a line of String

nextBoolean()

Accept a boolean

nextFloat()

Accept a float

nextDouble()

Accept a double

Suppose, we want to accept an integer and store it in the variable firstNumber, we write the
following statement:
int firstNumber = s.nextInt();
In a similar way, we can accept other data types from the user. The following code shows
the complete program which accepts two numbers from the user and adds them and
displays the result.
import java.util.Scanner;
public class Addition {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter first number: ");
int firstNumber = s.nextInt();
System.out.print("Enter second number: ");
int secondNumber = s.nextInt();
int sum = firstNumber + secondNumber;
System.out.println("The result of addition was " + sum);
}
}
Following shows a sample output when we enter the numbers 34 and 43 as input.
Enter first number: 34
Enter second number: 43
The result of addition was 77

288

In a similar way, you can take other data types as input.


Following program shows another example usage of the Scanner class. Here we take the
marks of a student in three subjects and display his average and his average as in done a
progress report.
import java.util.Scanner;
public class Average Marks {
public static void main(String[] args) {
Scanner s = new Scanner ( System.in);
System.out.print("Enter your name: ");
String name=s.next();
System.out.print("Enter marks in three subjects: ");
int marks1=s.nextInt();
int marks2=s.nextInt();
int marks3=s.nextInt();
double average = ( marks1+marks2+marks3)/3.0;
System.out.println("\nName: "+name);
System.out.println("Average: "+average);
}
}
There are a few things worth mentioning regarding this code. The first thing is that we have
taken the marks of the student in three subjects by using the nextInt() method repeatedly.
We haven't prompted thrice for input. While, there appears nothing extraordinary in this way
of programming, let's look at the output in different executions.
Following are some sample outputs.
Enter your name: Sai
Enter marks in three subjects: 100 98 99
Name: Sai
Average: 99.0
Enter your name: Sai
Enter marks in three subjects: 100
99
98
Name: Sai
Average: 99.0

289

Enter your name: Sai


Enter marks in three subjects:
100
99
98
Name: Sai
Average: 99.0
Enter your name: Sai
Enter marks in three subjects:
100 99
98
Name: Sai
Average: 99.0
We have given the same input in all the cases but the way in which we have input the
values was different. In the first case, we separated the different marks with a space. In the
second case, we have pressed the enter key after entering each subject's marks. In few of
the outputs, we have also entered some blank lines but still the output was the same in all
the cases. This is because of the way in which the input from the keyboard. Whatever in
entered by us goes to the input steam, in and then we extract data from it using the nextInt()
method. What actually happens is that the data is separated into tokens. Token are pieces
of information. Tokens are not generated randomly but by noting the delimiters. Every time,
the delimiter appears, the input is split at that point and a new token is created. The default
delimiter is a whitespace. A whitespace can be a tab, space, a new line or a combination of
theses. For example- a new line followed by three spaces is also a delimiter. After the input
is split into tokens, the tokens are accessed by the method nextInt(). In all the cases, the
three tokens formed were the same and hence we got the same output.
Another thing has to be noted is the following statement:
double average = ( marks1 + marks2 + marks3 ) / 3.0;
The first thing is the use of parentheses. If we have omitted the parentheses, then marks3
would have been divided by three first and then added to marks1 and marks2. Precedence
of operators exists in Java just as in mathematics. In Java /, * and % have equal preference

290

which is higher than the preference for + and -. In order to alter the order in which
evaluation is performed, we use parentheses. Change 3.0 to 3 and you will notice that the
average printed would be incorrect. This is because, the three integers marks1, marks2 and
marks3 on addition give an integer and an integer on division with another integer gives
another integer and not a floating point number. In simpler words, an integer on division with
another integer gives the quotient and not the entire result that includes the remainder part
in the form of a decimal part. However, when the expression involves atleast a single
decimal, we get the decimal part of the calculation as well. That is why we have written 3.0
instead of 3. We shall see more about mathematical calculations in the next chapter.

Introduction to object oriented programming


Till now, we have written a program under the guise of a class though what we have
actually written was just a program and not a class in the real sense. Now, we shall start
programming the object oriented way. In the due course of being taught the way to write
simple programs, you have also been told a great deal about classes and objects. We shall
now recollect all that we have learnt about object oriented programming, classes and
objects. We shall also look into the three features of object oriented programming.
Classes and objects are the basics of objected oriented programming. In an objected
oriented model, the focus is on data (contained in objects) and not on the code that
manipulates the data. A class contains instance variables, constructors and methods. We
instantiate (create) objects from these classes by invoking (calling) the constructors. Each
object created from a class has a copy of the instance variables. Each object manipulates
its instance variables independently using the methods of the class. While variables
represent an object, the methods help in modification of these variables and
accomplishment of tasks.
Object oriented model of programming helps to simulate real world objects in a better way.
Let's discuss how this is done by considering a 'Car 'class as an example. The class can
have instance variables such as current Speed, quantityOfPetrol, and so on. We can
provide methods such as startCar(), stopCar(), chageSpeed() and so on. Some of these
methods do not require any additional information while a few others do require. For
instance, startCar() and stopCar() doesn't require any additional information while
changeSpeed() requires the speed to which the car is to be raced. This information that is to
be passed is known as an argument. In conclusion, we have designed the 'Car' class and
we are now capable of building a number of Car objects from them such as 'Car1', 'Car2'
and so on. Each of these objects function independently from each other by maintaining
their own sets of variables. We can, of course, make different objects such as 'Car1' and
'Car2' interact with each other. We have now a world of cars. We have been able to

291

successfully build a virtual world. That is what object oriented programming is all aboutsimulating the real world using objects built from classes.
There are three principles of object oriented programming- abstraction, inheritance and
polymorphism. We shall look at them one by one.
Abstraction is the process of representing the essential features of a system without getting
involved with the its complexities. Consider the Car example again. Once you write the 'Car'
class, other people will be able to create Car objects and use them. You need not disclose
to them how you implemented the starting and stopping of the Car. All that you need to tell
them is how those methods can be called. This is what abstraction is all about. Other
people are capable of using your Car class, create Car objects, and call methods such as
startCar() and stopCar(). They are capable of starting and stopping the car without knowing
how it is being done. Complexities have been hidden. Only the essentialities have been
exposed.
The next feature is inheritance. It is the capability of a new class to inherit the variables and
methods of other classes. The new class can define its own variable and methods in
addition to what have been inherited to provide additional capabilities to the new class. It is
similar to how sons and daughters inherit property and can add their own earned property to
the inherited property. If we talk in terms of the Car example, a new class called SuperCar
can be made to inherit from the class Car so that it will have the functionality of starting,
stopping and changinging speed and in addition will be able to perform some special tasks
like flying in the air similar to what we see in Hollywood movies.
The final feature of object oriented programming that is to be discussed is polymorphism.
This is the property by which different objects can react to the same method call or in
simpler terms a message, and still produce the correct output i.e. the desired output. If we
talk in terms of our Car, then we can state the feature of polymorphism as the ability to
change speed to both a numeric value and a fractional value. Different methods in those
classes will handle these calls but still the message that would be passed would be the
same, which is changeSpeed(). The only difference is in the arguments (the information to
be passed). While one call passes 34 as an argument, the other call would pass 34.7 as the
argument. These things might appear trivial for now but you will be able to appreciate these
features later on when we deal with how these features are implemented in Java.
Hoping that you understood what object oriented programming is, we now move on to the
details of how classes are defined in Java. For the rest of our discussion about building
classes, we will focus on building a Student class. A student will be having a name, a roll
number and marks in three subjects. Once the class is built, we should be able to create
Student objects. And there should be methods for finding the total marks, the average of
two students and so on. In the due course of time, we will also see how we can assign the

292

roll numbers automatically to Student objects starting from 1. We shall also explore some of
the other countless possibilities.

The constituents of a class


A class as already stated has three major components- variables, constructors and
methods. A class may have all of these, some of these or none. We can create an empty
class which doesn't have variables, constructors or methods but however there would be no
use of such a class. First, we shall look at the outer wrapping of the class which simply
names the class. This is exactly similar to what we have already seen in our initial
programs.
< access specifier > class < class name > {
}
Access specifiers that are permitted to be specified for a class are public and private. We
may also leave it unspecified. We can simply write the word class and give a name to it.
Access specifiers are used to define the domain in which an element is accessible. When
we define a class a public, it means that the class is accessible from anywhere. On the
other hand, defining a class as private restricts the accessibility to that particular program
file. We shall look at specifiers again shortly. The word class is a keyword and finally the
class name needs to follow the rules of identifiers. The braces serve the purpose of
delimiting the class. Anything that appears within the braces is a part of the class. A group
of statements enclosed in braces is known as a block. For now, we will move on to the
Student class. We define the Student class in the following way.
public class Student {
// variables
// constructors
// methods
}
At this point of time, it is necessary to understand that we do not have a main method here.
We are of course free to include a main method but we shall test this Student class outside
in a new class (or to be more clear- a program ) having a main method.
Now, we shall look at declaring the variables. Variables are declared by specifying the data
type and the variable name. We may optionally state the access specifier also. Variables
declared within the class are accessible to all the methods of the class. These variables
characterise the object that would be instantiated from these classes. Following is the
syntax for variable declaration.
< access specifier > < data type > < variable name >;

293

We may also give a value to it, which would be the default for objects instantiated from this
class. But, we shall do it in a better way using constructors.
< access specifier > < data type > < variable name > = < value > ;
For now, here is the class Student with five variables.
public class Student {
private int rollNumber;
private String name;
private int marks1;
private int marks2;
private int marks3;
}
We have applied the private access specifier to each of the variables. When we do so,
these variables are accessible from within the class only. Any attempts to access them from
outside the class will result in compilation errors. This can be better explained when we
bring objects into the scene. We create Student objects from this class. After doing so, we
cannot directly request access to these variables by using the object name and dot operator
in the following way.
student1.marks1 = 100; // student1 is of type Student
Recall that we have used the dot operator several times earlier in the print() statement. The
dot operator is used to access members of classes and objects. Earlier we have accessed
the out variable of the class System. While now, we are trying to access the marks1
variable of a Student object, student1. This isn't allowed since the marks1 variable was
declared to be a private variable. If the variable was public, such a statement would have
been valid. We shall see later on how we can create the object student1. We shall also see
how these variables can be accessed or modified using get and set methods. Now, we
move on to constructors. Constructors are used to initialise an object. Constructors appear
somewhat similar in syntax to methods but there are a few differences. There are two types
of constructors- default constructors and parameterised constructors. Default constructors
do not accept any parameters while parameterised constructors accept parameters. Recall
that variables stated within the parentheses are referred to as parameters. These
parameters have a data type and a variable name. We shall now first look into how we can
provide a default constructor.
public Student ( ) {
name = null;
rollNumber = -1;
marks1 = -1;
marks2=-1;

294

marks3=-1;
}
The header of a default constructor (the first line) consist of the access specifier and the
constructor name. The constructor's name should be the same as that of the class, which in
this case is 'Student'. Since this is a default constructor that doesn't take any arguments,
the parentheses are left empty. And then, as usual we start a block using an opening curly
brace. We then initialise the variables to some default values. We have initialised the name
to null. A reference data type when initialised to null indicates that the variable doesn't refer
to any object in memory. Recall that String is a reference data type (since it is class). And
we have initialised the remaining integers to -1 to simply indicate that the Student wasn't
initialised with a proper value. You may, if you wish to do so, provide some other default
values. The following default constructor would also be equally fine. But we have used the
null and -1 default values as they reflect the scenario in a biter way.
public Student ( ) {
name = "No name";
rollNumber = 0;
marks1 = 2;
marks2=3;
marks3=10;
}
But, remember that a class cannot have more than one default constructor.
We now move onto to parameterized constructors. Parameterized constructors accept
arguments which are data items that are used to initialise the variables of a class. Following
shows a parameterised constructor for a class where the five variables are initialised with
arguments that would be received by the constructor.
public
Student
(
String
n,
int
rn,
int
m1,
int
m2,
int
m3)
{
name
=
n;
rollNumber
=
rn;
marks1
=
m1;
marks2
=m2;
marks3=
m3;
}
Since this is a parameterised constructor which receives arguments, the required values
have been stated in the parentheses. We state the data type of the required argument and
give a variable name. This particular parameterised constructor was specified with five
parameters. Each of the parameters should be separated by a comma. The body of the
constructor assigns the values received to the instance variables. Suppose we pass the
values "Gautham", 34,97,99,98 to this constructor; then "Gautham" would be stored in n, 34

295

in rn, 97 in m1 and so on. And then because of the statement name =n; name will be
initialised with "Gautham". In a similar manner, the other variables are also initialised with
the values passed to the constructor. We shall see later on how we pass values to a
constructor while creating an object using the new keyword.
We may define more than one constructor for a class. Suppose, we want to provide the
facility where we should be able to create Student object by simply passing the name and
roll number, and assign the marks to 0, we may do it with the help of another constructor as
shown below.
public

Student

(
name
rollNumber

String

n,

int
=
=

rn)

{
n;
rn;
marks1=0;
marks2=0;
marks3=0;

}
The process of providing more than one constructor to a class is known as constructor
overloading. However, there are certain restrictions here which we shall see later on when
dealing with constructor overloading. For now, we have declared the variables and provided
three constructors. Now, let us provide a method which will print the details of a Student. A
method definition would be similar to what we have already seen in our previous programs.
The only difference would be that we will now omit the word static and also remove the
String[] args parameter. Static was used earlier since there was a need for that main
method to be called without crated an object of that class, be it HelloWorld or Addition class.
The parameter String[] args too had a significance there about which we shall later on when
dealing with command line arguments. String[] is a data type just like String and int and args
was a variable name for the argument that would be passed to main. We will deal with them
later on. For now, here is a method printDetails() which prints the details of the Student.
public

void
printDetails()
System.out.println("Roll
Number:
"+
System.out.println("Name:
System.out.println("Marks
in
first
subject:
System.out.println("Marks
in
second
subject:
System.out.println("Marks
in
second
subject:

{
rollNumber);
"+name);
"+marks1);
"+marks2);
"+marks3);

}
This method looks just like a constructor. The difference is that we have a return type and
the name of the method need not be the same as that of the class. The return type here is
void which means that the method will not return any value after execution. We shall see

296

how to implement methods that return values in a few moments and how to use those
returned values.
We have just started with the design of our Student class but it is still not completed. We
haven't provided a means to modify the values of the variables and there are no methods
that print the total marks and average. However, this current version of the Student class is
sufficient to build objects. Here is the first version of our Student class which has five
instance variables; two constructors- one default and two parameterised and lastly a
method to print details about the student.
The default constructor has been slightly modified to give default value for name as "No
name" instead of null.
public

class

Student

private
private
private
private
private

public
name

public

Student

int
String
int
int
int

Student
=
rollNumber
marks1

String n,
name
rollNumber
marks1

int

rollNumber;
name;
marks1;
marks2;
marks3;

)
"No
=
=

rn,

int

m1, int
=
=
=

m2,

{
name";
-1;
-1;
marks2=-1;
marks3=-1;
}

int

marks2
marks3=

public

Student
(
name
rollNumber

String

n,
=
=

int

rn)

m3)

{
n;
rn;
m1;
=m2;
m3;
}

{
n;
rn;

297

marks1=0;
marks2=0;
marks3=0;
}

public
void
System.out.println("Roll
Number:
System.out.println("Name:
System.out.println("Marks
in
first
System.out.println("Marks
in
second
System.out.println("Marks
in
second

printDetails()
"+
subject:
subject:
subject:

{
rollNumber);
"+name);
"+marks1);
"+marks2);
"+marks3);
}

Creating objects and Calling Methods


Now that, we have coded a class, we will now use it to create different Student objects. We
do all of this in a test class. A test class isn't a special type of class. It is just like our initial
'Hello World 'programs which had a main method that is called when the program is run.
Recall that a program should have a main() method defined with the specifiers public, static
and void if it is to be executable.
First, we will look into creating objects from classes. This is similar to how we declared
variables of primitive data types and initialised them with values, for example: initialising the
variable firstNumber with the integer 3. The same tasks are to be done here- Declaring the
variable and initialising it with an object. But the additional task required here is the creation
of objects. Since classes are reference data types, variables of a class type may not be
initialised in a simple way as we have initialised integer and floating point variables. We
create the object using the keyword new and then assign a reference of that object to the
variable of the class type. Following is the general syntax of creating an object and
assigning its reference to a variable of the corresponding class type.
< variable type - the class name > < variable/ object name > = new < call to constructor >;
The variable type that we specify here is the class name. the constructor is called by
passing the required parameters if any. Suppose, we wish to create a Student object using
the default constructor, then the following statement is used.
Student s1 = new Student ();

298

The parentheses were left empty since the default constructor does not require any
arguments. However, if we wish to create a Student object by using a parameterised
constructor, then we need to pass the appropriate arguments, separating them with
commas. We can also separate the declaration of the Student variable from the initialisation
with a Student object in the following way.
Student s1; s1 = new Student();
The above two statements are equivalent to the single statement which was earlier used to
create the Student object s1. The following statements use the parameterised constructors
of the Student class to create Student objects. We pass the required arguments by
specifying them in the parentheses.
Student s2 = new Student ( "Sai", 3 ); Student s3 = new Student ( "Gautham" , 4 , 98 , 100,
96);
The constructor that is to be called is decided by matching the argument list with the
parameter lists of the constructors. In the first statement above, we have specified a String
argument and an integer argument. We have a constructor that corresponds to these
arguments. Hence that constructor is invoked, initialising, name to "Sai", rollNumber to 3,
and marks1, marks2 and marks3 to 0. The second constructor call above matches with the
third constructor provided by us which requires five arguments. It is not just the number of
arguments that is tallied for but also the order and type of these parameters. If we had
replaced the first String with an integer value, or exchanged the first String and the last
integer argument as shown below, we would have received a compilation error.
Student s3 = new Student (4 ,96, 98 , 100, "Gautham"); // incorrect
We can provide not just constants but also variables or expressions in the arguments list.
They would be evaluated before the corresponding constructor is called. The third Student
object s3 could have been created in the following way also:
int num = 96 ; Student s3 = new Student ("Gautham" , 4, num, num+2, 48+52);
The Student object that would result from this statement will identical to the one that was
created earlier. Any variables or expressions in the arguments list are evaluated before they
are passed to the constructor.
Now, we have three Student objects. Each one of them has their own copy of the instance
variables which can be modified independently of others. Following is physical
representation of these three objects.

299

Now that we have created the objects, we will look into how the variables and methods of
these objects can be accessed. In order to access a variable or a method, we use the
reference operator (.) in the following way:
s1.printDetails();
The above statement invokes the printDetails() method on the Student object s1. If the
method requires arguments, we state them within the parentheses just as we had done in
the case of parameterised constructors. Variables too are accessed in a similar way, except
that the parentheses are not included. This is what separates the variables from methods
and helps us to distinguish between the two. If the name variable was public we could have
used the following statement to assign a String to the name variables of s1 in the following
way:
s1.name="Ravi";
We can also print these values, as we would have printed a String variable if the variable
was declared as public.
System.out.println("Name is "+ s1.name);
But, for the current objects such access is denied since the variables were declared to be
private which means that the variables are not accessible outside the class.
Now, we have the complete program below which creates three Student objects and
invokes the printDetails() method on each of these objects.
public class StudentTest {
public static void main ( String[] args ) {
Student s1 = new Student () ;
Student s2 = new Student ( "Sai", 3 );
Student s3 = new Student ( "Gautham" , 4 , 98 , 100, 96);
System.out.println("Student s1: ");
s1.printDetails();
System.out.println("\nStudent s2: ");
s2.printDetails();
System.out.println("\nStudent s3: ");
s3.printDetails();
}
}
When we run this program, we get the following output:

300

Student s1:
Roll Number: -1
Name: No name
Marks in first subject: -1
Marks in second subject: -1
Marks in second subject: -1
Student s2:
Roll Number: 3
Name: Sai
Marks in first subject: 0
Marks in second subject: 0
Marks in second subject: 0
Student s3:
Roll Number: 4
Name: Gautham
Marks in first subject: 98
Marks in second subject: 100
Marks in second subject: 96

Get and Set methods


We were able to create objects of the Student and initialise the variables of the object using
the constructor. But after that, we can no longer change the values the variables hold. The
following statement would result in an error since the variables were declared to be private.
s1.name = "Ravi";
The solution lies in providing public methods through which new values can be assigned to
these variables and the values they hold can be accessed. These are commonly known as
get and set methods. Get methods provide access to the value a variable holds while set
methods assign values to the variables of the objects. First, we shall see how we write a
method. In order to set a variable to a new value, the method needs arguments similar to
how the parameterised constructors required details such as rollNumber, name and marks.
These required arguments are specified in the method header within the parentheses by
specifying the variable name and a data type for that variable name. A set method for name
looks as shown below:
public void setName ( String n ) {
name = n;
}

301

It is a convention to name the setter methods starting with the word 'set' followed by the
variable name that is going to be set. If we wish to set the name for the first Student object
s1 which we have created, we use the following statement:
s1.setName("Ravi");
Now, we shall provide a get method for the variable name. As we have earlier said,
methods are capable of returning values. These values can be of any primitive data type or
reference type like a class. Here, we will be returning a String. The data type that is going to
be returned in specified in the method header instead of the word void. We have used the
word void till now to indicate that a method does not return any value. The get method for
name would be the following:
public String getName() {
return name;
}
The value that is to be returned is specified by using the 'return' keyword. The variable or
value that is to be returned follows the return keyword. We can specify not just a variable
name but also a constant or an expression. the following return statements would also be
equally fine. return "XYZ";
return "Name: "+name;
However, for the current scenario, we require that only the name be returned and not
anything in addition. Also, the return statement should be the last line in a method that
returns a value. Once the return statement is reached, the lines of code that follow the
return statement would not be executed. In this particular case, we cannot write any
statements after the return statement. This is because unreachable code generates
compilation errors. Unreachable code refers to those statements which can never be
executed. Consider the following get method for name.
public String getName() {
return name;
name = "No name";
}
The statement name="No name" is an unreachable statement. This is because, once the
return statement is encountered, the remaining lines of code in that method would be
ignored. Therefore, the above code produces compilation errors. However, in certain
circumstances, we can provide a return statement and also write code following that
statement when we use decision making statements. We will look into it alter on.

302

Now, that we have written a get method, we shall see how we can use it. We can invoked
the getName() method a Student object, and the returned value can be stored in a variable,
can be printed on the screen or can be used for any other purpose.
In the following statement, the value returned by getName is stored in the variable aName.
String aName = s2.getName();
As we have earlier initialised the name of s2 object with "Sai", aName will hold the value
"Sai". We can also directly print the returned value by invoking the method within the
parentheses in the following way:
System.out.println ("Name of s2: "+ s2.getName() );
In a similar way, we can provide get and set methods for all other variables of the class. But
what exactly is the use of these get and set methods? Instead of providing these methods,
we could have simply made the variables public and they could be accessed in the following
way instead of using get and set methods.
s1.name="Ravi";
System.out.println("Name of s1: " +s1.name);
Such a simpler approach would reduce the work of providing a get and a set method for
each of the five variables, greatly reducing coding work. But that isn't the preferred way for
programmers. When data is easily accessible in that way, data isn't secure. One who uses
the class can easily assign the marks1 of a Student with the integer 1000 where in reality,
the maximum marks are 100. In order to restrict access and to check data before it is
assigned to the variables, we provided the get and set methods. We haven't done such
checking for the name variable. We shall see how it can be done for the marks1 variable.
For this purpose, we use decision making statements. We shall see two of them for now:
the if statement and the if else statement. Following is the syntax of the if statement:
if ( condition ) {
// code
}
And here is the syntax for if else statement
if ( condition ) {
// code1
} else {
// code2
}

303

We hope that you are able to guess what the purpose of the above statements is. To make
sure that you've got it right, let's look at them individually. If the condition stated in the
parentheses of the if statement is true, then the code in the block is executed. In a similar
way, for the if else statement, if the condition is true, the first block of code is executed. If
the condition is false, the statements in the else block are executed. As already said, a
block is a set of statements within a pair of curly braces. They indicate the ownership of a
piece of code. Here, the blocks are used to indicate that the code contained in them is a
part of the corresponding if or else statements. If the code which is to written for an if or else
statement has just a single line or a single statement, there is no need to put the braces.
Another important thing is that variables declared within a block are not accessible outside
the block. Here, if we declare a new variable 'var 'in the if block and try to print its value in
the else blocks, we would be getting a compilation error. The same holds true for methods
also. For instance, if we declare a new variable in the setName() method and try to access it
in the getName() method, we would be stopped bay compilation errors. The following code
is erranous.
public void setName ( String n ) {
name = n;
int var = 34;
}
public String getName() {
var = 7; // incorrect var is not known here
return name;
}
Now, it's time to see how these decision making statements can be used to enforce data
validation in the set methods. But before that we need to learn how we can write conditions
in a language that is understandable by the computer. To make it short, we should be able
to tell the computer 'If marks are greater than or equal to zero and less than or equal to 100,
assign the value to the variable marks, else set the marks to zero'. In order to write
conditions, we use relational and logical operators. We have already come across the other
category of operators- mathematical operators and we have used them widely. Now, we
shall see what the relational and logical operators are. Here are some of the operators in
each of the categories that we would be using widely from now onwards.
Relational operators:
&gt; Greater than
&lt; Less than
&gt;= Greater than or equal to
&lt;= less than or equal to
== equal to

304

!= not equal to
Logical operators
&& Logical and
|| Logical or
! Logical not
Relational operators are used to compare the values of two data items- variables or
constants. Each of the variables requires two operands and the result returned would be
either true or false. All of these operators are similar to what we come across in
mathematics; the only difference lies in their representation. Look at the following code to
see how these relational operators work. As already said, the result of a relational operation
is a boolean value: true or false. Hence, we need a boolean variable to store the result.
int a=3, b=4, c=4;
boolean res1 = a>b ; // res1 holds false
boolean res2 = b<10; // res2 holds true
boolean res3 = b>=c; // res3 holds true
boolean res4 = c<=34; // res4 holds true
boolean res5 = b==c ; // res5 holds true
boolean res6 = 3!=a; // res6 holds true
And now, coming to logical operators- we have three of them. 'Logical and' and 'logical or'
require two operands while 'logical not' requires a single operand. The operands in all the
cases are of type boolean and the result obtained is also a boolean. The 'logical operator
and' (&&) returns true when both the operands are true, otherwise returns false. 'Logical or'
(||) returns true when atleast one of the operand is Tue. And lastly 'logical not' (!) returns
true if the operand is false and returns false if the operand is true. The following are the
truth tables of these operators while are helpful in knowing the value of the returned
boolean when the operands values are known.
Logical operator and &&
Operand 1 Operand 2 Result
true true true
true false false
false true false
false false false
Logical operator or ||
Operand 1 Operand 2 Result
true true true
true false true
false true true
false false false

305

Logical operator not !


Operand Result
true false
false true
Following code shows the use of logical operators
boolean a = true;
boolean b = false;
boolean res1 = a&&b; // false
boolean res2 = a||b; //true
boolean res3 = !a; //false
boolean res4 = !false; // true
boolean res5 = true&&a; //true
Now, to frame the conditions that we would we using in the if statements, we make a
combined use of the relational and logical operators. The operands for a logical operation
can be expressions too. We frame these expressions using relational operators. For
example, in order to check that the marks are both >= 0 and <= 100, we use the following
condition:
marks1 >= 0 && marks1 <=100
In the above expressions, the conditions marks1>=0 and marks1<=0 are evaluated first and
then the result of these evaluations are used to find the result of the 'logical and' operation.
The order in which the operations are done depends on the precedence of operators.
Relational operators have a higher precedence than logical operators. Hence they are
evaluated first. Further, the different relational and logical operators also have a precedence
order among themselves. For a complete list of the operator precedence, visit this page.
When you are not sure about the precedence, use parentheses so that the expression will
be evaluated in the way you would like. The above expression could have written more
clearly as
(marks1 >= 0 ) && ( marks1 <=100)
Following is the complete setMarks1() method. This method takes an integer argument. If
the argument satisfies the conditions, then marks1 are initialised to that argument,
otherwise we initialise marks1 to zero.
public void setMarks( int m) {
if ( m>=0 && m<=100 ) {
marks1 = m;
} else {

306

marks1 = 0;
}
}
We again emphasize on the fact that Java is a free form language. You can break a
statement into two lines at any valid point and also write more than one statement one
single line. If you feel that reading the above code is inconvenient to you, we suggest the
following alternative form.
public void setMarks( int m)
{
if ( m>=0 && m<=100 )
{
marks1 = m;
}
else
{
marks1 = 0;
}
}
Also, in this case, since the if and else blocks contain only a single statement, you can omit
the braces and write the code in the following way:
public void setMarks( int m)
{
if ( m>=0 && m<=100 )
marks1 = m;
else
marks1 = 0;
}
And another remainder regarding eth accessibility of a variable: Variables defined within a
block are accessible in that block only. These conditions are known as the scope and
lifetime of variables. Scope refers to the part of the code in which the variable is accessible
while lifetime refers to the duration for which a variable exits before it is destroyed by
deallocating the memory allotted to it while declaring the variable. If we declare a variable
within the if block, the lifetime ends once we come of if the if block. Any attempt to access
that variable would give an error that the requested variable is not defined. If there is a need
to declare variables inside such blocks and access them even after we move out of the
blocks, then we need to declare these variables before the starting of the block and outside
the block. Following pieces of code shows an incorrect way and a correct way of using such
variables.

307

public void setMarks( int m)


{
if ( m>=0 && m<=100 )
int temp = m;
else
int temp = 0;
marks1 =temp; // Incorrect: temp is not known here
}
public void setMarks( int m)
{
int temp;
if ( m>=0 && m<=100 )
temp = m;
else
temp = 0;
marks1 =temp; // Correct: temp is known here
}
In the second piece of code, the variable temp is accessible since it was declared outside
the if and else blocks in the same block as that of the method. Variables declared within
methods are known as local variables. For example, here temp is a local variable. Such
variables are accessible within that particular method only. The scope and lifetime of local
variables is the method block itself. Now that we have learnt how to use set and get
methods to enforce restriction on the data that can be assigned to variable, we present a
complete program below. We also provide a getAverage() method which computes the
average if the Student. We use this getAverage() method in the printDetails() function. And
then we have a test class, where the object is initialised with values entered by the user.
And then, we display the details of the student in two ways- one by using the printDetails()
method and the other by using the get methods provided in the class.
Given below is the Student class
public class Student {
private int rollNumber;
private String name;
private int marks1;
private int marks2;
private int marks3;
public void setName(String s) {
name = s;
}

308

public String getName() {


return name;
}
public void setRollMumber(int r) {
if (r > 0) {
rollNumber = r;
} else {
rollNumber = 1;
}
}
public int getRollNumber() {
return rollNumber;
}
public void setMarks1(int m) {
if (m >= 0 && m <= 100) {
marks1 = m;
} else {
marks1 = 0;
}
}
public int getMarks1() {
return marks1;
}
public void setMarks2(int m) {
if ((m >= 0) && (m <= 100)) {
marks2 = m;
} else {
marks2 = 0;
}
}
public int getMarks2() {
return marks2;
}
public void setMarks3(int m) {
if ((m >= 0) && m <= 100) {
marks3 = m;

309

} else {
marks3 = 0;
}
}
public int getMarks3() {
return marks3;
}
public double getAverage() {
return (marks1+ marks2 + marks3) / 3.0;
}
public void printDetails() {
System.out.println("Roll Number: " + rollNumber);
System.out.println("Name: " + name);
System.out.println("Marks in first subject: " + marks1);
System.out.println("Marks in second subject: " + marks2);
System.out.println("Marks in second subject: " + marks3);
System.out.println("Average: " + getAverage());
}
}
Go through the above class carefully and note the following points. The conditions
expressions in each of the three methods for setting marks was written in a slightly different
manner. The parentheses used in them were redundant i.e. it would have made no
difference even if the parentheses were omitted. Following are the three different forms we
have used. All of them are equivalent:
m >= 0 && m <= 100
(m >= 0) && (m <= 100)
(m >= 0) && m <= 100
We can also write the condition in the following way
m >= 0 && ( m <= 100)
Also, note how the if else conditions were written. All of the blocks have a single statement.
Therefore, enclosing the single statement in curly braces is optional. Therefore all the three
forms of if else we have written for the different methods are equivalent. If we want to do so,
we may also enclose the else statement in curly braces and leave the if statement without a
pair of curly braces.

310

Another thing is regarding the computation of average. We need to write 3.0 and not 3. If we
write it as 3, then the result will be an integer and the fractional part would be lost. We could
also have written the statement as:
(marks1 + marks2 + marks3) / (double)3;
Note that return keyword in getAverage() method is followed by the above expression and
not a variable as in the other get methods. Variables, constants and expressions can be
returned. Before returning the expression is first evaluated. We can write the getAverage()
method in the following way also:
public double getAverage() {
double average =(marks1 + marks2 + marks3) / 3.0;
return average;
}
Also note that the return type specified in the method header of the getAvearge() method is
double. This type needs to match with the data type of the value being returned.
The expressions have been written in different styles, using parentheses at some places,
omitting them at few other places, using curly braces at some points and so on. This has
been done to show that all the forms of coding are acceptable. However, when you write a
program, use the same style throughout. It makes your program appeal to others.
And given below is the Test program. In this program, we use the second constructor that
accepts a roll number and a name to create the object. And the marks are set using the
different set marks methods. And then we print data; first by invoking printDetails() method
and then by using the different get methods.
The only thing worth mentioning here is the manner in which we have taken the input:
s1.setMarks1(s.nextInt());
This statement is correct. As already said, arguments passed are first evaluated before they
are passed to the method. So s.nextInt() method would be executed and then the integer
would be passed to setMarks1() method.
The following is the StudentTest class.
import java.util.Scanner;
public class StudentTest {
public static void main(String[] args) {

311

Student student = new Student();


Scanner scanner = new Scanner(System.in);
System.out.print("Enter Name: ");
String name = scanner.nextLine();
student.setName(name);
System.out.print("Enter roll number: ");
int rollNumber = scanner.nextInt();
student.setRollMumber(rollNumber);
System.out.print("Enter marks1: ");
int marks1 = scanner.nextInt();
student.setMarks1(marks1);
System.out.print("Enter marks2: ");
int marks2 = scanner.nextInt();
student.setMarks1(marks2);
System.out.print("Enter marks3: ");
int marks3 = scanner.nextInt();
student.setMarks1(marks3);
System.out.println();
System.out.println("Printing details using printDetails() method: =");
student.printDetails();
System.out.println();
System.out.println("Printing details without using printDetails() method:");
System.out.println("Name: " + student.getName());
System.out.println("Roll Number: " + student.getRollNumber());
System.out.println("Marks1: " + student.getMarks1());
System.out.println("Marks2: " + student.getMarks2());
System.out.println("Marks3: " + student.getMarks3());
System.out.println("Average: " + student.getAverage());
}
}
We have named the Student object as student. We can give any name including the same
name as that of the class, capitalisation included. For instance, the following statement is
also correct.
Student Student = new Student();
Here is a sample input where the user enters all correct details.
Enter name: Sai
Enter roll number: 34
Enter marks1: 98
Enter marks2: 97
Enter marks3: 100

312

Printing details using printDetails() method:


Roll Number: 34
Name: Sai
Marks in first subject: 98
Marks in second subject: 97
Marks in second subject: 100
Average: 98.33333333333333
Printing details without using printDetails() method:
Name: Sai
Roll Number: 34
Marks1: 98
Marks2: 97
Marks3: 100
Average: 98.33333333333333

And here is a sample input where the user enters incorrect details.
Enter name: Sai
Enter roll number: 34
Enter marks1: 100
Enter marks2: -34
Enter marks3: 347
Printing details using printDetails() method:
Roll Number: 34
Name: Sai
Marks in first subject: 100
Marks in second subject: 0
Marks in second subject: 0
Average: 33.333333333333336
Printing details without using printDetails() method:
Name: Sai
Roll Number: 34
Marks1: 100
Marks2: 0
Marks3: 0
Average: 33.333333333333336

313

Now, try creating a Student object using the constructor where all the values all passed in
the following way.
Student s = new Student ( "sai",34,100,-34,347);
Now invoke the printDetails() method. You will see that marks2 and marks3 were not set as
zero but as -34 and 347. The reason is that in the constructor, we have not provided data
validation. We have directly assigned the values. Hence, we need to modify the
constructors and call the set method from the constructors instead of directly assigning the
values. Following is a modified version of the constructor. The name variable can be either
directly initialised or by calling the set method. Either way gives the same result because no
data validation was provided for the name variable. Following is a modified version of the
constructor.
public Student(String n, int rn, int m1, int m2, int m3) {
name = n; setRollNumber(rn);
setMarks1(m1);
setMarks2(m2);
setMarks3(m3);
}

Default Constructor provided by Compiler


When we do not explicitly provide a constructor to our class, the compiler provides a default
constructor which initialises all the instance variables to their default values. The default
constructor provided by the compiler is different from the no argument or default constructor
which we provide ourselves. In the constructor that we provide, we are able to set the
variables to any default values that we wish to do so which may be 0 ,-1 or some other
different value, but this is not the case with the default constructor provided by the compiler.
It sets variables of different data types to the default values given by the following table:
Data Type

Variable Name

byte

short

int

long

0L

float

0.0f

double

0.0

boolean

false

char

<All reference types>

Null

314

To verify this fact, remove all the constructors from the Student class, create an object of
that class and print the information stored in the variables.
public class Student {
private int rollNumber;
private String name;
private int marks1;
private int marks2;
private int marks3;
public void printDetails() {
System.out.println("Roll Number: " + rollNumber);
System.out.println("Name: " + name);
System.out.println("Marks in first subject: " + marks1);
System.out.println("Marks in second subject: " + marks2);
System.out.println("Marks in second subject: " + marks3);
}
}
public class StudentTest {
public static void main ( String[] args ) {
Student s=new Student();
s.printDetails();
}
}
We get the following output:
Roll Number: 0
Name: null
Marks in first subject: 0
Marks in second subject: 0
Marks in second subject: 0
Average: 0.0
As you can see, all the variables were set to 0 or their equivalent. String which is also a
reference type was set to null. (All classes are reference types). When a variable of a class
type is set to null, it means that the variable wasn't initialized.

315

When we provide atleast one constructor to our class, then the compiler no more provides a
constructor. It doesn't matter whether we are providing a no argument constructor or a
parameterised constructor. The following code generates compilation errors since the class
Student has no default constructor and we are trying to create an object using a default
constructor.
class Student {
public Student ( int m ) {
}
}
class StudentTest {
public static void main ( String args[] ) {
Student s=new Student(); // Incorrect
}
}
Also, if we do not initialise any variables in the constructors provided by us, then they too
are set to their default values. This is not the case with local variables (those defined in
methods).
class Student {
int m;
public Student () {
}
}
class StudentTest {
public static void main ( String args[] ) {
Student s=new Student();
System.out.println(s.m);
}
}
The above program prints 0 in the output. This is because any variables that are
uninitialized in the constructor are initialized with their default values. However, as the
following program shows, this default initialisation does not occur with other types of
variables.

316

public void print() {


int x;
System.out.println(x); // A compilation error would be generated saying that x was not
initialized
}

Access Specifiers
We have quite often been using the access specifiers- public and private. We shall now see
what these access specifiers actually are, to what entities they can be applied and what
access restrictions are imposed by their usage.
But before looking into access specifiers, let us see what packages are. Packages, in a
simple language can be stated to be a group of related classes. They are just like folders on
your computer and the classes within these packages are like the files contained in folders.
Packages help in organising classes. We shall see how to create and use packages later
on. Every class is a part of a single package. When we do not explicitly specify to which
package a class belongs, it is placed in the default package. Before we can use a class
from a package, we need to import either the entire package or that particular class by
using the import statement as we have done when using the Scanner class. Two packages
are implicitly imported into a class. One is the java.lang package and the other is the default
package in which we are working. That was the reason why we were able to use the
Student class in the StudentTest class without importing the Student class. The class String
which we often use to store text is a part of the java.lang package.
Access specifiers are used to control the visibility of members like classes, variables and
methods. There are three access specifiers: public, private and protected. We shall see only
about the public and private access specifiers for now. Protected access specifier comes
into picture when inheritance is implemented. Also, we may leave the access specifier
keyword unspecified just as we had seen when learning about classes in the beginning. For
example, the following class declaration is also valid though no access pacifier is stated.
class Student {
}

In such cases, the default restrictions (also known as the package restrictions) are applied.
Now, we will see what effect these specifiers have on classes, methods and variables.
Before moving further, there is another thing to be noted. A simple program file can contain
more than one class but only one of them should be declared as public. If more than one
class is declared in the same program file, both of them will be considered as different
classes. Or in other words, one class is not said to be contained within the other class. This

317

is important to be noted to avoid any erroneous interpretation of the restrictions imposed by


access specifiers.

Access specifiers for classes


When a class is declared as public, it is accessible to other classes defined in the same
package as well as those defined in other packages. This is the most commonly used
specifier for classes. A class cannot be declared as private. If no access specifier is stated,
the default access restrictions will be applied. The class will be accessible to other classes
in the same package but will be inaccessible to classes outside the package. When we say
that a class is inaccessible, it simply means that we cannot create an object of that class or
declare a variable of that class type. The protected access specifier too cannot be applied
to a class.

Access specifiers for instance variables


Accessibility of instance variables can be controlled with all the four access specifierspublic, private, protected and the default restriction (no access specifier mentioned). When
a variable is declared as public, it can be modified from all classes in the same or different
packages. When we talk of modification here, it refers to the modification of the variables
corresponding to an object built out of this class and not the variable of the class itself. If no
access specifier is stated, then these variables are accessible from classes in the same
package only. If the variable is private, access is restricted to the class itself. If we create an
object of this class in the main method of the same class, the variable is accessible but if
the object is created in different class, the variable is accessible. Look at the following
sample code for example.
public class Student {
private name;
public static void main ( String[] args ) {
Student s = new Student ();
s.name = "Sai"; // allowed
}
}
In the above program, we were able to modify the name variable directly even though the
access specifier was private. This is because the variable was accessed from the same
class itself. If we create an object of the Student class in a new class, such an StudentTest,
access would be denied.

318

public class StudentTest {


public static void main ( String[] args ) {
Student s = new Student ();
s.name = "Sai"; // not allowed
}
}

Access specifier for methods


Access specifiers for methods work in a similar way to that of variables. Methods too can be
defined using all four levels of access protection.

Access specifiers for constructors


All four access restriction may be applied to constructors. When we talk of accessing a
constructors, it refers to creating an object of that class using that particular constructor. If a
constructor is declared as public, its objects can be created from any other class. If no
access specifier is stated, its objects may be created from classes belonging to the same
package only. If the private access specifier is applied, objects may be created in that
particular class only. However, we generally do not apply the private access specifiers to a
constructor if the class contains only a single constructors as this may render the class
unusable. Look at the following code where a constructor is declared as private. We can
create objects within the same class only. In this particular example, we have created the
object in the main method of the class. Attempting to create the object in different class
would result in compilation errors.
public class Student {
public name;
private Student() {
}
public static void main ( String[] args ) {
Student s = new Student (); // allowed
}
}
public class StudentTest {
public static void main ( String[] args ) {
Student s = new Student (); // not allowed

319

}
}
Following table shows what access specifiers may be assigned to different elements. Note
that all four levels may be applied to all elements except classes. Classes may be declared
with only public and private access specifiers
public

private

protected

< unspecified >

class

allowed

not allowed

not allowed

allowed

constructor

allowed

allowed

allowed

allowed

variable

allowed

allowed

allowed

allowed

method

allowed

allowed

allowed

allowed

The following table summarises the above said points regarding the accessibility of entities.
We haven't looked into what a subclass is and the accessibility in a subclass. We shall see
about it when we deal with inheritance.
class

subclass

package

outside

private

allowed

not allowed

not allowed

not allowed

protected

allowed

allowed

allowed

not allowed

public

allowed

allowed

allowed

allowed

< unspecified >

allowed

not allowed

allowed

not allowed

Scope and Lifetime of Variables


The scope of a variable defines the section of the code in which the variable is visible. As a
general rule, variables that are defined within a block are not accessible outside that block.
The lifetime of a variable refers to how long the variable exists before it is destroyed.
Destroying variables refers to deallocating the memory that was allotted to the variables
when declaring it. We have written a few classes till now. You might have observed that not
all variables are the same. The ones declared in the body of a method were different from
those that were declared in the class itself. There are there types of variables: instance
variables, formal parameters or local variables and local variables.

Instance variables
Instance variables are those that are defined within a class itself and not in any method or
constructor of the class. They are known as instance variables because every instance of

320

the class (object) contains a copy of these variables. The scope of instance variables is
determined by the access specifier that is applied to these variables. We have already seen
about it earlier. The lifetime of these variables is the same as the lifetime of the object to
which it belongs. Object once created do not exist for ever. They are destroyed by the
garbage collector of Java when there are no more reference to that object. We shall see
about Java's automatic garbage collector later on.

Argument variables
These are the variables that are defined in the header oaf constructor or a method. The
scope of these variables is the method or constructor in which they are defined. The lifetime
is limited to the time for which the method keeps executing. Once the method finishes
execution, these variables are destroyed.

Local variables
A local variable is the one that is declared within a method or a constructor (not in the
header). The scope and lifetime are limited to the method itself.
One important distinction between these three types of variables is that access specifiers
can be applied to instance variables only and not to argument or local variables.
In addition to the local variables defined in a method, we also have variables that are
defined in bocks life an if block and an else block. The scope and is the same as that of the
block itself.

Call by Value and Call by Reference


Before we look into what the terms call by value and call by reference mean, let us look at
two simple programs and examine their output.
class CallByValue {
public static void main ( String[] args ) {
int x =3;
System.out.println ( "Value of x before calling increment() is "+x);
increment(x);
System.out.println ( "Value of x after calling increment() is "+x);
}
public static void increment ( int a ) {
System.out.println ( "Value of a before incrementing is "+a);

321

a= a+1;
System.out.println ( "Value of a after incrementing is "+a);
}
}
The output of this program would be:
Value of x before calling increment() is 3
Value of a before incrementing is 3
Value of a after incrementing is 4
Value of x after calling increment() is 3
As is evident from the output, the value of x has remain unchanged, even though it was
passed as a parameter to the increment() method. (This program contains two static
methods. The method increment() was also specified to be static since only static members
can be accessed by a static method)
And now, we move on to the second program, where we will make use of class Number that
contains a single instance variable x.
class Number {
int x;
}
class CallByReference {
public static void main ( String[] args ) {
Number a = new Number();
a.x=3;
System.out.println("Value of a.x before calling increment() is "+a.x);
increment(a);
System.out.println("Value of a.x after calling increment() is "+a.x);
}
public static void increment(Number n) {
System.out.println("Value of n.x before incrementing x is "+n.x);
n.x=n.x+1;
System.out.println("Value of n.x after incrementing x is "+n.x);
}
}
This program would give the following output

322

Value of a.x before calling increment() is 3


Value of n.x before incrementing x is 3
Value of n.x after incrementing x is 4
Value of a.x after calling increment() is 4
Now, there is a remarkable difference between the outputs obtained in the above two
programs. In the first program, the change made to the variable a inside the increment()
method had no effect on the original variable x that was passed as an argument. On the
other hand, in the second program, changes made to the variable x that was a part of the
object in the increment() method had an effect on the original variable ( the object which
contained that integer variable) that was passed as an argument. The difference lies in the
type of the variable that was passed as an argument. int is a primitive data type while
Number is a reference data type. Primitive data types in Java are passed by value while
reference data types are passed by reference.
What we mean by passing a variable by value is that the value held in the variable that is
passed as an argument is copied into the parameters that are defined in the method
header. That is why changes made to the variable within the method had no effect on the
variable that was passed. On the other hand, when objects are passed, the object itself is
passed. No copy is made. Therefore changes made to the object within the method
increment() had an effect on the original object.
The following figure illustrate call be reference and call by value.

323

The concept of call by reference can be better understood if one tries to look into what a
reference actually is and how a variable of a class type is represented. When we declare a
reference type variable, the compiler allocates only space where the memory address of the
object can be stored. The space for the object itself isn't allocated. The space for the object
is allocated at the time of object creation using the new keyword. A variable of reference
type differs from a variable of a primitive type in the way that a primitive type variable holds
the actual data while a reference type variable holds the address of the object which it
refers to and not the actual object.

324

Consider the following program which illustrates theses concepts.


class Number {
int x;
}
public class Reference {
public static void main ( String[] args ) {
Number a = new Number();
a.x=4;
System.out.println(a.x);
Number b=a;
b.x=5;
System.out.println(b.x);
}
}
The output would be:
45
This program creates just one object and not two. The statement Number b doesn't create a
new object. Instead it only allocates some space where the address of the object to which b
refers would be stored. The statement b=a; simply copies the value stored in b to a. This

325

value isn't the object itself but is simply the address at which the object is stored. Therefore,
both a and b refer to the same object. Any change made to the object through either of the
variables gets reflected on the other variable also. That is why when we have changed the
value of x through the variable name b to 5, the change was reflected on the value of x
accessed through a. this is because, a and b are simply different names for the same object
in the computers 'memory.
What the new keyword does is that it simply creates an object and returns reference to that
object i.e. the address of that object. we assign this reference ( address) to an appropriate
variable.
We can compare two reference variables using the == relational operator. The result is true
is both the vraibles refer to the same object, otherwise the result is false. Look at the
following code for example:
Number
a
=new
Number
b
=
new
Number
c=b;//
c
also
boolean
result1=
boolean result2= b==c; // true

Number();
Number();
refers
to
a==b;

//
//
the

first
second
second
//

object
object
object
false

Casting
We have already come across casting quite a number of types. In order to help you, we will
now recollect all that we have learnt about casting till now and then learn something in
addition to what you have already learnt.
Casting refers to the conversion of one data type to another. When we cast a particular
variable, the data type of the variable itself is not altered. For example, in the following
code, when we cast, num1 to a double; the variable num1 does not change its data type
from int to double. Instead, a new copy of num1 is made and its data type is changed to
double.
int num1=3, num2=4;
double result = (double) num1 / num2;

Casting is of two types- up casting and down casting. When we cast a variable to a higher
data type it is known as up casting. A higher data type simply indicates that the memory
allocation for that data type is higher. For example, int is a higher data type than short as
the memory allocated for int is 32 bits which is higher than the memory allocated for a short
which is 16 bits. On the other hand, when we cast a variable to a lower data type, it is
known as down casting. When we up cast a variable, no information is lost but while down
casting a variable, information loss might occur. Consider the following example:

326

short a = 347;
int b= 347347;
short c = (short)a;
int d = (short) b;
System.out.println(c);
System.out.println(d);
This code would give the output:
347
19667
As you can see, when an int was cast to a short, data loss had taken place as the number
347347 is too large for a short variable.
Following conversions fall under down casting
byte -> char
short -> byte, char
char -> byte, short
int -> byte, short, char
long -> byte, short, char, int
float -> byte, short, char, int, long
double -> byte, short, char, int, long, float
And the following conversions fall under up casting
byte -> short, int, long, float, double
short -> int, long, float, double
char -> int, long, float, double
int -> long, float, double
long -> float, double
float -> double

Implicit and explicit casting


When casting is performed by the programmer using the cast operator (a pair of
parentheses containing the data tope), it is known as explicit casting. When such casting is
performed by the compiler, it is known as implicit casting. Implicit casting is performed when
operators and operands come into the scene. In order to operate on two operands with an
operator, both of them should be of the same type. If they are not, implicit up casting to
higher of the two types is performed. Consider an int 'a' and a long 'b'. When 'a' and 'b' are
added, 'a' is first implicitly casted to a long and then added to 'b'.

327

int a=3;
long b=4;
long c=a+b; // a is implicitly cast to a long
Look at another example below:
char c='A';
int s=1;
If we perform the addition of c and s (c+s), we get an int as a result. This is because c is
implicitly casted to an int. if we try to store the result in a short or a byte variable; we get a
compilation error saying 'possible loss of precision'. Precision here refers to the number of
digits. Therefore the following statement is invalid.
short ans= c+s;
We will have to cast the result of c+s into a short explicitly in the following way.
short ans= (short) (c+s);
Note that we require a parentheses around c+s. this is because the cast operator has a
higher operator precedence than +. To force the addition to occur first, parentheses are
used as shown above.
It is also possible to cast objects from one class type to another class type. We shall look at
it when we deal with inheritance. For now, this is all you need to know about casting.

Class as a Reference Data Type


It has already been said that a class is also a data type- a non primitive reference data type.
This was very much implicit in the way we had declared a class variable in the following
way.
Student s;
This declaration was identical to the way we declared the int variable firstNumber was
declared in our Addition program
int firstNumber;
Now, considering this similarity, it should be possible to use a class everywhere we had
used a primitive data type such as int. We can have instance variable of a class type, we
can accept parameters of class type and we can also return objects from methods. All that

328

needs to be done is to specify the particular reference type (the class name) wherever we
had earlier specified the data type as int or double.
We shall now look into each of these possibilities and their applications.
The first in queue is to declare an instance variable of a class type. Assume that we have a
Tutor class which would represent a person who would be taking classes for Students and
each Tutor will be taking classes for exactly two Students. So, we need to have two Student
instance variables in a Tutor class in the following way:
public class Tutor {
Student s1,s2;
}
All the things that we have learnt with declaring and initialising variables of simple data
types are applicable here also. And now, we need a constructor for this Tutor class which
will initialise the variables s1 and s2 with two objects that would be passed as arguments.
The constructor would be having the following form.
public Tutor ( Student stu1, Student stu2 ) {
s1 = stu1;
s2 = stu2;
}
We can also have methods that would return Student objects. For example, consider the
following method getS1 which returns the s1 object. note that this method is however not
necessary here as s1 hasn't been declared to be private.
public Student getS1() {
return s1;
}
Note that we have specified the return type to be Student just like int, double and void. And
lastly, we have to deal with referencing the constituents of an object. Suppose that we have
a Tutor object named t. How would we call the print Details() method of s1? It is very much
the same thing that we have been doing now with a little addition.
t.s1.printDetails();
t.s1 gives us access to the first Student's object and then we invoke the print Details()
method on that object. Here is a small class for Tutor and a test program which follows it
which illustrate all that has been told till now.

329

public class Tutor {


Student s1, s2;
public Tutor ( Student st1, st2 ) {
s1 = st1;
s2 =st2;
}
}
public class TutorTest {
public static void main ( String args[] ) {
Student student1 = new Student ( "Gautham", 3 );
Student student2 = new Student ( "Sai", 4, 98, 100, 96);
Tutor t = new Tutor (s1,s2);
t.s1.printDetails();
t.s2.printDetails();
}
}
Run the above program and try to understand the output.
There are many more possibilities that we can try here. One such possibility is to check
which of the two Students of a particular Tutor is performing better by considering his
average. For this we can provide a compareStudents() method within the Tutor class itself
in the following way. We have used the decision making statement if- else that has been
introduced earlier.
public void compareStudents() {
if ( s1.getAverage() >= s2.getAverage() ) {
System.out.println("s1 is better");
} else {
System.out.println("s2 is better");
}
Note that this method doesn't give the correct output if both of them have the same
average. We will see later on how we can do it. And apart from this we can also provide an
another method comapreToTutor() which would compare a Tutor to another Tutor that
would be passed as an argument based on the sum of average marks of both the students.
public void compareToTutor ( tutor t ) {
double average1 = s1.getAverage() + s2.getAverage() ;
double average2 = t.s1.getAverage() + t.s2.getAverage() ;

330

if ( average1 >= average2) {


System.out.println("Tutor is performing well");
} else {
System.out.println("Tutor is not performing well");
}
}
Observe the computation of average1 and avergae2. Avearge1 is the average of the Tutor
on which this method would be called. And average2 is the average of the Tutor that would
be passed as parameter.
In the main method of a test class, we write the following code:
Tutor t1 = new Tutor ( new Student ( "Sai", 3,98,97,100), new Student
("Gautham",4,94,97,98) );
Tutor t2=new Tutor ( new Student ( "Ravi", 7, 99, 98, 100), new Student ("Ranjith", 34, 95,
97,97) );
t1.comapreToTutor(t2);
Note how the Tutor objects were created. Instead of first creating the Student objects and
then passing them to the constructor of Tutor, we have written the object creation
statements within the parentheses itself. As always, the arguments in the parentheses
would be evaluated first and then the constructor would be called. In this case, first the two
Student objects would be created and then the Tutor constructor would be called. And then
t1 is compared to t2. Run the program and see down the result.

Constants or Literals
We have already come across constants a number of times. Constants are those data items
which do not change their value during the execution of a program. For instance, the integer
5, the String "Hello World" are all constants. Constants can be classified into five
categories: Integer constants, character constants, Floating point constants, boolean
constants and String constants. We have already dealt with all these constants when
dealing with data types. The following table shows the various types of constants and the
data types that fall under them.
Type of Constant

Data Types

Integer Constants

byte, short, int, long

Character Constants

char

Floating Point Constants

float, double

Boolean Constants

boolean

String Constants

String

331

Final Variables
We have seen what a variable is and we are also aware of the fact that a variable may be
assigned a new value any number of times. That is the reason it is known as a variable i.e.
something whose values keeps varying and does remains constant. Suppose that we need
to use the value of PI repeatedly in our program correct to ten decimal places. Mentioning
this value each time may not be a viable option. One thing that can be done is to initialise a
variable named pi to its value in the following way in the beginning of the program and use
the variable wherever the variable is required.
double pi = 3.1428571428;
double volume = pi * radius * radius * height;
But such a representation falsely implies that pi is a variable, something contradicting the
fact that everyone is aware of. Moreover, one might erroneously change the value of the
variable pi to a new value.
pi = 4.1458;
To avoid such mishaps, we have another type of variables in Java known as final variables.
The value of such variables once initialised may not be changed later on during the
execution of the program. Final variables are declared using the final modifier in the
following way:
final double pi = 3.1428571428;
If we later on try to modify the value, as we have done earlier, compilation errors occur. So,
marking a variable whose value shouldn't be changed helps it from being modified
accidentally. This value of pi can be used just like any other value. In order to distinguish a
final variable from a non final variable, we name it in all uppercase letters. If the variable
name consist of more than a single word, they are separated by an underscore ( _ ) sign.
This is the naming convention that everyone follows. For example:
double PI = 3.1428571428;
final int NUMBER_OF_TURNS = 34;
Final variables may be declared as either static or non static. However, it doesn't make any
difference since the value of that variable can however not be changed. The only reason
that could be cited for declaring a final variable as non static is to restrict its access only to
objects of that class and avoid it from being accessed without creating its object.
Also, the value of a final variable should be initialised at the time of its declaration itself. For
example, the statements below would result in errors:

332

final int A_STATIC_VARAIBLE ;


A_STATIC_VARAIBLE = 34;
The reason behind this is that all uninitialized variables are initialized by the compiler with
their default values when creating objects of that class type. When the initialisation takes
place to the programmer defined value, the task is equivalent to reassigning the variable
with a new value.
Use of final variables also betters reflects the task being done and makes the program self
explanatory. For example, look at the following statement:
double average = (double)( marks1 + marks2 + marks3 ) / 3;
At the first look the number 3 might not appear to be the total number of subjects. But if we
use the following sets of statements, the expression becomes self explanatory.
int NUMBER_OF_SUBJECTS = 3;
double average = (double)( marks1 + marks2 + marks3 ) / NUMBER_OF_SUBJECTS;
Just like final variables, we also have final methods and final classes. The use of final with
these entities also means the same as seen with variables. We shall look into it when we
deal with inheritance.

Increment and Decrement Operators


Increment and decrement operators are widely used in controlling loops. These operators
provide a more convent and compact way of increasing or decreasing the value of a
variable by one. For instance the statement x=x+1; can be simplified to x++; or ++x;
The increment operator increases the value of the variable by one while the decrement
operator decreases the value of the variable by one. The value of the operand is altered to
its new value. The operands required should be a variable. Constants or expressions are
not allowed because of the purpose for which the operator is used. For instance, the
expression, ++34; doesn't make sense, as 34 isn't a variable and cannot be increased by
one. If you would wish to convince that 34 can be incremented to 35; it can but what we
create is a new integer literal and we aren't updating the 34 that is already present.
Increment and decrement operators are used to update a variable to a new value.
Both these operators have two forms each: prefix and postfix. In prefix form, the operand
appears before the operand while in post fix form, the operand appears after the operand.
These operations are also referred to as pre increment, post increment, pre decrement and
post decrement.

333

When used with prefix notation, the value of the variable referred to by the operand is first
incremented and then the new value is used in the expression while in postfix notation, the
value of the variable is first used in the expression and then increased. Look at the following
examples:
int x = 34;
int y = ++x;
The value of x is first incremented to 34 and is then assigned to y. Therefore x is now 35
and y is also 35.
int x = 34;
int y = x++;
x is first assigned to y and then incremented by one. Therefore, x becomes 35 while y is
assigned with the value 34.
Similarly, pre decrement and post decrement operators work.
The post fix or pre fix notations do not make a difference when the operators are applied as
a statement by itself in the following way.
int s = 34;
s++; // s is now 35
int s= 34;
++s; // s is now 35
Give n below is an example to illustrate the use of increment and decrement operators:
int a = 3;
int b = a++;
int c = ++a;
int d = --b + ++c * --d - ++a / --d % ++c;
The first statement assigns 3 to the variable a. The second statement assigns the current
value of a i.e. 3 to b and then increments a to 2. The third statement first increments a to 3
and then assigns its value i.e. 3 to c. Now, after the execution of the first three statements,
the values of a, b and c are 3, 1 and 3 respectively.
Increment and decrement operators have a higher precedence than the other mathematical
operators. Hence, they are applied first from left to right in the order in which they occur
unless one of them has been given a higher precedence through the parantheses.

334

The following lines show the step by step application of the increment and decrement
operators.
--b + ++c * b-- - ++a / --b % c++
a=3b=1c=3
0 + ++c * b-- - ++a / --b % c++
a=3b=0c=3
a=3b=0c=3
0 + 4 * b-- - ++a / --b % c++
a=3b=0c=4
a=3b=0c=4
0 + 4 * 0 - ++a / --b % c++
a = 3 b = -1 c = 4
a = 3 b = -1 c = 4
0 + 4 * 0 - 4 / --b % c++
a = 4 b = -1 c = 4
a = 4 b = -1 c = 4
0 + 4 * 0 - 4 / -2 % c++
a = 4 b = -2 c = 4
a = 4 b = -2 c = 4
0 + 4 * 0 - 4 / -2 % 4
a = 4 b = -2 c = 5
Now, the resulting expression is evaluated according to the rules of precedence of
mathematical operators.
0 + ( 4 * 0 ) - 4 / -2 % 4
0 + 0 - ( 4 / -2 ) % 4
0 + 0 - ( -2 % 4 )
(0+0)-2
(0-2)
-2

Overloading Constructors and Methods


When more than a single constructor is defined in a class, it is known as constructor
overloading. Similarly, when more than one method with the same name is defined in the
same class, it is known as method overloading. However, there is a restriction on such

335

overloading. Constructors or methods can be overloaded only in a way that would allow
calls to these constructors or methods to be resolved i.e. when an overloaded method is
invoked, the compiler should be able to decide which of the overloaded methods is to be
called by checking the arguments. For example consider an overloaded method print()
having two versions. The first of these does not take any arguments while the second one
takes a single argument. A statement like the following is a call to definitely the second
version of the overloaded method which requires a single String argument.
print ( "example");
However, if both the versions of the overloaded methods take a single String argument,
then the call is non resolvable. A statement like the above could be a call to either the first
or to the second version of the method. Therefore, the overloaded methods here would give
compilation errors. In short, it can be stated that overloading of methods or constructors can
be done only if the parameter list varies in atleast one of the following things: number of
arguments, types of arguments or order of arguments. The return types of the overloaded
method doesn't matter.
Methods calls to overloaded versions are resolved by looking at the above stated three
parameters. Following statements shows a few sets of overloaded methods and also
specify if that particular set is allowed in a single class. The reason is also stated in each
case.
Set 1:
public void print()
public void print ( String str)
This set is allowed since the number of arguments differ in the two cases.
Set 2:
public void print ( int a)
public void print ( String s)
This set is also allowed since the type of parameters are different even though the number
of arguments are the same. One of the overloaded versions of print accepts an integer
argument while the other accepts a String argument.
Set 3:
public void print ( int x )
public void print ( int y)

336

This set may appear as acceptable at the first look but it is not. These versions do not differ
in either the number, order or type of arguments. The variable name in the parameter list
doesn't really matter. For example, consider the following call:
print(34);
This might be a call to either the first method or the second method. Hence this set is not
allowed. The ultimate rule to check the validity of overloaded methods is to see if a method
call is resolvable i.e. there should be a one to one correspondence between a method call
and a method. A method call should always point to a single method and there should be no
doubt as to which of the methods would be called.
Set 4:
public void print ( int a, String s)
public void print ( String s, int a )
This set is an acceptable set for overloading the methods since the parameters differ in the
order in which they are specified even though the number and type of parameters is the
same.
Set 5:
public void print ( int a)
public int print ( int a)
The above sets of methods cannot be declared in the same class. As already said, the
return type doesn't matter when deciding the mutual co-existence of overloaded methods.
One might argue that the call can be resolved depending on whether the call requires a
value to be returned. But such an argument isn't valid because, it isn't necessary that a
returned value should always be used in one or the other way. Consider the following
method call.
print(34);
Looking at this call, one can't say that the print() method doesn't return a value. If we had
only the second version of print (the one that returns an int) out of the two stated versions
above, that version would be the one to be called. The returned int would be simply ignored.
In short, values returned by a method need not always be put to use and therefore the
return type isn't checked to verify the validity of overloaded methods. In a similar way, we
can check the extent to which we can overload constructors for a class.

337

The following class contains overloaded versions of the method findVolume(): the first
overloaded version calculates the volume of a cube, the second one calculates the volume
of a cylinder and the third calculates the volume of a cuboid.
class Volume {
public void findVolume ( int s) {
System.out.println ( "Volume of cube is "+ ( s * s * s ) );
}
public void findVolume ( int r, int h ) {
System.out.println ( "Volume of cylinder is "+ ( 3.14 * r * r * h) );
}
public void findVolume ( int l, int b, int h) {
System.out.println ("Volume of cuboid is " + ( l * b * h ) );
}
}
And here is a test class
class VolumeTest {
public static void main(String[] args) {
Volume v=new Volume();
v.findVolume(3);
v.findVolume(3,4);
v.findVolume(3,4,7);
}
}
The output is
Volume of cube is 27
Volume of cylinder is 113.03999999999999
Volume of cuboid is 84
One particular thing is to be noted here. We have always called the method findVolume()
not bothering if the call would be diverted to the method intended for the cube, cylinder or
cuboid. If Java hadn't supported method overloading, there would have been a need to
write different names for each method. Remembering all those names and calling the
correct version might not always be convenient. Method overloading is one of the ways by
which Java implements polymorphism which is the ability to pass the same message and

338

still receive the correct response. In this particular example, the message passed was the
same i.e. findVolume() and the result was the required one in all the three cases.
As already said, when resolving method calls to overloaded methods, the data types of
arguments passed are verified against the data types of the parameters specified in the
parameter list of the methods. This match between the arguments and the parameters need
not be always exact. Automatic type casting takes place if no exact match is found. Casting
always occurs to higher data types. For example, a byte may be cast into an int but an int is
never cast into an int. The former is known as up casting ( casting to higher data types)
while the latter is known as down casting ( casting to lower data types). For instance
consider the following statements:
byte b = 3;
v.findVolume(b);
This particular method call doesn't match with any of the overloaded versions but still the
first version would be called. This is because of automatic type casting. The byte is first cast
to a short and checked if the method call is resolvable. As no match occurs even after
casting to a short, the short is further casted to an int. Now, a match occurs with the first
version of the method and hence the call gets diverted to it.
If in the above example, we had two versions of findVolume() method, which accept a single
parameter as shown below; one of them accepting short and the other an int; the method
call above would call the version that accepts a short. This is because casting takes place in
gradual steps to higher levels. Once a match is found, casting to higher data types is
halted.
findVolume ( short a) // version 1
findVolume ( int a) // version 2
byte a=4;
v.findVolume(a); // version 1 is called and not version 2
There is another rule which determines the method to be called during automatic type
casting: when the method call contains more than one parameter, after casting either of the
arguments, the method calls should match with only on of the overloaded versions.
Otherwise compilation fails. For example, consider that we have the following two versions
of a method print:
public void print ( int a, byte b)
public void print ( byte a, int b)
And we have the following method call

339

byte a=3,b=4;
print(a,b);
No exact match is found for the above method call and the call is not resolvable even after
casting. The reason is that if a is casted to an int and b is left as a byte, then the call would
be to the first version of the method print(). However, if b is cast to an int and a is left as a
byte, the call would be to the second version of the method. There is no reason why either
the variable a or the variable b needs to be casted to an int in preference to the other.
Hence, the call is non resolvable and would generate a compilation error.

Static Methods and Variables


Variables and methods of the Student class which we have written can be accessed only
after creating an object of that class. Write a test program with a main method containing
the following line.
Student.printDetails();
You will receive a compilation error saying that a non static method cannot be referenced
from a static context. This is what we are going to deal with static and non static variables
and methods.
When a variable or a method is not defined used the static keyword, it cannot be accessed
by specifying the class name and the dot operator followed by the variable or method name.
This is because such items are said to belong to objects which would be instantiated from
those classes. Every object would have its own copy of those variables. The class as such
doesn't possess that particular variable. On the other hand, when something is defined as
static, the particular entity, be it a method or a variable belongs to the class itself. There
would be only one copy of that static member and all the objects would be sharing it. These
static members can be accessed directly without creating an object. We have use the static
method main a number of times in our program. Recall that we have never created the
'HelloWorld' object but still the program had run. This is because the method main() was
declared static. We shall now take a deeper look at static variables and static methods.

Static variables
A variable can be declared as static by using the static keyword in the following way.
static int a;
Such variables can be defined only in a class. The keyword static cannot be used for
variables that would be declared in methods. Further, a static variable is set to its default

340

value. There is no need to explicitly specify it. However, we are free to initialise it with some
other value if we wish to do so.
static int a = 34;
These static members can be accessed through the class as well as through objects
created from the class. Further, there would be only one copy of static variables. All objects
would be sharing the same copy. The following program illustrates the use of static
variables through the use of a class Number which contains a static variable x and a non
static variable y.
public class Number {
static int x; // x will be initialized to its default value 0
int y; // non static variable

Following is the test class.


public class Test {
public static void main ( String args[] ) {
System.out.println ( Number.x );
Number.x=34; // accessing static variable through class name
Number num1 =new Number ();
num1.y=3;
System.out.println ( num1.x );
System.out.println( num1.y );
num1.x = 347; // accessing static variable through an object
System.out.println(Number.x);
Number num2 = new Number ();
num2.y=4;
System.out.println ( num2.x );
System.out.println( num2.y );
num2.y=3479;
// The three statements below print the same value as there is only one copy of a static
variable which is shared by all the objects
System.out.println ( Number.x );
System.out.println ( num1.x );
System.out.println ( num2.x );
}
}

341

The output would be:


0
34
3
347
347
4
347
347
347
The above program shows that a static variable can be accessed by using the class name,
or through an object of that class. Also, there is only one copy of the static variable. That
was the reason why the change made through Number.x was reflected on the x that was
accessed through num1 also. Further, the static variable was set to zero by default as is
evident in the first line of output.

Static methods
Similar to static variables, we have static functions also. Functions or methods are declared
as static by specifying the static keyword. A static method can be called either using the
class name or the object name. A static function can access only other static members
(variables or methods). Attempting to access non static members will result in errors.
Following program shows the usage of static functions.
public class Number {
static int x = 7;
int y;
public static void a () {
System.out.println ( "static a() ");
}
public void b () {
System.out.println ( "b() ");
}
public static void c () {
System.out.println ( "x is "+x); // static variable a can be accessed
a() ; // static method a() can be accessed
/*

342

y = 34; // non static variable y cannot be accessed in static method


b(); // non static method b() cannot be accessed in static method
*/
}
}
public class Test{
public static void main(String[] args) {
Number.c(); // accessing static method using class name
Number n=new Number();
n.c(); // accessing static method using object
}
}
Output:
x is 7
static a()
x is 7
static a()
Invalid code in Number class has been commented out using a multi-line comment. The
code contained in that Comment is invalid since an attempt was made to access non static
methods and variables from a static method. The Test class shows how static methods can
be accessed using both the class name and method name.

this Keyword
The this keyword in Java returns a reference to the object on which the method being
executed is invoked. We can use the returned reference to access the variables and
methods of the object. Look at the following example where the this keyword is used in a
constructor
class Student {
String name;
public Student ( String name ) {
this.name = name;
}
}

343

As we know, a constructor is used to create the object of the class. So, the keyword this
returns a reference to the object being created. Therefore, this.name refers to the instance
variable 'name' which is assigned with the 'name' passed to the constructor. We could have
of course written the constructor as we would have normally written in the following way:
public Student ( String n ) {

name = n; }

But, in this case, a person who is reading the code wouldn't know what n is unless he
continues to the next line. So, the use of this keyword is justified in the constructors of a
class.
The this keyword is also used to access instance variables that have been hidden by local
variables. We have read that a variable can be declared only once. However, there is an
exception to this. We can declare an instance variable and a local variable (for example, a
variable in a method) with the same name. When we use the variable name in the method
body, we get the value which the local variable points at. In effect, the local variable has
hidden the instance variable.
public class Student {
int marks = 34;
public void newMarks () {
int marks = 100;
System.out.println ( marks );
}
}
The method newMarks() in the above program would print the integer 100 and not the
integer 34. This is because the local variable marks has hidden the instance variable marks.
In order the access the hidden variable, we make use of the this keyword in the following
way.
System.out.println ( "Old marks: " + this. Marks ); // prints 34
The this keyword has returned a reference to the object and therefore marks accessed
through the this keyword refers to the marks that was declared as an instance variable.
The this keyword is also used to call one constructor from another. This is quite helpful in
reducing code work when a number of instance variables are declared in a class and there
is a necessity to provide a number of constructors which would be able to create objects of
that class whether all the necessary parameters have been passed or not. In simpler terms,
creation of the object should be made more flexible. The user should be allowed to go

344

ahead, whatever be the information he possesses, be it only the name and rollNumber, just
the rollNumber or all the details. Look at the following example of the Student class.
class Student {
String name;
int rollNumber;
int marks1, marks2, marks3;
public Student ( String name, String rollNumber, int marks1, int marks2, int marks3 ) {
this.name = name;
this. rollNumber = rollNumber;
this.marks1= marks1;
this.marks2 = marks2;
this.marks3= marks3;
}
public Student ( String name, int rollNumber ) {
this ( name, rollNumber, -1,-1, -1 );
}
public Student ( String rollNumber ) {
this ( null, rollNumber );
}
}
When we create an object of the Student class in the following way, the second constructor
would be invoked which would then invoke the first constructor.
Student s= new Student( "Sai", 34);
And, if we use the following statement, all the three constructors would be called in effect.
We are actually making call to the third constructor, which then calls the second which in
turn calls the first.
Student s= new Student (34);
An important thing to be remembered when calling other constructors using the keyword
this, is that such a call should be the first statement in the constructor. The following code,
for instance would result in an error:
public Student () {
System.out.println ("No argument constructor called"); // incorrect
this(-1); }

345

Wrapper Classes
As we have already seen, a variable of primitive data type is by default passed by value and
not by reference. Quite often, there might arise the need to consider such variables of
primitive data type as reference types. The solution to this lies in the wrapper classes
provided by Java. These classes are used to wrap the data in a new object which contains
the value of that variable. This object can then be used in a way similar to how other objects
are used. For example, we wrap the number 34 in an Integer object in the following way:
Integer intObject = new Integer (34);
The Integer class is the wrapper class that has been provided for the int data type. Similarly,
there are wrapper classes for the other data types too. The following table lists the data
types and their corresponding wrapper classes.
Data Type

Wrapper Class

byte

Byte

short

Short

int

Integer

long

Long

float

Float

double

Double

char

Character

boolean

Boolean

Note that the wrapper classes of all the primitive data types except int and char have the
same name as that of the data type.
A wrapper class also contains a number of other different methods which may be used in
the processing of variables of the corresponding data type. For example, the Character
wrapper class contains methods which can be used to check if a character is a digit or a
letter or a whitespace and so on.

Creating objects of the Wrapper classes


All the wrapper classes have constructors which can be used to create the corresponding
Wrapper class objects by passing either a String or a variable of the same data type as that
of the type to which the wrapper class corresponds, except for the Character wrapper class
whose object cannot be created with a String. Also, the Float wrapper class allows its object
to be created using a double value.

346

For example, we can create an Integer object which wraps the int 34 in either of the
following two ways:
Integer intObject = new Integer (34);
Integer intObject = new Integer ( "34");

Retrieving the value wrapped by a wrapper class object


Each of the eight wrapper classes have a method to retrieve the value that was wrapped in
the object. These methods have the form *Value() where star refers to the corresponding
data type. For example, to retrieve the value stored in the Integer object intObject, we use
the following statement.
int x = intObject.intValue();
Similarly, we have methods for the other seven wrapper classes: byteValue(), shortValue(),
longValue(), floatValue(), doubleValue(), charValue(), booleanValue().

Auto boxing and auto unboxing


Creating a wrapper class object using the constructors and retrieving the values wrapped by
those objects using the methods as shown above can become quite cumbersome. As an
alternative, there exists auto boxing and uutounboxing. Auto boxing refers to an implicit call
to the constructor and auto unboxing refers to an implicit call to the *value() method.
Therefore, a new wrapper object can be created by specifying the value to be wrapped just
as we would do for a primitive data type variable. Also, the value can be retrieved and used
in a simple way by specifying the object name. Look at the following code:
Integer intObject = 34;
int x=intObject;
int x = intObject + 7;
The above statements are equivalent to the following set of statements
Integer intObject = new Integer (34);
int x = intObject.intValue();
int x = intObject .intValue()+ 7;
Similarly, auto boxing and auto boxing apply to other wrapper classes also.

Conversion between data types


The wrapper classes also provide methods which can be used to convert a String to any of
the primitive data types, except character. All these methods are static. These methods

347

have the format parse*() where * refers to any of the primitive data types except char. And
to convert any of the primitive data type value to a String, we use the valueOf() methods of
the String class which through method overloading and implicit casting can accept any of
the eight primitive types.
int x = Integer.parseInt("34"); // x=34
double y = Double.parseDouble("34.7"); // y =34.7
String s1= String.valueOf('a'); // s1="a"
String s2=String.valueOf(true); // s2="true"

Control Statements
All the programs we have written till now had a sequential flow of control i.e. the statements
were executed line by line from the top to bottom in an order. Nowhere were any statements
skipped or a statement executed more than once. We will now look into how this can be
achieved using control structures. These control structures can be classified into three
groups: Decision making statements, repetition statements and branching statements.
Decision making statements are used to decide whether or not a particular statement or a
group of statements should be executed. Repetition statements are used to execute a
statement or a group of statements more than once. Branching statements are used to
transfer control to another line in the code. We shall look into the syntaxes of these
structures first and then see how we formulate algorithms using these statements.
We have already seen the if statement and the if else statement while writing the set
methods for our Student class. The if statement is used to selectively execute a statement
or a block of statements. The if statement contains a condition which decides whether or not
the statements would be executed. If the condition stated in the parentheses evaluates to
true, then the statements are executed, otherwise the statements in the if block are skipped.
Conditions, as we have already seen are built using conditional and relational operators.
Following is the syntax of the if statement.
if ( condition ) {
// code
}
And here is a small code snippet which displays the message "Hi" only if the value of the
boolean variable wish is true.
if ( wish == true ) {
System.out.println("Hi");
}

348

In the above code snippet, the braces could have been omitted. Braces are not required
when the block consists of only a single statement. But we recommend that braces always
be placed. This ensures that mistakes won't creep into the code when you modify your
program at a later time to add another statement to the if block forgetting to insert the
necessary braces. Moreover the condition 'wish==true' could have also been written as
'wish'. Both are equivalent and perform the same condition check.
The if statement is known as a single selection structure since we have only a single
statement that is either executed or not. No alternative statement would be executed if the
condition evaluates to false. For such purpose, we have the if else double selection
structure. If the condition is true, the if block will be executed. Otherwise, the else block will
be executed. Following is the syntax of if else structure.
if ( condition ) {
// code
} else {
// code
}
And here is an example usage which states whether a number is an even number or an odd
number. Even numbers are divisible by zero and hence leave a remainder of zero. The
remainder on dividing the number by two can be obtained using the modulo (%)
mathematical operator.
if ( num%2==0){
System.out.println("Number is even");
}else{
System.out.println("Number is odd");
}
if else statements can be nested. That is the statements block of an if or else can in turn
contain another if else structure. And moreover, an else is always associated with the
immediately preceding else. These two concepts are used to form a chained if else
structure in which only one of the several alternatives is executed. Look at the following
code where if else structures have been nested to print the number stored in the int num in
words when the value of num is between one and three. If the number falls outside this
range, an appropriate message is displayed.
if (num == 1) {
System.out.println("One");
} else {
if (num == 2) {
System.out.println("Two");

349

} else {
if (num == 3) {
System.out.println("Three");
} else {
System.out.println("Numbers greater than three cannot be processed by this code");
}
}
}
This code looks highly unreadable. One thing that we can do is to remove the redundant
braces since each of the blocks contain no more than one statement. You may be hesitant
to perform this action with the first else statement since it contains more than a single line of
code. But all that would still fall under the else statement even if we remove the braces. This
is because the statement within the if block is associated with the if header and the
succeeding else is associated with the if block. So the entire block will be associated with
the else even if no braces are used. So, after we remove the braces, this is what we are left
with. We have also written the words if and else on the same line.
if (num == 1) {
System.out.println("One");
} else if (num == 2) {
System.out.println("Two");
} else if (num == 3) {
System.out.println("Three");
} else {
System.out.println("Numbers greater than three cannot be processed by this code");
}
This code looks much better than the earlier once. This is what we refer to as chained if
else structure formed using a number of if and else statements. Only one out of the four
statements will be executed depending on the value of num. Once a particular statement is
executed, the remaining ones would be ignored. This chained control structure is quite
frequently used.
We could have used a set of four if statements instead of the above chained sequence but
that that code would take a longer time to execute. This is because all the conditions would
be checked. But in this chained structure, one a condition evaluates to true, all other
statements are skipped which would reduce processing time, hence, making the code more
efficient.
As already said, an else is associated with the immediately preceding if. Indenting the code
by using tabs has no effect on how the code works. Assuming that the indentation matters
may lead to errors in programming. Consider the following code:

350

if(x>3)
if(y>3)
System.out.println("Both x and y are greater than 3");
else
System.out.println("x is not greater than 3");
By looking at the indentation one might be tempted to say that the last else is associated to
the first if. But this is erroneous since an else if always associated with the immediately
preceding if unless braces are used to associate the else with a different if. This problem of
which if the final else is to be associated is known as the dangling else problem. If we
wrongfully assume that indentation matters, the result obtained would be incorrect. Include
the above code in a program and set x and y to 2. According to what one might think, the
statement "x is not greater than 3" is not printed. Given below is a corrected version of the
above code.
if(x>3) {
if(y>3)
System.out.println("Both x and y are greater than 3");
} else
System.out.println("x is not greater than 3");
In order to avoid such trivial mistakes, always use braces unless you are writing a chained if
else structure in the case of which using braces makes the code clumsy and hard to
decipher.
Apart from the if and else statements, we have the switch structure. The switch control
structure however cannot be used in the situations where the condition needs to contain
relational operators like greater than, less than and so on. The switch structure can only be
used to check for equality. Given below is the syntax of the switch structure in Java.
switch ( expression )
{
case value1 :
// code
break;
case value2:
// code
break;
...
...
case valueN:
// code
break;
...

351

...
default:
// code
break;
}
The expression should evaluate to one of the following types: byte, short, int, char, String.
This value is compared with each of the case values ( value1, value2,... valueN). When a
match is found, the statements under that particular case label are executed. Strings are
checked for equality by invoking the equals() method and not by using the == operator
which is the used for the other data types. If no match is found, the statements under the
default label are executed. The break keyword is used to transfer control outside the switch
block. If the break keyword is omitted, the statements under the other case labels are also
excited whether or not the case value matches. This might be useful in certain situations
which we will look into shortly. The last break under the default label is optional as on
reaching the line, the control has to anyway move out of the switch block. All the case
values should be unique. Duplicates are not allowed. Also note that braces are not required
even if we wish to include more than one statement in a particular case label. However,
using them doesn't make any difference. Given below is an example which prints the day of
the week based on the value stored in the int variable num. 1 stands for Sunday, 2 for
Monday and so on:
int day = s.nextInt; // s is a Scanner object connected to System.in
String str; // stores the day in words
switch(day)
{
case 1:
str="Sunday";
break;
case 2:
str="Monday";
break;
case 3:
str="Tuesday";
break;
case 4:
str="Wednesday";
break;
case 5:
str="Thursday";
break;
case 6:
str="Friday";

352

break;
case 7:
str="Saturday";
break;
default:
str=" Invalid day";
}
System.out.println(str);
The value stored in day is compared with each of the case values 1 to 7. If a match is
found, the statements under the corresponding case label are executed. And since, break is
encountered, the remainder of the code in the switch structure so skipped. If the value
stored in day does not fall in the range 1-7, the default statement is executed.
As already said, at times, there might be a need to omit the break statement under certain
situations where we want the same set of statements to be executed as a target of more
than a single case label. Look at the following example where the season is printed
deepening on the month.
switch(month)
{
case 12:
case 1:
case 2:
System.out.println(" Winter");
break:
case 3:
case 4:
case 5:
System.out.println(" Spring");
break:
case 6:
case 7:
case 8:
System.out.println(" Summer");
break:
case 9:
case 10:
case 11:
System.out.println(" Autumn");
break:
default:
System.out.println(" Invalid month");
}

353

Suppose we have the value of month as 4. This value would be compared each of the case
values 12 to 4. The value of month equals the case value 4. Therefore statements under
this case label would be executed until a break is encountered. However, note that in the
statements that follow, the value of month is not compared with any of the case values. In
this example, the value of month would not be compared with 5. The next print() statement
is executed. After this, the break statement is encountered because of which, control shifts
outside the switch structure.
The last of the decision making statements is the ternary operator which provides a concise
form for short and simple if lese statements. The ternary operator is represented by ?:
Following is the syntax of ternary operator:
expression1 ? expreession2 : expression3
If expression1 evaluates to true, then expression 2 is evaluated, otherwise expression 3 is
evaluated. The ternary operators can be used as a standalone statement or in conjugation
with other statements like declaration and print statements. Following examples illustrate
the use of ternary operator:
Example 1: The value of s (an int ) is either incremented or decrement based on whether it
is a positive integer or not.
s>0 ? s++ : s-- ;
If s is 3, then s is incremented to 4. If s is 0, it is decremented to -1.
Example 2: Division
If the divisor is zero, then the quotient is set to zero, otherwise division is performed and the
quotient is stored in the variable res. a and b are the dividend and divisor respectively.
int res = b==0 ? 0 : a/b;
if b is zero, then the expression b==0 evaluates to true, hence the first expression is
evaluated. 0 is the result of the ternary operation which is assigned to res.
If b is non zero, expression1 evaluates to true. Hence expression 3 is evaluated i.e. the
ternary operation returns the result of dividing a by b. This returned value is assigned to
num.
Example 3: Ternary operator in print statements
The following statement prints either "Positive "or "Non positive "depending on the value of
num.

354

System.out.println( num?0:"Positive":"Non positive");


Example 4: Passing arguments to methods
The following statement passes the value 3 or 0 to the method Math.sqrt() depending on the
result of the .equals() method call on str.
double root = Math.sqrt ( str.equals("three") ? 3: 0 );
if str equals "three", then the expression evaluates to zero because of which the ternary
operator returns 3 which is passed as an argument to Math.sqrt() function. In other cases, 0
is passed to the function.
An important thing to be kept in mind while using control structures is that any variable that
is declared within a block is not visible outside that block. If results processed within such
blocks are to be accessible outside the blocks, then such values should be stored in
variables that have been declared outside the blocks.
Look at the following code:
if ( num % 2 == 0){
boolean res =true;
} else {
boolean res = false;
}
System.out.println(res);
The above code would produce compilation errors. Given below is a corrected version of
the baove code.
boolean res;
if ( num % 2 == 0) {
res = true;
} else {
res = false;
}
System.out.println(res);

Repetition Statements
Java provides three repetitions structures: while, do while and for. These statements are
also known as loops. We shall look into the syntaxes of these structures first and also learn
how we can formulate algorithms using these loops.

355

The while loop


Following is the syntax of the while loop. The statements in the while block are executed as
long as the condition evaluates to true.
while ( condition ) {
// code
}
For this loop to end, the condition should at some point of time become false. This is
achieved using counters. Counters are simple variables which are incremented (or
changed) every time the body of the loop is executed. They are used to keep track of the
number of times the loop is executed. The value of counter is used in the conditional
expression to determine the end of the loop. Consider the following code snippet which is
used to print the statement "Hi" thrice on the screen.
int ctr = 0;
while (ctr < 3 ) {
System.out.println("Hi");
ctr++;
}
The value of the integer variable ctr is first set to zero. When control enter the while
statement, the condition ctr<3 is evaluated. Since 0<3 is true, the body of the loop is
executed. The statement "Hi" is printed and ctr is incremented to 1. The condition is
evaluated again. ctr < 3 is still true. The body of the loop is again executed. In this way, the
while loop executes thrice after which ctr becomes 3. Now, since the condition 3< 3
evaluates to false, control moves out of the while loop. In the above program, we can
eliminate the ctr++; statement and include it in the while condition itself by using increment
operator. But be careful while deciding whether pre increment or post increment should be
used.
int ctr = 0;
while (ctr++ < 3 ) {
System.out.println("Hi");
}
We also quite often use the value of the counter as a part of our code. For example, the
following code is used to add the numbers from 1 to 100.
int ctr = 1; sum =0;
while (ctr<=100) {
sum = sum + ctr;

356

ctr++;
}
Always use integers (byte, short, int or long) variables as counters. Never use floating point
numbers to control loops since floating point numbers are not accurate values. For
example, the floating point constants 3.4 is not exactly the value 3.4 but is an approximation
of some other closer value like 3.39999999999.....
Following program shows how the output produces will be incorrect when using floating
point constants. The actual purpose of the program was to print the floating point numbers
0.1, 0.2, 0.3 ....1.0 on the screen but the result produced was different.
double ctr = 0.1;
while (ctr <= 1) {
System.out.println(ctr);
ctr = ctr + 0.1;
}
Output:
0.1
0.2
0.30000000000000004
0.4
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999
As you can see, instead of displaying 0.3, 0.30000000000000004 was displayed and similar
is the case with the last three numbers. Similar would have been the case if we used ctr to
print some statement a predefined number of times.
While loop is an entry control loop which means that the condition is checked before
entering the body of the loop. Therefore, it might be possible that the body of the loop is not
executed even once. For example, if we set the condition in the above examples to str<0,
the loop is not executed even once. In contrast, we have the exit control loops in which the
condition is checked after executing the body of the loop because of which the loop is
executed atleast once. Following is the syntax of the do while loop:

357

do {
// code
} while ( condition );
Note that there is a semicolon after the while statement. Following code uses the do while
loop to print "Hi" thrice on the screen.
int ctr = 0;
do {
System.out.println("Hi");
ctr++;
} while (ctr < 3);
The last of the repetition statements is the for loop which provides a more convenient way
to handle counters in loops. Following is the syntax of a for loop:
for ( initialization; condition; increment/ decrement ) {
// body
}
The for header has three parts namely initialisation, condition and increment/ decrement.
The initialisation part is used to declare and initialise loop control variables or any other
necessary variables before entering into the loop. The condition is checked before
executing the loop and the increment/ decrement part is executed after each time the body
of the for loop is executed. The third part of the for header can also contain statements
other than increment and decrement operations. The above for loop is equivalent to the
following while loop.
initialisation;
while ( condition ) {
// body
increment / decrement;
}
However, there is major difference between these two loops. Variables that are declared in
the for header have a scope and lifetime that is limited to the body of the for loop. These
variables are not accessible once we come out of the for loop. This is one reason why for
loops are preferred over while loops.
Following code prints the numbers from 1 to 10 using a for loop.
for ( int i=1; i<=10; i++) {
System.out.println(i);
}

358

We generally use the identifiers I, j, k for loop control variables. We may also, declare these
variables outside the for loop if the value of this counter if required after control moves out
of the for loop.
int i;
for (i=1; i<=10; i++) {
System.out.println(i);
System.out.println("The value of i was "+i +"when the loop condition evaluated to false");
}
The above code will display the statement "The value of i was 11 when the loop condition
evaluated to false" in addition to printing the numbers from 1 to 10. If the variable i was
declared in the for header itself, the above print statement would have produced a
compilation error.
We may declare more than a single variable in the initialisation part of the header. However,
each of these variables should have the same data type and they should have not been
declared earlier. The following for header declares and initialises two variables i and j.
for ( int i= 0, j=10; // code; // code )
Here are the various formats of the initialisation part that are allowed:
< variable name > = <value >
< data type > < variable name > = < value >
< data type > < variable name 1 > = < value (optional) > , < variable name 2 > = < value (
optional ) >, ...... <variable name n > = < value ( optional ).....
The increment decrement part can contain more than one statement. These are separated
by a comma and not by a semicolon. Generally, we use this part only to increment or
decrement variables, though other statements are also allowed.
for ( // code; // code; i++, j++, k+=5 ) {
//code
}
It is not necessary that all the three parts of the for header have to be present. One or all of
them may be skipped. Following shows a for header in which only the condition part is
specified. The other two parts are left empty.
for( ; i<=10; ) {
// code
}

359

In all the above three decision making statements, if the condition is left empty, it is taken as
true. Such a loop keeps executing for ever and is known as an infinite loop.
while ( ) {
// code
}
Infinite loops may also result even after specifying the condition as in the following
example:
for ( int i=1; i <= 10 ;i--) {
System.out.println(i);
}
Infinite loops are considered to be logical errors. There would be no reason as to why a
programmer wishes to run a loop for ever. This would eventually cause the system to crash.
Infinite loops result from trivial mistakes. For example, in the just preceding example, i++
was replaced with i-- which caused the loop to run continuously. Loops that do not have a
body are known as empty loops. For example, the following while loop is an empty loop:
while ( ctr++<10 ) {
}
We may also write this loop in the following way:
while ( ctr++ < 10 ) ;
The above statement is equivalent to the following which contains an empty statement. As
stated already, whitespaces do not matter in a program.
while ( ctr++< 10 )
;
Control statements may be nested within one another. An if else structure may be written
inside a for loop, a for loop can contain another for loop which in turn can contain one more
for loop and so on...

Nested Loops
Nested loops are quite helpful in processing information. We will learn how nested loops are
used by taking the example of a pattern problem. An integer value is to be taken as an input
from the user and the following pattern is to be printed based on the input. If the input is
seven, the following pattern needs to be printed.

360

*
**
***
****
*****
******
*******
One thing that is obvious on observing this pattern is that loops are used to print the pattern.
This is because, we are not aware in advance of the number of *'s that are to be printed.
Further, we need nested loops: a for loop nested within another for loop. the outer for loop
keeps track of the line number. Or, in other words, it is used to count the number of lines we
are printing. The inner for loop is used to keep track of the number of *'s we are printing.
Urther, the number of stars on a particular line is equal to the number line number which in
some way can be realted to the outer loop control variable. keeping these things in mind,
we can write the following code which prints this pattern. The number n is atken as an input
from the user:
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
Note that we have used the print() method and not the println() method to display the stars
as we want the *'s to be displayed on the same line. And after the inner loop is executed,
we go to the next line using the println() statement.

Formulating Algorithms
Now that we have learnt about two of the control structures, we shall see how we can
formulate algorithms using theses structures. We do have another group of control
structures- branching statements, about which we shall see later on. We have two basic
approaches, each of which is used for a particular situation. The first is counter controlled
repetition and the other is sentinel controlled repetition. Counter control repetition is
followed when we know in advance the number of times the loop has to be executed while
the sentinel controlled approach is taken when this number is not known before entering the
loop. We will deal with the problem of adding numbers to understand these two
approaches.

Counter Controlled Repetition

361

We have already used controlled repetition when discussing the basics of loops. This
example would make the approach more clear. This is the problem: the number of numbers
to be added is to be first taken as an input. The user is then prompted for the numbers
which will be added by the program. The sum of the numbers entered is then displayed on
the screen. This is the program which performs the task:
import java.util.Scanner;
public class AddNumbers {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the number of numbers that you wish to add: ");
int count = s.nextInt();
int sum = 0;
for (int i = 1; i <= count; i++) {
System.out.print("Enter number " + i + ": ");
sum = sum + s.nextInt();
}
System.out.println("The sum of the numbers is " + sum);
}
}
Given below is a sample output:
Enter the number of numbers that you wish to add: 4
Enter number 1: 34
Enter number 2: 7
Enter number 3: 4
Enter number 4: 347
The sum of the numbers is 392
As you can see in the program above, we have taken the count as an input from the user.
The loop is executed these many number of times. A counter, i is used to keep track of the
number of numbers that have been added. Each time, the value of i is also displayed along
with a prompt for the number. Within the for loop itself, the number taken as input is added
to sum.

Sentinel Controlled Repetition


Sentinel is a value which the user enters to indicate that there is no more input to be given
to the program. For example, you can take input from the user as long as he doesn't enter
the number 0. In that case,0 is called the sentinel since entering this value causes to the

362

program to stop taking the input. Given below is a program which uses a while loop driven
by a sentinel to calculate the sum of numbers entered by the user.
import java.util.Scanner;
public class AddNumbers {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
int sum = 0;
int num;
do {
System.out.print("Enter a number (0 to stop): ");
num=s.nextInt();
sum=sum+num;
}while(num!=0);
System.out.println("The sum of the numbers is " + sum);
}
}
And here is a sample output:
Enter a number (0 to stop): 3
Enter a number (0 to stop): 4
Enter a number (0 to stop): 7
Enter a number (0 to stop): 34
Enter a number (0 to stop): 0
The sum of the numbers is 48
Note that we have used a do while loop instead of a while loop or a for loop. We could have
used them also and modified the program accordingly. In this particular program, we are
first adding the number entered by the user to sum and then checking if it is the sentinel.
Since the sentinel is 0, it doesn't make any difference if we add the number first and then
check or check the number and then add it to sum. However, if the sentinel is another value
like -1, then the order does matter. In that case, we can take several approaches. One is to
subtract the sentinel from the sum after coming out of the loop and before displaying the
sum. But this doesn't look quite good and therefore we present below, a few alternate
versions to be used when the sentinel is a value other than 0.
Version 1:
int sum = 0;
int num = 0;
do {

363

sum = sum + num;


System.out.print("Enter a number (0 to stop): ");
num = s.nextInt();
} while (num != 0);
Version 2:
int sum = 0;
System.out.print("Enter a number (0 to stop): ");
int num = s.nextInt();
while (num != 0) {
sum = sum + num;
System.out.print("Enter a number (0 to stop): ");
num = s.nextInt();
}
Out of all the above versions, the preferred is the last one. This is because in all other
cases, we need to know the identity number which when accumulated with the existing
result doesn't change the value of result. In this particular case, where we are adding
numbers, that number is 0. If we were to multiply the numbers entered instead of adding
them, we would have initialised num to 1. But for an operation whose identity value isn't
known, version 2 is the only approach that can be taken.

Branching Statements
We will now look at the last set of control statements in Java- branching statements. They
are used to transfer control to another point in the code. Java's branching statements are
defined by the three keywords- break, continue and return. The break and continue
statements have two forms: the labelled form and the unlabelled form. We shall now look at
each one of them in detail.
Java's break statement is used to exit out of a loop. We have already seen the use of the
break statement in the switch structure. We shall now see their use in loops. break is
normally executed as a target of a decision making statement like if. Look at the following
for loop which should actually print the integers from one to seven. However, because of the
break statement that is associated with an if, only the numbers up to four are printed. When
the break keyword is encountered, controls gets transferred to the end of the loop and
statements following the loop are executed.
for (int i = 1; i <= 7; i++) {
System.out.println(i);
if (i == 4) {
break;

364

}
}
The above code will print the numbers from 1 to 4, one each one line.
1
2
3
4
When loops are nested within one another, the use of break will causes control to move out
of the loop to which the break statement belongs. Look at the following partial code which
contains three loops nested within one another. The break statement is a part of the second
for loop. On encountering it, control shifts to the line indicated by "// control shifts here".
for ( ..... ) {
for ( ..... ) {
for ( ..... ) {
}
if ( ..... ) {
break;
}
}
// control shifts here
}
In the above program, if on encountering the break statement, we want control to be
transferred to the end of the outermost loop instead of the second loop to which the break
statement is associated by default, we use a labelled break statement. Before using it, we
need to define a label. A label is an identifier followed by a colon. A label is associated to
the loop that is defined immediately after the label. When the break is followed by a label,
encountering it will cause the control to be shifted to the exit of the loop corresponding to
that particular label. Look at the first statement where a label named "here" (Label names
should follow the rules of identifiers), is set to be associated with the outer for loop. When
the break statement is encountered in the for loop, control is transferred to the end of the
outer loop instead of the inner loop as a labelled break has been used.
here:
for ( ..... ) {
for ( ..... ) {
if ( ..... ) {
break here;
}

365

}
// control shifts here on encountering the labelled break
You will be able to appreciate the use of these branching statements when we deal with
arrays. However, for the time being, to help you get familiar with the two forms of break
statement's, we present below an example, with has three for loops nested within one
another. We also have a label for each of these for loops. The code is first executed without
any break or continue statements and then, we introduce several break statements, labelled
and unlabelled and show you the outputs.
public class Break Example {
public static void main(String[] args) {
label1:
for (int i = 1; i <= 3; i++) {
label2:
for (int j = 1; j <= 3; j++) {
label3:
for (int k = 1; k <= 3; k++) {
System.out.print(k);
// line1
}
System.out.println();
//line2
}
System.out.println();
//line3
}
}
}
And here is a table. Use it to manipulate the above code by replacing line1, line2 and line3
with the contents of this table. Run your program and match your results with the ones
shown here. Reason out for yourself the logic behind the output. Note that in this example,
we haven't executed break statements as a target of a decision making statement to make
the code simpler.
In certain rows of the above table, we have stated //compilation errors. The code in those
cases is incorrect since we are trying to access labels that are not known in those scopes.
For example, when two loops are nester within one another with the outer loop labelled
outer: and the inner loop labelled inner:. Trying to break to inner within the body of the outer
loop will result in a compilation error.

366

outer:
for ( ..... ) {
inner:
for ( ..... ) {
}
break inner; // error
}
You can try out more combinations for the three lines in the above program by including the
break statements on more than a single line. For your reference, 54 combinations are
possible in all, including the above stated ones. A majority of these would result in
compilation errors.
Now we move on to the continue statement. The continue statement just like the break
statement has two forms. When the continue statement is encountered, the remainder of
the loop in the current iteration is skipped and control passes to the condition of the loops in
while and do while loops while in a for loop, control get transferred to the increment/
decrement part. Given below is a program that prints only positive integers from 1 to 10
using a for loop and the continue statement. The program would of course be much simpler
without the use of continue statement but the purpose of this program is to help you learn
the working of the continue statement rather than code a program to print even numbers.
for (int i = 1; i <= 10; i++) {
if (i % 2 != 0) {
continue;
}
System.out.println(i);
}
Just like the labelled break statement, we also have the labelled continue statement and
this functions in a similar way. Control gets transferred to the corresponding condition (in
case of while and do while) or the increment/ decrement operation (in case of a for loop)
that that belongs to the stated label.
Just like the table above for the break statement, we present below a table for the continue
statement.
Note that the first three sets have the same output. This is because in each of the cases,
whether or not the continue statement is used, the flow of control is the same.
The last among Java's branching statements is the return statement. As we already know,
the return statement is used in methods to optionally return a value and transfer control

367

back to the calling method. To make it more simple and clear, the return statement skips the
remaining of the method. Look at the following code for example:
public class ReturnExample {
public static void main(String[] args) {
meth(true);
System.out.println("end of main");
}
public static void meth(boolean b) {
System.out.println("line1");
if (b) {
return;
}
System.out.println("line2");
System.out.println("line3");
}
}
The output of this program would be:
line1
end of main
When meth() is invoked with a true argument, the return statement is executed. This
statement causes the remaining statements in the method to be skipped and control
transfers back to the calling method. The return statement works in a similar manner when
used with methods except that a value to be returned should also be specified.
As we have already learnt, unreachable code in Java generates compilation errors. For
example any code written after the return statement in a method containing a single return
statement is an unreachable statement. We have already seen this when dealing with get
and set methods. And at that time, you have been promised that you will be shown an
example where such a usage is allowed when decision making statements are used. The
above program is such an example. The statements that print line2 and line3 are not
classified as unreachable even though they will never be executed in this particular
program. This is because they may be executed when meth() is called with a false
argument in another program. Hence, the statements are not unreachable.
This is all that we have about control structures in Java. We will now move to arrays in
which the for loop is widely employed.

368

Arrays
We have seen that variables are used to store data in a Java program. Each variable can
store not more than one data item. What do we do if we wish to store a large number of
data items, say 100. A quick answer from you might be to use 100 variables, one for each
of the 100 data items. But coding wouldn't be as simple as the answer you have given. We
need to write 100 lines of code for setting up these variables and manipulating them would
be quite a difficult task. And if we do not know beforehand, the number of variables that are
required, there seems to be solution from what we have studied till now. The answer to
such a problem lies in arrays. Arrays are the simplest data structure inbuilt into the Java
programming language. Data structures are used to store data in a more efficient way. Data
here refers to a group of data items and not a single data item for the purpose of which
variables are used.
An array is used to store a group of values, all of which have the same data type. All the
elements stored in the arrays are accessed by simply using the variable name and the
index of the element. You can think of an array as a block of cells, each having an index
starting from 0, just as we had seen with Strings. Before we move further into arrays, be
clear of the fact that an array is a reference data type just like a class. They are passed by
reference. They may be considered as reference variables and they have a name which
follows the rules of identifiers.
Here is a graphic representation of an array that contains seven elements, all having the
same data type, int. The length of the array is the number of elements contained in the
array. The length of this particular array, named by us as myArray is 7. The elements have
indices starting from 0 and extending up to 6, which is one subtracted from the length of the
array. (7-1=6). The element at index 0 is 3, the element at index 1 is 34 and so on. We refer
to the elements of the array programmatically as arrayName [ index] as we will see later on.
For instance myArray[0] contains the integer 3.

The data type of an array name is specified as <data type>[] where < data type > refers to
the data type of the elements the array would be storing. The square brackets indicate an
array. The following statements show the declaration of an array named a, which holds int
values.
int [] a;

369

The square brackets may also be placed at the end of the array name, as shown below. It
would make no difference.
int a[];
Just like variables, we may also declare more than one array in a single statement, as
shown below:
int[] a, b, c;
The above statement declares three arrays, a, b and c all of int type. However, be cautious
when using such a notation. In such multiple declaration statements, the square brackets
are placed along with the data type. If we wish to declare a few integer variables and a few
integer arrays in a single statement, we use the following form:
int a[], b, c[];
The above statement declares two integer arrays, a and c and a single integer variable b.
We however recommend that you declare not more than a single array in a statement. Now
that we have declared the array, we need to create an integer array and assign its reference
to the array variable. Just like classes, arrays are created using the new keyword. The new
keyword returns a reference to the array being created which is then assigned to an
appropriate variable. The size of the arrays (or the length, which is the number of elements
the array will hold) is also specified. Following statements creates an array to hold seven
integers and assigns its reference to eth arrays variable a.
a = new int[7];
The size of an array may be specified using integer constants as done above or by using
expression that contain variables. The following array creation statements are also valid.
int size = 7;
a = new int [ size ];
a = new int [ 3+4 ];
a = new int [ size / 3 + 5 ];
As we can specify the size of an array using a variable, arrays can be dynamically created
at run time. In other words, the size of the array can be taken as an input from the user and
an array can be created using the user entered value.
As with variables, the declaration and initialisation of arrays can be combined into s ingle
statement as shown below:
int[] a = new int[7];

370

After an array is created, all the elements are set to their default values. The above array a
has all the seven elements set to 0 implicitly.
Next, we need to access each element of the array and assign it with new int values. Array
elements are accessed by specifying the array variable and the index of the elements. a[0]
refers to the first element of the array. The following statements initialise some of the
elements of the array a.
a[0]=3;
a[1]=34;
a[5]=7;
Elements accessed with the above notation ( a[index] ) may be used just like normal
variables. We may print those values, use them in calculations, pass them as arguments
and so on.
System.out.println( a[1] );
int sum = a[6] + a[5];
double root = Math.sqrt ( a[5] );
When we specify an invalid index such as a negative number ora number hich is greater
than or equal to the length of the array, no compilation errors occur. Rather, a run time
execpetion, anmely ArrayIndexOutOfBoundsException is thrown during runtime. An
exception in Java is an object which indicates an abnormal error. We shall see how to
handle these errors in the chapter on exception handling.
There is one important thing to be noted here. While the array is a reference type, the
elements of the array are not of reference type. a[] is a reference type while a[0] is a
primitive type. For example, if we pass an element of the above array to a method and that
element is modified within the method, it shows no effect on the original value stored in eth
array. However, if the array itself is passed, it is passed by reference and is susceptible to
changes. Look at the following program which illustrates these concepts.
public class Array {
public static void main(String args[]) {
int[] a = new int[7];
a[2] = 3;
a[5] = 7;
System.out.println("Value of a[5] before passing it to the method changeElemnt() is " +
a[5]);
changeElement(a[5]);
System.out.println("Value of a[5] after passing it to the method changeElemnt() is " +

371

a[5]);
System.out.println("Value of a[0] before passing it to the method changeArray() is " +
a[0]);
changeArray(a);
System.out.println("Value of a[0] after passing it to the method changeArray() is " +
a[0]);
}
public static void changeElement(int a) {
System.out.println("In changeElement() : ");
System.out.println("Value of a before incrementing is " + a);
a++;
System.out.println("Value of a after incrementing is " + a);
}
public static void changeArray(int[] arr) {
System.out.println("In changeArray() :");
System.out.println("Value of arr[0] before incrementing is " + arr[0]);
arr[0]++;
System.out.println("Value of arr[0] after incrementing is " + arr[0]);
}
}
The output of this program would be
Value of a[5] before passing it to the method changeElemnt() is 7
In changeElement() :
Value of a before incrementing is 7
Value of a after incrementing is 8
Value of a[5] after passing it to the method changeElemnt() is 7
Value of a[0] before passing it to the method changeArray() is 0
In changeArray() :
Value of arr[0] before incrementing is 0
Value of arr[0] after incrementing is 1
Value of a[0] after passing it to the method changeArray() is 1
Note that the value of the array element a[5] in main() remain changed even after it was
passed as parameter to the method changeElemnt(). This is because a[5] is of type int (a
primitive data type) which is passed by value. a[5] is not an array type variable.
However, when the array a[] itself was passed, the value of the event a[0] was changed.
This is because a[] is of type int[] an not int. int[] is a reference type that is passed by
reference and not by value.

372

As this program has illustrated, an array type can also be taken as an argument. Also, an
array can be returned by a method. For example, a method which returns a double typed
array will have the following header:
public double[] methodName ()
We will look at an example shortly in which all these concepts are explained. There is
another way to initialise arrays by using an array initialiser. An array initialiser contains a
pair of braces which enclose the values that are to be stored in the array separated by
spaces. Following line uses an array initialise to initialise the array a[].
int[] a= { 3, 34, 7, 9};
Note that we haven't specified the length of the array in the above statement. It is
automatically calculated. When using array initialisers, separating the declaration from
initialisation isn't possible. The following set of statements result in a compilation error.
int [] a;
a = { 3, 34, 7, 9};
The length of an array can be determined through the length variable of the array object in
the following way:
int [] a= { 3, 34, 7, 9};
int len = a.length; //len = 4
Note that length is not a method of the array object but rather an instance variable.

Processing Arrays using Loops


It would be quite difficult to process each of the array's elements individually as we have
done in the previous chapter. Since these are repetitive tasks, repetition statements like for
and while come to our rescue. The common approach is to use a for loop with a variable
used to keep track of the index number and iterate through the entire array.
For example, the following code stores the numbers from 1 to 7 in a seven element int
array.
int[] a =new int[7];
for ( int i=0; i<a.length; i++) {
a[i]= i+1;
}
In a similar way, a for loop can be used to print the elements of the array.

373

for ( int i=0; i<a.length; i++) {


System.out.println("Element at index "+i+" is "+a[i]);
}
And the code below stores the first seven even numbers in the array a, starting from 2.
for ( int i=0; i<a.length; i++) {
a[i] = (i+1) * 2;
}
Here are a few more example which use loops to process arrays.

examples
We may also use the enhanced for loop ( also known as the for each loop) to access the
elements of the array in a more convenient way. The for each loop has the following
syntax.
for ( <data type> <variable name>:< array name>) {
// code
}
The data type should be the same as the data type of the variables that are stored in the
specified array or it can be a higher data type. For example, when the array is of type int,
the data type specified can be long.
For each iteration of the for loop, an element of the array starting from the zeroth index is
stored in the variable specified in the header and the body of the for loop is executed. In
other words, the body of the for loop executes for each element of the array.
The following enhanced for loop is used to print the elements of the array.
int[] a ={3,4,7,9};
for ( int x: a ) {
System.out.println(x);
}
This is how the above code works. That value of x is first initialised to a[0] i.e. 3 and the
body of the for loop is executed which will causes the integer 3 to be printed on the screen.
Next a[1] i.e. 4 is assigned to x and the body executed again. In this the loop continues until
all the elements are printed.
Note that the enhanced for loop cannot replace every for loop that is used to manipulate an
array. This is because, the enhanced for loop only provides us the values held in the array
and not a means to manipulate those values unless the array contains reference type

374

variable. For example, we cannot use the for loop to initialise the array variables with the
natural number from 1 to 7, as done above using a normal for loop. This is because
elements here are of type int which is a primitive data type. Hence the variable x holds the
copy of the integer variable of the array and not a reference to the variable. Moreover, we
have no counter variables that would help in manipulating the array. However, if the array of
of a reference type, like Student, the values stored in the array cannot not just be accessed
but also modified, because in that case the variable specified in the for header (say x) holds
a reference to the Student object stored in the array.
The enhanced for loop is used to iterate through not just an array, but a collection in
general. We will see what collections are in a later chapter.

Searching and Sorting Arrays


An array is not just used to store elements but also access those stored values later on. We
may also need to search for a particular element in the array. Sorting the array may also be
required at times. We will now look into how these things are done using different
algorithms. And we shall also see what the big O notation is and use it to determine the
efficiency of these algorithms.

Simple Search or Linear Search


The simplest way to search for an element is to iterate through the entire array and
compare each value of that array with the target element. When a match is found, we may
break out of the loop if we are sure that there exist no duplicate values. However, if
duplicate values do exist in the array, we might have to continue searching even when a
match is found. Since we search for the elements in a linear order from left to right ( by
convention, you may also search from the end of the array to the beginning), this algorithm
is named as linear search. Following is the code snippet for linear search.
int[] a = { 3, 34, 5,91, 100}; // an array not containing duplicates
int target = 91; // the element to be searched
for( int i=0; i<a.length; i++) {
if(a[i]==target) {
System.out.println ( "Element found at index "+i);
break; // break should be omitted if the array contains duplicates
}
}
Before we move onto the next algorithm, we will look at what efficiency means in the
context of algorithms. There are two things that have to be taken care of when we write
algorithms. The first is the execution time and the second is the memory requirement.

375

Execution time is determined by the numbers of statements that are excited by the
algorithm while memory requirement is determined by the additional variables that we use.
In the above program, we have used only one variable, target, which falls under memory
requirement. However, the execution time cannot be specified directly as such even if we
consider every statement to take the same time to execute. The reason is that, in this
particular algorithm, if the target is in the beginning of the array, then this search would
require only a single comparison which is known as the best case. However if the target is
located at the end of the array, the number of comparisons required would be equal to the
length of the array. This is the worst case. The average execution time would occur when
the target is located in the middle of the array. So, one thing that we can conclude is that
the efficiency of algorithms depends on the input data too. Here arises the need for a
standardised comparison of efficiencies. And one solution is the Big O notation.
The big O notation is gives us a relation between the number of data items contained in the
array and the number of comparisons required. It takes the worst case into account. It
determines how hard an algorithm has to work to obtain the result. In this particular linear
search algorithm, if the number of data items are n, then the number of compressions
required are also n. This is the order of the algorithm. Hence, linear search is said to be an
algorithm of order n.
There is a better way to arrive on this result by using the formal definition of big O. A
function f(n) is said to have an order g(n) written as O(f(n))=g(n) [ O represents order ] if and
only if, there exists an N and a c such that for every n>N, the following condition is true: 0 <
f(n) < c* g(n). What this definition has basically done is to put an upper bound on the
performance of the algorithm and take the worst case scenario.
Let us understand it in the context of linear search. We should first develop the function f(n).
Assume that each of the statements takes the same time to execute. So the execution time
is proportional to the number of statements executed which will be equal to 2*n or n or
2*n+1 depending on what you wish to regard as a statement. The important thing here is
that the power of n is 1 and not 2 or 3. This basically depends on the loop which is executed
n times (the size of the array). In the above definition, if the f(n) is substituted, you would get
g(n) as n by taking appropriate values of c and N. This might not be much clear for the
present moment. But for now, assume that order of an algorithm is the number of times the
for loop is executed for the array size, n. In this particular case, when the array contains n
elements, the for loop has to execute n times (considering the worst case scenario) and
hence the order of linear search is n.

Binary Search
Binary search is an efficient algorithm which can be used to search in a sorted array. Note
that the array has to be sorted in either ascending or descending order for the algorithm to

376

worth. Initially, the range of the array to be searched begins at the first element of the array
and extends up to the last element. This range reduces by half in every iteration. We locate
the middle element of the array and compare it with the target. If the target equals the
middle element, our search is completed, otherwise the range has to be adjusted
accordingly. For now, assume that the array is sorted in ascending order. If the middle
element is smaller than the target, then the target cannot be found in the left half of the
array as each of those elements would also be smaller than the target. Hence, we can
narrow down our search to the right half of the array. On the other hand, if the middle
element is larger than the target, we narrow our search to the left auld of the array. Clearly,
the range of elements to be searched has been reduced by half. We now perform the same
operation of finding the middle element of the new range and reduce the range accordingly.
In the second iteration, the range of elements to be searched reduces to one fourth of the
original array length. Similarly, with the third iteration, the range of elements reduce to one
eighth. Given below is diagrammatic representation of this algorithm
We now have to represent this algorithm programmatically. For this purpose, we take two
variables left and right which represent the bounds of the array to be searched. Left
indicates the left bound of the range and right indicates the right bound of the range.
Initially, the left bound is set to 0 and the right bound is set to array length -1. We then use a
while loop to perform the repetitive task of finding the middle element and comparing it with
the target event. We shall look into the termination condition of while shortly. For now, the
various things to be included in the while loop are statements to find the middle element,
compare it with the target and set the left and right bounds accordingly. Now coming to the
condition in the while loop, this process of finding the middle element and comparing it with
the target would end when we are left with just a single element. This happens when the
value of left and right becomes identical. On moving further, either right would become less
than left or left would become more than right. At this point of time, the search needs to be
stopped. Hence the loop condition is left<=right. Given below is at the code sniper for the
binary search algorithm for an array sorted in ascending order.
int[] a = {3, 7, 10, 15, 91, 110, 150}; // a sorted array not containing duplicates
int target = 91; // the element to be searched
int left = 0;
int middle;
int right = a.length - 1;
while (left <= right) {
middle = (left + right) / 2;
if (a[middle] == target) {
System.out.println("Element found at index " + middle);
break;
} else if (a[middle] < target) {
left = middle + 1;

377

} else if (a[middle] > target) {


right = middle - 1;
}
}
Binary search has an order of log (n). This means that if the length of the array to be
searched is n, the numbers of iterations required will never exceed log2n. You can verify this
by taking a few examples. If you would like to know a formal proof, visit this page.
Now we move to sorting of arrays. Sorting refers to arranging the elements of an array in
either ascending or descending order. We will in the code snippets that follow arrange the
elements in ascending order. The code may be suitably modified to sort in descending
order. We will deal with two algorithms: Simple or selection sort and insertion or bubble
sort.
The selection sort algorithm is rather quiet simple. We start from the left of the array and
search for the smallest element and then place is at index 0 by swapping the two elements.
In order to find the smallest element, we first assume that the element at index zero is the
smallest and assign the index 0 to a variable, say minPos. We then compare each of the
successive elements with the value held at minPos. If the new value in smaller than what
minPos corresponds to, the index stored in minPos is updated. In this way, when we reach
the end of the array, the variable minPos will be holding the index of the smallest element.
Now, we exchange the number stored at index 0 with the number stored at index minPos.
To do this, we require an additional variable and a simple pair of statements shown below
do not work.
a[0] =a[minPos];
a[minPos]=a[0];
After the above two statements are executed, what we will be left with is just a single value
which was earlier the value stored at the index minPos. The value at index 0 is lost. To
avoid this, the value at index 0 should first be stored in a temporary variable and swapping
be performed using the following set of three statements.
int temp = a[0];
a[0] = a[minPos];
a[minPos]= temp;
After this first iteration, we bought the smallest element to index 0. Now, we need to search
for the second smallest element. To do it, we assume that the element at index 1 is the
smallest and proceed as before. In this way, we sort the entire array. Given below is the
code sniper for selection sort.

378

int[] a = {4, 85, 7, 1, 0, 36, -5, 48};


int minPos;
for (int i = 0; i < a.length; i++) {
minPos = i;
for (int j = i + 1; j < a.length; j++) {
if (a[j] < a[minPos]) {
minPos = j;
}
}
int temp = a[0];
a[0] = a[minPos];
a[minPos] = temp;
}
Note that the above code uses two for loop, one nested within the other. The outer loop
keeps track of the position from which the elements are to be searched for the smallest data
item. Initially, this position is 0. After we bring the smallest item to index 0, this position in
the second iteration becomes 1. The inner loop is used to find the smallest elements
starting from the position defined by the outer loop. After finding the smallest element, the
two values are swapped.
This algorithm has an order of n2. The outer loop executes for n times. And the inner loop
executes for variable number of times deepening on the value of i. When i is 0, the inner
lope executes n-1 times. When i is 1, the inner loops excites n-2 times and so on. Therefore
the total number of comparisons made come out to be (n-1)+(n-2)+(n-3)+....(n-(n-1)) which
equals (n-1)*n-(1+2+3....n-1). The second set of values that are subtracted wouldn't make
much difference when the value of n is very large. Hence the above expression evaluates to
n2 which is the order of this algorithm. There is also another way to understand what the
order of an algorithm means. It denotes the effect on the number of steps required when the
number of data items change. Since the selection sort is of n2 order, when the data items
change from n to 2n, the number of comparison increase to 4n2. This can also be
concluded by considering the original expressions (n-1)*n-(1+2+3....n-1). Change n to 2n
and find the new number of comparisons required. Find the ratio of these two terms and
evaluate the limit as n tends to a very large number. You will get the result 4. Therefore
when the data items are increased by twice, the comparisons required increase by four
times which is the square of two. This is what the order of an algorithm represents. Try
similar calculations for the previous algorithms.

Bubble Sort
The last of the algorithms that we are gaining to deal with is the bubble sort method. This
algorithm has its name derived from the water bubbles which surface to the top. In a similar

379

way, in this algorithm, we make larger numbers move to the top of the array when we wish
to sort in ascending order. We iterate through the array from the left to the right and
compare each pair of successive values in turn. If they are in the right order, we leave them
as they are. However, if a larger item is on the left of a smaller item, we swap them. Note
that only successive values are compared. In this way, when we move to the rightmost end
of the array, the largest value is guaranteed to have been bubbled to the top of the array.
For example, if the largest element was at index 0 initially, then in each step of comparison,
this element is moved up ultimately bringing it to the top. In this way when we repeat this
process for n-1 times, the entire array is guaranteed to be sorted. We can further improve
this algorithm by setting proper loop termination conditions. This algorithm requires two
nested loops. Within the inner loop, the loop condition can be stated to be a relation with the
outer counter variable rather than the end of the array. For example, if it is the fifth iteration,
then the four largest elements have already been bubbled to the top of the array. So, there
is no need of comparing those values gain. So, the loop condition can be specified as
j<x.length-1-i. Given below is the code for bubble sort.
int[] a = {4, 85, 7, 1, 0, 36, -5, 48};
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - 1 - I; j++) {
if (a[j + 1] < a[j]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
The bubble sort algorithm also has an order of n2. There are many more searching ND
sorting algorithms but are complicated. If you wish to learn about them, then refer to these
pages on another site:

Array of Objects
As we have already said, arrays are capable of storing objects also. For example, we can
create an array of Strings which is a reference type variable. However, using a String as a
reference type to illustrate the concept of array of objects isn't too appropriate due to the
immutability of String objects. Therefore, for this purpose, we will use a class Student
containing a single instance variable marks. Following is the definition of this class.
class Student {
int marks;
}

380

An array of objects is created just like an array of primitive type data items in the following
way.
Student[] studentArray = new Student[7];
The above statement creates the array which can hold references to seven Student objects.
It doesn't create the Student objects themselves. They have to be created separately using
the constructor of the Student class. The studentArray contains seven memory spaces in
which the address of seven Student objects may be stored. If we try to access the Student
objects even before creating them, run time errors would occur. For instance, the following
statement throws a NullPointerException during runtime which indicates that
studentArray[0] isn't yet pointing to a Student object.
studentArray[0].marks = 100;
The Student objects have to be instantiated using the constructor of the Student class and
their references should be assigned to the array elements in the following way.
studentArray[0] = new Student();
In this way, we create the other Student objects also. If each of the Student objects have to
be created using a different constructor, we use a statement similar to the above several
times. However, in this particular case, we may use a for loop since all Student objects are
created with the same default constructor.
for ( int i=0; i<studentArray.length; i++) {
studentArray[i]=new Student();
}
The above for loop creates seven Student objects and assigns their reference to the array
elements. Now, a statement like the following would be valid.
studentArray[0].marks=100;
Enhanced for loops find a better application here as we not only get the Student object but
also we are capable of modifying it. This is because of the fact that Student is a reference
type. Therefore the variable in the header of the enhanced for loop would be storing a
reference to the Student object and not a copy of the Student object which was the case
when primitive type variables like int were used as array elements.
for ( Student x : studentArray ) {
x.marks = s.nextInt(); // s is a Scanner object
}

381

Recall that we were not able to assign to the array elements in a similar way when the array
was of type int.
Moreover, in the case of array of objects, when we pass an array element to a method, the
object is susceptible to changes. This is because the element being passed is also a
reference type item. This differs from the situation when we have an int array. Following
illustrates this concept.
public static void main(String[] args) {
Student[] studentArray = new Student[7];
studentArray[0] = new Student();
studentArray[0].marks = 99;
System.out.println(studentArray[0].marks); // prints 99
modify(studentArray[0]);
System.out.println(studentArray[0].marks); // prints 100 and not 99
// code
}
public static void modify(Student s) {
s.marks = 100;
}
Compare the output with the one when the array was of type int[].
Processing an array of objects is much similar to the processing of an array of primitive
type. the only thing to be kept in mind is the possibility of NullPointerException being thrown
during run time and also remembering that the array elements themselves are reference
types, which brings subtle differences from the case when they are passed as parameters.
Moreover, an enhanced for loop may be used to initialise the array elements.

Multi Dimensional Arrays


We have seen that an array can hold references to objects and an array itself is a reference
type so an array of arrays seems quite plausible. These are referred to as multidimensional
arrays. We can arrays of two, three or more dimensions. We will look at multi dimensional
arrays, with special focus on two dimensional arrays which are quite frequently used. They
are generally used to represent matrices. But unlike a mathematical matrix, there are a few
differences which we will see now.
We have represented an array type using a pair of brackets. Two dimensional arrays are in
a similar way represented by two such pairs of brackets and an N dimensional array is
represented by using N such pairs of brackets. The following statement creates a two
dimensional array of integers, which contains 3 arrays containing 4 integers each.

382

int[][] a=new int[3][4];


We can also think of this array as a 3*4 matrix in mathematics, with each row of the matrix
being a Java array. You might also think of it in the other way, also as a 4*3 matrix, but we
generally use the first notation.
Elements of this array are accessed by specifying the index numbers, here two of them.
The first representing the array number and the second representing the index element in
that particular array.
a[0][2] = 34;
A two dimensional airy can also be initialised using an array initialiser in the following way.
This paints a better picture of a 2D array as an array of arrays.
int[][] d = { { 1,5,74,2}, {4,68,45,65},{5,0,34,54}}:
The above array a[][] contains three arrays { 1,5,74,2}, {4,68,45,65} and {5,0,34,54}. This
particular 2D array contains equal number of elements in each of its sub arrays. We can, if
we wish to, create 2D arrays which have different number of elements in its sub arrays.
int[][] c = { { 4,56,7}, {1}, {45,78} };
The above two dimensional array contains three arrays. The first of these has three
elements, the second has a single element and the last of these has two elements. We can
also create such non symmetric arrays using the new keyword in the following way:
int[][] b = new int[3][];
b[0]=new int[3];
b[1]=new int[1];
b[2]=new int[2];
The above three sets of statements also creates an array space b identical to that of a
created earlier using an array initializer. Observe that in the first statement, we haven't
specified any integer in the second pair of square brackets following [3]. b[][] is reference
type and so are b[0], b[1] and b[2]. However, b[0][0], b[0][1] .... are of primitive type int.
These things are to be dealt with carefully when we pass an array, a sub array or an
element of the array as parameters.
The length of a two dimensional or a multi-dimensional array gives the number of arrays it
contains. For example: b.length gives 3 while b[0].length gives 3, b[1].length gives 1 and so
on. All these facts are easy to assimilate if we consider two dimensional arrays to be an
array of arrays rather than as a mathematical matrix.

383

We manipulate multi-dimensional arrays using nested loops. For example, the following
code snippet is used to print the elements of an array as a matrix. The code works even
when the rows of the array are of different lengths.
for ( int i=0; i<a.length; i++) {
for(int j=0; j< a[i].length; j++)
System.out.print ( a[i][j] );
System.out.println();
}
Searching a two dimensional array is performed using a linear search. The labelled break
statement is used to break out of the loop once the element is found.
outer:
for ( int i=0; i<a.length; i++) {
for(int j=0; j< a[i].length; j++) {
if ( a[i][j] == target) {
System.out.println("Element found at ["+i+"]["+j+"]");
break outer;
}
}
}
Sorting isn't generally performed on multidimensional arrays since we generally use them to
represent a physical situation rather than as data structures to hold information. For
example, we may use a three dimensional array to hold Student objects in a more realistic
way. We have different cities and each city has different schools which has students. Let
each city, school and Student have a code. A Student object in that case can be accessed
more conveniently as s[city code][school code][student code]. This 3D representation gives
a more realistic picture than a 1D array of Students.

Taking Input as Command Line Arguments


You must have now by realised what String[] args within the declaration of the main method
means. It represents a String array named args. Since args is nothing more than an
identifier, we can replace it with any other identifier and the program will still work. What we
need to know now is how a String array can be passed as an argument when we execute
the program. We pass it through the command line itself. Consider that we have a class
named Add. The following statement normally used to execute the program.
java Add

384

When we wish to pass the String array, we simply include the elements of the array as
simple Strings beside the class name. Enclosing the Strings in quotes is optional.
Consecutive Strings are separated with a space. For example, if we wish to pass a three
element String array containing the values "1", "2", and "3" any of the following lines is
entered on the command prompt.
java Add 1 2 3
java Add "1" "2" "3"
Since these arguments are passed through the command line, they are known as command
line arguments. The String arguments passed are stored in the array specified in the main()
declaration. args[] is now a three element String array. These elements are accessed in the
same way as the elements of a normal array. The following is the complete Add program
which is capable of adding any number of integers passed as command line arguments.
public class Add {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < args.length; i++) {
sum = sum + Integer.parseInt(args[i]);
}
System.out.println("The sum of the arguments passed is " + sum);
}
}
And here are some sample executions from the command line:

Using Ellipsis to Accept Variable Number of Arguments


A method can receive a variable number of arguments with the use of ellipsis (three
consecutive dots: ...) In order to do so, the data type of the variable number of arguments
which can be even a reference type is stated followed by the ellipsis and an identifier. This
type can be used not more than once in a method header and should be the last of all

385

parameters. Following lines show a few valid and invalid method declarations that use
variable length argument lists.
public void meth ( int... a) // valid
public void meth (double a, int... b) // valid
public void meth ( int... a, int b) // invalid- Ellipsis may be used towards the end only
public void meth ( int... a, double... b) // invalid - More than one variable length parameter
list may not be used
public void meth ( Student... a) // valid - Reference types are also allowed
public void meth( int[]... a) // valid - reference types are also allowed
The arguments received are stored in an array of the same data type as specified in the
method header having a length equal to the number of arguments passed. Therefore, those
elements can be accessed as we access an array passed to an array type parameter. Here
is an example of a class Add containing a method addVariable() which takes variable
number of arguments, add them and displays the result. This method is invoked through the
main method with 0, 1 and 2 arguments.
public class Add {
public static void main(String[] args) {
addVariable();
addVariable(1);
addVariable(3, 4);
}
public static void addVariable(int... a) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
}
System.out.println(a.length + " arguments received whose sum is " + sum);
}
}
Here is the output of this program.
0 arguments received whose sum is 0
1 arguments received whose sum is 1
2 arguments received whose sum is 7
The method taking variable arguments is called only when no exact match of arguments
occur for a given method call. For example if we had a method that accepts a single int
argument in the above class, the method call addVariable(1) would invoke this particular

386

method rather than the one taking variable number of arguments. Verify this fact yourself by
modifying the code above.

Inheritance
Inheritance is the process by which the variables and methods defined in one class become
a part of a newly defined class too. The class which inherits can define its own variables
and methods in addition to what have been inherited from the other class. As said in the
beginning, you can take the analogy of inheritance of property from parents to children. The
children inherit the property of their parents and are capable of adding their own earned
property too. Also, property inherited may be sold and given a few face in the form of a new
property. This can be implemented in Java's inheritance too. Variables and methods
inherited may be overridden to give them a new definition. We will now look into how one
class can inherit from another using the extends keyword. We will also study various other
things vital for the application of inheritance in our projects. Lastly, we shall learn about the
Object class from which all new classes inherit implicitly.
For the purpose of learning in a more natural way, we will continue with the Student
example which we have dealt with in the beginning but slightly modify it to adapt it to this
study on inheritance. We will have a class named Person which is more general in nature.
This class contains the variables name and age which every person possesses. We also
have a method printDetails() which prints the name and age. And then we develop a class
Student that inherits from the Person class. A student will have a few additional variables
like marks and rank. There will also be appropriate methods for the Student class.
Inheritance is used either to provide additional functionality to a class in the form of new
methods or to define a specific class from a general class. In this particular example, a
Person is general in nature,, while Student is more specific. Of course, specific and general
are relative and depend on the objects that are taken into consideration.
The class from which a new class inherits is known as the super class. It is also called by
other names such as base class, main class and parent class. The class which inherits from
the super class is known as the subclass, also referred to as derived class, extended class
and child class. But, we generally use the terms super class and sub class. In this particular
example, Person is the super class and Student is the Sub class. Let us first define the
Person class in the following way with two variables, a constructor and a method.
public class Person {
String name;
int age;

387

public Person(String n, int a) {


name = n;
age = a;
}
public void printDetails() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
Now, we define the Student class and specify it to be a subclass of the Person class
already defined. For this purpose, the extend keyword is used beside the class name and is
followed by the name of the class it is extending which in this case is Person. So the class
declaration of Student would be the following.
public class Student extends Person
A sub class inherits all the variables and methods of the super class even if they are private.
The only difference with private variables is that they cannot be accessed in the sub class.
So, our Student class has inherited the two variables, name and age and the method
printDetails() from the Person class. We only need to define the additional variable marks
and provide a proper constructor.
When a sub class members' are being initialised in the constructor of the class, an
appropriate constructor of the super class has to be called from the sub class' constructor
so that the variables defined in the super class are also initialised properly. This call may be
made using the super keyword followed by parentheses in which the required arguments for
the constructor of the super class are passed. This call to super should be the first line of
the constructor. If we do not explicitly call the super class constructor, the compiler makes
an automatic call to the default constructor of the super class (or the no argument
constructor). In case, the super class does not have a no argument constructor, compilation
errors will be generated. The following code shows the Person class with the variable marks
declared and the constructor defined.
public class Student extends Person{
int marks;
public Student(String n, int a, int m) {
super(n, m);
marks = m;

388

}
}
The class Student declared above has not just marks, but also a name and an age. To
verify this, provide some method m() and try to access these variables and the method
printDetails() in the following way. Compile the program and you will not receive any
compilation errors. This confirms that variables and methods of the super class have been
inherited by the sub class.
public void m() {
name=null;
age=-1;
printDetails();
}
However, if we try to access private variables of the super class from the sub class,
compilation errors occur. This is because the scope of private instance variables is limited
to the class itself. In order to modify such variables from the super class, we need to provide
set and get methods or other similar methods in the super class which can then be called
from the sub class. In the above program, change name to private, and provide getName()
and setName() method in the Person class. Call these methods from the method m() in the
following way and compile.
String str=getName();
setName("No name");
Variables and methods inherited from the super class retain their access specifiers. A public
variable is still public and a variable whose access specifier is unmentioned is still treated in
the same way in the sub class also. For example, we can write a Test program for the
Student class, create its objects and access the variables name and age through the object
as they are still public.
Student s = new Student ("Sai", 19, 99);
s.age=18; // valid
If we declare variables in the sub class which have the same name as the variables
declared in the super class, then these variables would hide the ones declared in the super
class. This is similar to how local variables hide instance variables. For example, define a
new variable age in the Student class.
int age;
This age variable hides the age variable that has been declared in the super class. Now, the
Student class has two age variables, one of which has been defined in the Person class

389

and the other defined in the Student class itself. When we refer to the variable age in a
method of the sub class, we get access to the sub class version of age and not the super
class version. The sub class version has hidden the super class version. To get access to
the super class variable, we use the super keyword in the following way:
super.age= 10; // gives access to the super class' version
In a similar way, we can also hide the methods of the super class. This is more aptly
referred to as method overriding. A method in the super class is said to override the method
in the sub class when it has the same method signature which includes method name and
the number, order and type of parameters. The names of parameters are irrelevant. We can
override the method printDetails() in the Student class so that the marks of the Student are
printed in addition to the name and age of the Student. Note that we can also call the super
class version of printDetails() in order to display the first two items.
public void printDetails(){
super.printDetails();
System.out.println("Marks: "+marks);
}
If a method in the sub class has the same name and parameter list as another method
defined in the super class, then it needs to have the same return type also. Otherwise
compilation errors occur. Moreover, stricter access specifications may not be applied to the
overridden methods. This is known as attempting to assign weaker access privileges. The
weakest of access privileges is private followed by unspecified, protected and public. A
method that was public may not be overridden with a method that is private. However, a
private method may be overridden with a public method. Also, to make sure that we are
writing an overridden version of an already method and not a new method, we may use the
'@ Override ' annotation. This is specified prior to method declaration in eth following way.
@Override
public void printDetails(){
//code
}
It is always recommended to use this annotation whenever methods are being overridden.
When this annotation is used, the compiler checks that this method's signature matches
with the ones existing in the super class. If no match is found, a compilation occur occurs.
This is important to ensure that our code is not affected by typographical errors. For
example, if in the Student class, we incorrectly type the method name as printDetails()
instead of printDetails(), the method will be considered to be a new method. When Objects
of Student are created and the printDetails() method is invoked on them, the method

390

defined in super class called. In order to avoid such trivial errors, the use of @Override
annotation is recommended.
The principle of least privileges is not applicable to variables. We may have a public
variable in the super class and a private variable in the subclass both with the same which
isn't possible with methods. When the objects of sub class are created and the access to
this variable is given based on the specifiers associated with the variable defined in the
subclass, which in this case is private leading to denial of access. Moreover, such variables
are also not accessible in classes derived from theses sub classes.
Subclasses may be further extended to another class. This is known as multi-level
inheritance. For example, we can extend the Student class above to a new sub class
StudentWithDisabilities. Now, this new class will have the variables and methods of both of
its super classes. A class is called as either a super class or a sub class depending on the
context in which it is being seen. For example, the Student class is a sub class with respect
to the class Student while it is a super class with respect to the class
StudentWithDisabilities. We will look into multi-level inheritance later on. The inheritance
which we have seen till now is single inheritance where a class extends a single super
class. Java does not support multiple inheritance (not to be confused with multi-level
inheritance) Multiple inheritance is the form of inheritance where a class can extend more
than one super class. We will look into multiple inheritance later on. For now, here is the
complete Student sub class with the overridden method and a Test class. we have also
provided an extra method showGrade() which displays the grade of the Student.
public class Student extends Person {
int marks;
public Student(String n, int a, int m) {
super(n, a);
marks = m;
}
@Override
public void printDetails() {
super.printDetails();
System.out.println("Marks: " + marks);
}
public void showGrade() {
char grade;
if (marks >= 90) {
grade = 'A';

391

} else if (marks >= 75) {


grade = 'B';
} else if (marks >= 50) {
grade = 'C';
} else {
grade = 'D';
}
System.out.println("Grade: " + grade);
}
}
And here is the Test class
public class StudentTest {
public static void main(String[] args) {
Person p = new Person("Ram", 18);
p.printDetails();
Student s = new Student("Sai", 7, 97);
s.age = 19;
s.marks = 100;
s.printDetails();
s.showGrade();
}
}
We have created two objects, one of the Person class and one of the Student class and
assigned them to the corresponding variables. We have accessed the age and marks of the
Student object and changed them. This is possible as they have been declared to be public
variables. And then, the printDetails() method was invoked on both these objects. Here is
the output:
Name: Ram
Age: 18
Name: Sai
Age: 19
Marks: 100
Grade: A

Relation between a Super Class and Sub Class


A sub class has an 'is a' relationship with its superclass. This means that a sub class is a
special kind of its super class. When we talk in terms of objects, a sub class object can also
be treated as a super class object. And hence, we can assign the reference of a sub class

392

object to a super class variable type. However, the reverse is not true. A reference of a
super class object may not be assigned to a sub class variable. The following statements
illustrate this concept by creating a Student object and assigning it to a Person variable.
However, when we try to assign the reference of a Person object to a Student variable, we
get a compilation error.
Person p=new Student("Sai", 19,100);
Student s=new Person("Ram",18);//error
This 'is a' relationship finds application in other areas too. For example, we can pass a
Student object to a method which requires a Person object and we can return a Student
object from a method whose return type is Person.
public Person someMethod () {
Student s=new Student ("Sai", 19,100);
return s; // allowed
}
public void needAPerson ( Person p ) {
// code
}
public void aMethod() {
needAPerson ( new Student("Sai", 19,100) ) ; // allowed
}
The methods and variables of a class that are accessible will depend on the variable type
and not the object type. For example, if we try to access the marks variables or the
displayGrade() method of the Student object p above, we receive compilation errors. This is
because, the accessible methods and variables are determined by the type of the variable
and not the type of the object.
p.marks=100; // error
p.showGrades(); //errors
The reason behind this is that the sub class isn't aware of any of the super classes that
have been derived from it. Hence, it cannot assure that the object contains a marks variable
or the showGrades() method.
This may sound unusual but you will agree that this is the correct way if you look at the
following method and read the discussion that follow it.

393

public void displayPerson( Person p ) {


p.displayDetails();
}
Assume that this method is defined in a new class. In this particular method, a statement
like the following would seem quite absurd.
p.marks=100;
This is because we do not know whether this method would be called with a Student object
or a Person object. If it is called with a Student object, there would be no problem with the
above statement that access the marks variable of p, but if it is invoked with a Person
object, then a problem would arise as p doesn't posses marks. And since we specified the
parameter type to be Person, we cannot assume that the caller will a Student object.
Moreover, a Person object is more likely to be passed as that is what is the one required by
the method.
But when we deal with overridden methods, the method call result resolution appears
unusual. Before we look into it, include the following code in a main method and execute the
program:
Person p=new Student("Sai", 12, 100);
p.printDetails();
When the program is executed, you will notice that the output contains three lines of text.
The marks are printed along with the name and age. This contradicts what has been
already said. The printDetails() method call above has to call the super class version as p is
a Person object and Student methods cannot be invoked on p. So, p should also not be
having any idea of the overriding method. But during run time, the version in Student was
called. This is because of dynamic binding (also known as run time binding or run time
polymorphism). When a class file is being compiled, the methods that can be called on a
particular object referred to by a variable are decided by the data type of the variable. In the
above example, the printDetails() method has been invoked on the Student object which is
referred to by a Person variable p. Hence, the call would be resolved to the printDetails()
method defined in the Person class during compile time. This is known as static binding
which occurs during compile time. However, the actual version of the method to be called is
decided during run time. If the super class variable holds a reference to a sub class object,
the method calls to overridden methods would be resolved to the versions defined in the
sub class. That is why the marks were also printed in the above case. If no overridden
version exists for the method, then the call is resolved to the super class' method.
However, such a thing doesn't happen in the case of instance variables. Suppose, we have
two variables both named var, one in the super class and in the sub class. If we access this

394

variable through a super class variable holding a reference to a sub class object, we get the
value corresponding to the super class variable and not the sub class variable, contrary to
what was observed in the case of methods. The following example makes this concept
clear.
class A {
int var = 10;
}
class B {
int var = 20;
}
// in the main method of a class, write the following code
A obj =new B();
System.out.println(obj.var); // prints 10 and not 20
In order to check whether an object is of a particular class type, Java provides the
instanceof operator (or keyword). This operator requires two operands, the first is a variable
name and the second is a class type. The operator returns either true or false.
Student s=new Student("Sai", 12, 100);
boolean result1 = s instanceof Student; // true
Person p = new Person ("Ram", 18);
boolean result2 = p instanceof Person; // true
The 'is a' relationship shows its effect on the working of instanceof operator also. A sub
class object is an instance of it super class. Hence, the following behaviour.
boolean result3 = s instanceof Person; // true
The instanceof operator may be used to check whether a particular object passed is of the
required data type. For example, if a method needs a Person object, a caller may pass a
Student object also. To process these two types separately, we may use a code similar to
the following:
public void process ( Person p ) {
if ( p instanceof Student ) {
// code
} else {
// code
}
}

395

We will come back to the instanceof operator once again when we deal with interfaces. The
next topic to be dealt is casting from one class type to another. Just as we cast primitive
data items, we can also cast reference data items to a different class type. Here too, the
concepts of up casting, down casting, explicit casting and implicit casting come into picture.
Implicit casting is performed in situations where we assign the reference of a sub class
object to a super class variable, pass a sub class object reference to a method where a
super class object is required or return a sub class object when a super class return is
specified. In all these cases since a lower data type is converted to a higher data type, it is
an up casting operation or type widening operation. Super classes are higher data types
and sub classes are lower data types.
Person p = new Student ("Sai", 19,100); // implicit casting
Student st = new Student ("Sai", 19,97);
Person pe = st; // implicit casting
We may also perform explicit casting, using the cast operator as shown below.
Student s= (Student) p;
The above statement does not create a new Student object identical to p. It simply casts
into to a Student type. Now, p and s refer to the same object and hence, changes made to
the object through any one of the objects are reflected on the other.
Person p = new Student ("Sai", 19,100); // implicit casting
Student s= (Student) p;
s.age=20;
System.out.println(p.age); // prints 20 and not19
When we cast objects from one type to another, the compatibility of these types is checked.
For example, a Student object cannot be cast to String type as they are incompatible.
String str= (String) s; // error, s is a Student object
Just like the 'is a 'relationship, we also have the 'has a' relationship which is quite
straightforward. A class A is said to have a 'has a ' relationship with a class B if class A
contains an instance variable of type B.
class A {
B obj;
}
class B {
}

396

Final Classes and Methods


Inheritance is surely one of the highly useful features in Java. But at times, it may be
desired that a class should not be extendable by other classes to prevent exploitation. For
such purpose, we have the final keyword. We have already seen even what final variables
are. Final classes and methods are also similar. A class declared as final cannot be
extended while a method declared as final cannot be overridden in its subclasses. A
method or a class is declared to be final using the final keyword. Though a final class
cannot be extended, it can extend other classes. In simpler words, a final class can be a
sub class but not a super class.
final public class A {
//code
}
The final keyword can be placed either before or after the access specifier. The following
declaration of class A is equivalent to the above.
public final class A {
//code
}
To make it more clear, there should be no specifiers between a class name and the
keyword class. All other specifiers may be placed to the left of the keyword class in any
order.
Final methods are also declared in a similar way. Here too, there should be no specifiers
stated between the return type and the method name. For example, to make a static
method declared with the public access specifier final, the three specifiers, public, static and
final may be placed in any order to the left of the return type.
public final void someMethod() {
//code
}
When we attempt to extend a final class or override a final method, compilation errors
occur.
class B extends A { // compilation error, A is final
}
We will now look into a small trivial example to understand the necessity of final classes and
methods. Consider that you are a developer writing classes for use by others. You have two

397

classes named Car and Vehicle defined in the following way and of course with may other
methods of your own.
public class Car {
public void move() {
System.out.println("Moving on road");
}
}
class MoveAVehicle {
public static void move(Car c) {
c.move();
}
}
Now, since the class Car is not final, other people may extend it to their own classes.
Following is an example:
class Aeroplane extends Car {
public void move() {
System.out.println("Moving in air");
}
}
This is logically wrong. An aeroplane is definitely not a Car. And a statement like the
following would print absurd data on the screen.
MoveAVehicle( new Aeroplane() );
In order to avoid such illogical extending of classes; classes and methods may be marked
as final. The example cited above is just illustrative. The actual scenario in real world
programming is much more complex.

The protected Access Specifier


As we have lardy said, there also exists the protected access specifier in addition to the
public and private access specifiers. This specifier can be applied to both instance variables
and methods. It offers a level of protection intermediate to that offered by the private and
public specifiers. Variables and methods declared protected are accessible from the classes
defined in the same package and also from subclasses which are defined in other
packages. To illustrate the use of protected access specifier, we first see how we create a

398

package and include a class in a particular package. A package isn't created by any explicit
statement. It is automatically created when a class is specified to be a part of that package.
A class is declared to be a part of a particular package by including the package statement
at the top of the class. The package statement should be the first statement in a program
file, even before import declarations. However comments are allowed to be placed before
the package statement. The following program defines a class A and places it in the
package named mypackage1. Package names are by convention written in all lowercase
letters even if they consist of multiple words.
package mypackage1;
class A {
protected int num;
}
And, the following defines a new class B in package mypackage2. This class consists of a
variable of type A. When one tries to access the variable num of class A, compilation errors
occur. This is because, num has protected access. It is accessible only within the same
package and within its subclasses.
package mypackage2;
class B {
A objA;
public B() {
objA = new A();
objA.num = 34; // not allowed
}
}
The above access is permitted if B is defined to be a subclass of A or if it in defined in the
same package as that to which A belongs, even if it is not declared to be a subclass.
package mypackage2;
class B extends A {
A objA;
public B() {
objA = new A();
objA.num = 34; // not allowed

399

}
}
When a class is not specified to be a part of any package, it is placed in the default
package. This default package and the java.lang package are imported into all classes
implicitly. A package can in turn contain other packages. For example, we can have another
package p2 in the package mypackage in eth following way.
package mypackage.p2;
class B {
}
Now, with respect to access restrictions, the class A and B are considered to be in different
packages. Protected variables of class B are not accessible from class A. Similarly,
protected variables of class A are not accessible from B.

Class Object
The Object class lies at the root of every hierarchy. In other words, every class is a direct or
an indirect superclass of the Object class. If we do not specify a superclass using the
extends keyword, the default is the Object class, otherwise the Object class becomes an
indirect superclass due to multilevel inheritance.
class A {
}
A extends Object implicitly.
The Object class has certain useful methods, notable among them being the equals()
methods. Since, every class is either a direct or an indirect superclass of the Object class,
these methods can be invoked on any object and a reference of any object can be assigned
to an Object type variable, including an array type.
Object obj = new int[5];
Object s = new Student ("Sai", 19, 97);
We can also create an object of the Object type using the constructor. However, such an
object finds no useful application.
Object obj= new Object();
The Object class defines 11 methods, five of these are used in the context of multithreading
which we will see when we deal with multithreading. We shall now look at some of the
remaining methods.

400

The equals() method has the following header.


public boolean equals(Object obj)
This method is used to compare two objects. It basically returns the boolean result of ==
operated on the two objects, one of them being the object on which this method is invoked
and the other is the one passed as an argument. In other words, it returns true only if the
variable on which this method is invoked and the variable that is passed as an argument
refer to the same object in memory. When the argument passed is null, the result is false.
Look at the following example:
Student s1 = new Student ( "Sai", 19, 100 );
Student s2= new Student ( "Sai", 19, 100 );
Student s3=s1;
Student s4=null;
Student s5=null;
Student s6;
boolean res1=s1.equals(s2); // false
boolean res2=s1.equals(s3); // true
boolean res3=s1.equals(s4); // false
boolean res4=s1.equals(null); // false
boolean res5=s4.equals(s5); // NullPointerException thrown at runtime since s4 is null
boolean res6=s4.equals(s6); // compilation error, s6 is not initialised
boolean res7=s6.equals(s1); // compilation errors, s6 is not initialised
boolean res8=null.equals(s1); // compilation errors, null type cannot not be dereferenced
Note that even though s1 and s2 are similar in content, they both are different objects.
Hence, the equals() method has returned false.
This method can be overridden or overloaded by a class to compare the contents of the
objects instead of checking the references. For example, the String class which is widely
used has this method overridden to compare the contents of the Strings rather than check if
the two variables point to the same String. We can also provide suitable implementation for
the Person and Student class which we have defined. However, one should be careful while
either overloading or overriding the equals() method. Shown below are what constitutes the
overloaded version and what constitutes an overridden version:
public boolean equals ( Object obj ) // overridden version
public boolean equals ( Student s ) // overloaded version
The recommended way is to provide an overloaded version instead of an overridden
version. In that case when the equals() method is invoked with a Student argument, the call
is resolved to the method provided. If the argument passed is not a Student object, then the

401

call gets resolved to the other version inherited from Object which checks for references
and would surely return false. Given below is the overloaded version:
public boolean equals(Student s) {
if (this.name.equals(s.name) && this.age == s.age && this.marks == s.marks) {
return true;
} else {
return false;
}
}
This overloaded version checks if the name, age and marks of both the Student objects are
identical and returns true or false accordingly. Note the use of this in the above method to
refer to the Student object on which the equals() method is invoked with a Student
argument.
We may if we wish to also override the method. The implementation would then vary
slightly. First, we need to check if the object passed is of Student type. If it isn't, then there
is no chance for it to be equal to the object on which the method is invoked. Hence, we
return false. Otherwise, the object passed is explicitly down casted to Student type and we
perform a comparison as done in the overloaded version above. The @ Override annotation
below is optional but recommended.
@ Override
public boolean equals(Object obj) {
if (!(obj instanceof Student)) {
return false;
} else {
Student s = (Student) obj;
if (this.name.equals(s.name) && this.age == s.age && this.marks == s.marks) {
return true;
} else {
return false;
}
}
}
Note that we have use the equals() method rather than == to compares the two names
which are Strings. After theses modification, the result of the equals() method call, which we
have seen would now change. res1 becomes true.

Converting an object to String


public String toString()

402

The toString() method returns a String representation of the object on which it is invoked.
This String contains the class name followed by the @ sign and the hexadecimal
representation of the object. Do not bother about what hash code is.
Student s = new Student ( "Sai", 19, 100 );
String s=s.toString(); // s1=" Student@addbf1"
When we pass an object as a parameter to the print() or println() statement, the toString()
method is implicitly called on the object and the String is printed on the screen.
System.out.println(s);// prints " Student@addbf1"on the screen
The toString() method can be overridden to return a better representation of the object. For
example, in the case of Student class, we can return the name, age and marks of the marks
along with the class name, in the following way.
@ Override
public String toString() {
String s="Student: "+this.name+" "+this.age+" "+this.marks;
return s;
}
Now, we may either explicitly call this method or implicitly call it by passing a Student object
as a parameter as in the following code.
Student s = new Student ( "Sai", 19, 100 );
System.out.println(s);// prints "Student: Sai 19 100"
If we wish to do so, we may copy the definition of printDetails() method into the overriding
toString() method and remove the printDetails() method. Since, the printDeatils() method's
task is to essentially convert the object to a String.

protected void finalize() throws Throwable


We have seen how a constructor is used to create objects but nowhere did we see till come
across a means to destroy the objects when they are no longer needed. This task is
performed by Java's automatic garbage collector. The garbage collector looks for objects
which no longer have references to them and destroys them. For example, look at the
following two statements, we create a Student object named s using its constructor. In the
second line, we assign null to the Student variable. null specifies that the variables s no
longer points to any object. The object created earlier is now abandoned.
Student s=new Student("Sai", 19,100);
s = null;

403

Instead of using the statement s=null to remove the reference to the object created on the
first line, you may also use the following statement which creates a new object and assigns
its reference to s. So, the object referred to earlier has no references now.
s= new Student("Sai", 18,100);
There is no way we can retrieve the object created earlier. If too many such abandoned
objects exist, they occupy significantly memory and waste the resources available. The
automatic garbage collector of Java destroys such objects. But before doing so, three may
be a need for that object to return back any resources that it has used. For example, if it had
opened a file, ( we ill see later how it is done), the object needs to first close that files before
destroying itself so that other objects can open that file. All such operations may be
specified by overriding the finalize() method. The finalize() method defined in the class
Object has an empty body. Shown below is an overridden version of this method for our
Student class. This method simply states that the object is being destroyed.
@ Override
protected void finalize() throws Throwable {
System.out.println("Object being destroyed");
}
We shall see what 'throws Throwable' means when we deal with exception handling but for
now, it indicates that the method might throw Exceptions. The method finalize() should
never be called explicitly. It is automatically called by the garbage collector when needed
but one cannot be assured of when it will be called and if it is guaranteed to be called. We
shall see after dealing with multithreading how we can realise the execution of the finalize()
method. And, if we call the finalize() method, it doesn't destroy the object on which it is
called. It only executes the body of the finalize method. We do have other methods: clone(),
hash code() and get Class() and the multithreading related functions. In you are interested
in learning about them, visit this page.

Polymorphism
Polymorphism is an object oriented programming feature which allows the same message
to produce different but correct outputs. One example is the case of method overloading,
the same message sent ( invoking the method) produces the desired and correct output by
resolving the call to the appropriate method based on the parameters passed. And now, we
shall see polymorphism in the context of inheritance. Polymorphism allows us to program in
the general rather than in the specific. We have already come across polymorphism in the
context of inheritance when we have overridden the printDetails() method in the Student
class. Invoking it has called the sub class version and not the super class version. We shall

404

continue a similar discussion, using a different and more appropriate example to illustrate
programming in the general.
We have a class named Animal having a method move(). An animal may move in different
ways, it might swim like a fish, fly like a bird or crawl like a spider. So the class Animal is
more general, so is the method move(). We then extend this superclass Animal to a few
subclasses like Fish, Spider and Bird which override the method move() to define a more
specific implementation of the method move(). For now, here are the various class
definitions.
public class Animal {
public void move() {
System.out.println("The animal is moving");
}
}
public class Bird extends Animal{
public void move() {
System.out.println("The bird is flying");
}
}
public class Fish extends Animal{
public void move() {
System.out.println("The fish is swimming");
}
}
public class Spider extends Animal{
public void move() {
System.out.println("The spider is crawling");
}
}
public class Hare extends Animal{
public void move() {
System.out.println("The hare is running");
}
}
Animal is a more general class and the sub classes are more specific in nature. There is
also a possibility that we may feel like adding more Animal types or subclasses of Animal in
the future. So, rather than programming with respect to a specific animal, we simply

405

program in the general taking only the Animal class into consideration and not its specific
sub classes.
To understand what programming in the specific and general means, let us assume that we
need to create ten different objects, some of them of Bird type, a few others of Spider type
and so on. And then make each of these animals move. One solution would be the following
where we consider each animal to be of a separate type. This might be named as
programming in the specific.
Fish f1 = new Fish();
Fish f2 = new Fish();
Bird b1=new Bird();
...
f1.moev();
f2.move();
f3.move();
...
This approach seems alright but what if we have 100 such different animals, a few in each
category? And if is not just one method that we need to invoke but several of them, all of
them having the same name and defined in each of the classes. One solution would be to
use arrays. Now, here arises the question. Do we create Fish arrays, Bird arrays or Animal
arrays. If we go for creating a different typed array for each of the Animal types, modifying
the code would be difficult if new Animal types like Crabs and Monkeys come into the
picture. So, we better choose to create arrays of Animal type. But, would move() invoked on
Animal type objects call the version in the superclass or the sub class? As we have already
seen when earlier, during compilation, the method call is resolved by looking at the variable
type which in this case is Animal. So each of the move() calls would be mapped to the
versions in superclass. However, the actual method being called is decided during time by
looking at the type of object and not the type of variable. If the sub class has overridden any
of the already matched methods during compilation, the call would be diverted to the sub
class method. So, the correct version is guaranteed to be called. This is what we refer to as
programming in the general and this resolution of calls during run time is known as dynamic
binding or run time polymorphism. Actual use of this feature is quite more complicated and
is used as a part of actual reusable class. But, for illustrative purpose, we use it in test class
as shown below:
public class Test{
public static void main(String [] args){
Animal[] animals=new Animal[4];
animals[0]=new Fish();
animals[1]=new Spider();

406

animals[2]=new Bird();
animals[3]=new Hare();
for(int i=0;i<animals.length;i++)
animals[i].move();
}
}
The output would be:
The fish is swimming
The spider is crawling
The bird is flying
The hare is running
To make this program more interesting, provide parameterised constructors for the sub
classes of Animal so that we may give names to the animal and modify the move() method
to display the name of the animal along with the action being performed.
Method call resolution during run time occurs to the deepest level. For example, if in the
above program, we further extends Bird to Sparrow overriding method move(), create a
Sparrow object, assign its reference to an Animal variable and then invoke the move()
method, the call gets resolved to the version in Sparrow and not to the one in Bird() or
Animal().

Interfaces
A Java interface is used to specify what is to be done but not how it is to be done. For
example, a Vehicle should be capable of performing several tasks such as starting,
stopping and changing speed. All types of vehicles, be it a car or an aeroplane should be
capable of doing these tasks. In such a case, we can define an interface Vehicle where
these various methods are specified but the definition of these methods are given in the
classes like Car and Aeroplane which implement these interfaces.
A Java interface consists of only final static variables and abstract methods. No
implementation is provided for the methods. We may declare the vehicle interface in the
following way:
public interface Vehicle {
// body
}

407

The interface name follows conventions similar to those followed by class names. The first
letter of each word in an interface is capitalised. The access specifier may be either public
or unspecified. When stated as public, the interface is available to all classes. When no
access specifier is stated, default access restrictions are applied and the interface is
accessible only from classes within the same package. private and protected access
specifiers cannot be used here. The interface may not be private because it should be
accessible from other classes if they are to implement. On similar lines, the use of protected
is absurd since an interface is mainly defined to be implemented in a class and there exists
no such thing like a class inheriting an interface because of which protected would offer the
same level of protection as the package specifier. Hence, its use is absurd.
The interface may contain both variables and methods. Variables are implicitly final, static
and public. And the methods are implicitly abstract and public. Use of specifiers that
overwrite these default specifiers is not allowed. For example, both methods and variables
may not be declared with the public or protected specifiers. The reason behind this is the
same as discussed above with reference to the interface.
The following example shows the interface Vehicle with three abstract methods and a final
variable code.
public interface Vehicle {
int CODE = 347; // implicitly public and final
void start(); // method is implicitly public and abstract
public void stop(); // method is implicitly abstract
public abstract void changeSpeed(int newSpeed);
}
Note that the variables declared in an interface should be initialised with default values as
final variables require that they be initialised at the time of declaration itself. A class which
implements this interface should provide the definition for all of the abstract methods. Given
below is an example.
public class Aeroplane implements Vehicle {
int speed;
public void start() {
System.out.println(" Taking off");
}
public void stop() {
System.out.println(" Taking landing");

408

}
public void changeSpeed(int s) {
speed = s;
}
}
Note that the variable names used in the parameter list of the method name in this class
and those defined in the interface need not match as was the case always. We have used
the variable name s instead of newSpeed.
The @Override annotation may be used here too to ensure that we are using the correct
method definition.
A statement like the following would be valid since the variable CODE is now a part of the
class Aeroplane too as the interface Vehicle containing the variable CODE has been
implemented.
System.out.println(CODE);
Even a class that does not implement an interface can access the variables defined in the
interface since they are static.
int code= Vehicle.CODE;
A class can implement more than a single interface. These interfaces are included in the
class declaration with a comma separated list as shown below.
public class Aeroplane implements Vehicle, AnotherInterface {
}
Moreover, a class can define its own additional variables, methods and constructors just like
any other class. Also it can extend a superclass in addition to implementing the interfaces.
An interface can also be implemented by more than a single class.
If a class does not provide the implementations of all the methods declared in the interface,
the class itself should be defined as abstract. These abstract methods can then be defined
in classes which extend it.
An interface also works as a data type. Though objects of an interface cannot be created,
we can assign to the variable a reference of an object belonging to a class which implement
the. For example, we can assign the reference of an Aeroplane object to a Vehicle variable.
Vehicle v = new Aeroplane();

409

The above statement indicates that there is an 'is a ' relationship between the class the
implementing classes and the interface and hence the following applications and results.
public Vehicle meth() {
return new Aeroplane();
}
public void someMethod( Vehicle v ) {
//code
}
// call to the above method
someMethod( new Aeroplane() );
// use of instanceof
Aeroplane a=new Aeroplane();
Boolean b=a instanceof Vehicle; //true
The above technique of considering an interface as a data type brings out the reason
behind the use of an interface. One can code a class containing calls to start() and stop() on
vehicle objects unbothered about the type of Vehicle- an Aeroplane or a Car. Since only
objects of types that have implemented the Vehicle interface can be passed to the class,
there is no need to worry if the class has the methods start() and stop(). However, to use
method other than those defined in the interface, the object needs to be cast to an
appropriate type. For example, consider that the Aeroplane class has an additional method
flyHigher(). This method called be invoked on an object through a variable of type Vehicle
only after explicitly casting it.
Vehicle v=new Aeroplane();
v.flyHigher(); // compilation error
This is because the interface Vehicle hasn't declared a flyHigher() method. To be able to
call this method, the object needs to first cast to an Aeropalne.
Aeroplane a=(Aeroplane) v;
a.flyHigher();
Interfaces can also be extended just like classes using the extends keyword. But unlike
classes, an interface can extend more than one interface by using a comma separated list.
public interface SuperVehicle extends Vehicle {
// code
}

410

The new interface will also posses all the variables and methods declared in its super
interfaces.
Inheritance is generally in the context of interfaces when extending an interface is
necessary. For example, consider that the above Vehicle() interface has been implemented
by many other developers. Now, if you add another method to this interface, all the classes
created by the other developers would break as a class when implementing an interface
should provide definitions for all the methods that have been declared in the interface. The
developers will have to modify their classes before they can be used once gain. To avoid
such complication, interfaces are extended when one wishes to modify them by adding new
methods.

Packages
We have come across packages many times. We have also used them in a few instances.
We will now review all those concepts and also look into the unexplored items. We start with
what a package is. A package in Java is used to group related classes together. For
example, we can have a package named shapes which will contain various classes like
Circle, Triangle and Square used to process various geometric shapes. Packages are also
used to resolve namespace conflicts. Two classes cannot have the same name under
normal circumstances. However, if they are declared in different packages, you can have
more than a single class with the same name.
Packages are created when the program files are compiled. You can specify a class to be a
part of a package by using the package keyword before any other code in your class,
including class declaration and import declarations. You can however have comments
before the package statement as they are ignored by the compiler. The following code
declares the class Triangle to be a part of the package shapes. A package name by
convention is written in all lowercase letters even if they consist of more than a single word.
package shapes;
class Triangle{
// code
}
A package can in turn contain other packages. You specify this using a dot. For example, if
you would like to include a class, say Cube in a package named threed which should be a
part of the package shapes, then you do it in the following way.
package shapes.threed;
class Cube {

411

//code
}
Understand that we include packages within packages only to represent the physical
situation. The two packages shapes and shapes.threed are considered to be different
packages when we deal with access protection and package imports. For instance, if the
class Cube is declared as protected, then it would not accessible to the class Triangle since
they both are situated in different packages. However, as already said packages are
defined in this way to represent physical relations which are reflected in the way the
compiled classes are organised. To understand this, define the following classes in different
program files all in a single folder on your computer and compile them.
package shapes;
class Triangle{
}
package shapes;
class Rectangle{
}
package shapes.threed.sixfaces;
class Cube {
//code
}
package shapes.threed;
class Sphere {
//code
}
package shapes.threed.sixfaces;
class Cuboid {
//code
}
package shapes.threed.fourfaces;
class Tetrahedron {
//code
}
In all we have six classes. After compiling them, observe how the Class files generated are
arranged in the folder. A new folder shapes has been created which contains Triangle.class,
Rectangle.class and another folder named threed. The threed folder contains Sphere.class

412

and two folders: sixfaces and fourfaces. The six faces folder contains two files : Cube.class
and Cuboid.class. The folder fourfaces contains a single file Tetrahedron.class.
When a class is not specified to be a part of any package, it is then placed in the default
package. In terms of a folder, the .class compiled file is placed in the same folder in which
the .java file is present.
In order to use a class of a package other than the one to which the class we are working in
belongs to, we need to import either that particular class or the entire package in which the
class is located. Or, we can refer to the class by its fully qualified name. To import a
package or a class, we use the import declaration placed after the package statement. To
import a class or the entire package, we use the following syntaxes. To import more than
one class, we specify each of these import declarations in different statements.
import <package name>.<class name>;
import <package name>.*;
The second statement above imports all the classes that are located in the specified
package. Given below are a few import declarations for the above classes we have defined.
Note that an import declaration similar to the second statement above does not import the
classes contained within sub packages of the specified package. It only imports the classes
of that package. For example, importing shapes imports only Triangle and Rectangle. It
doesn't import the other classes, Cube, Cuboid and Tetrahedron. The package shapes and
shapes.threed are considered to be different.
import shapes.Triangle; // imports Triangle
import shapes.Rectangle; // imports Rectangle
import shapes.*; // imports both Triangle and Rectangle
import shapes.threed.*; // imports Sphere
import shapes.threed.sixfaces.*; //imports Cube and Cuboid
import shapes.threed.sixfaces.Cube; // imports Cube
Specifying only the package name without the class name or the asterisk (*) results in
compilation error.
import shapes; // compilation error
Also, the * is not a general wild card character in this context. The asterisk is in daily life
used as a substitute for a sequence of characters. For example T* may represent Tea, Tree
and so on. However, here, the * is not a wildcard character and such a use isn't allowed.
For example, the following statement generates a compilation error.
import shapes.T*; //compilation error

413

Once we import a class, we can use that class by referring to its simple name. See the
example below:
import shapes.Triangle;
class Test {
Triangle t; // referring to with its simple name
public Triangle meth() { // referring to with its simple name
}
public void action(Triangle t) { // referring to with its simple name
}
}
We can also use a class without importing it. In that case, we need to refer to it using its
fully qualified name which includes the package name, followed by a dot and the class
name. For example, to create a Sphere object, we use the following statement:
shapes.threed.Sphere s = new shapes.threed.Sphere();
In a similar way, the following statements:
public void action(shapes.threed.Sphere s) { // referring to with its simple name
}
Such a use is highly inconvenient, hence it is always recommended to import the classes
before using them. However, in certain circumstances, this might not be possible when
name conflicts appear. Suppose, we have two packages p1 and p2 both containing the a
class with the same name MyClass, then importing both the classes is allowed but that
does not mean that we can refer to the either of the class with its simple name. For
example, see the following statements. The identifier MyClass cannot be resolved to either
of the two versions.
import p1.MyClass;
import p2.MyClass;
class Test {
MyClass m ; // compilation error
}
In such a case, the only available solution is to refer to the class with its fully qualified
name.

414

p1.MyClass m1; // correct


p2.MyClass m2; // correct
The current package in which the class is located and the java.lang package are imported
automatically into all new classes. That was why we were able to use the String class which
is a part of java.lang package without importing it. And also, we were able to use the class
Student without importing it in the test classes since both of them belong to the same
package- the default package.
We have said in the beginning that packages can be used to avoid name space collision i.e.
more than a single class can have the same name if it is in the same package. First create
a class named Cube and include it in package shapes.set1 using the package statement.
Now try creating a class with the same name with the intention of including it in the package
shapes.set2. You will not be allowed to do so as more than a single file in the same folder
cannot have the same name on a computer. So here comes the natural question as to how
name space collision can be resolved. The place where you store your .java files is
immaterial. What ultimately matters is the place where your .class files will be stored. If you
are keen on creating a new class with the name Cube, one solution available to you is to
create the file in another folder on your computer, compile the two .java files to get the
.class files and then arrange them in folders created by yourself. Create a folder named
shapes. Within shapes, create two new folders set1 and set2. Place the two class files in
their corresponding folders. Though this might sound unusual, this is the way it needs to be
done. Or as an alternative, you may use an IDE like Net beans which allows you to create
packages also. They too work in a similar way. What they actually create is nothing more
than an empty folder similar to what we have done. The last in this topic is regarding the
package access. We have already learnt about it. The package access is applied when we
do not explicitly specify an access specifier. Such entities are accessible by all members
with the package to which the class belongs.
Now that you know how to create packages, there should be a way by which you should be
able to import them to a class located anywhere on your computer. For example, you can
import the java.util package to any class file irrespective of the folder in which you are
storing your program file. If you think that the same can be done here, check if it is true. You
can import the shapes packages which you created only to those classes which are located
in the same folder as that of the folder in which the shapes folders containing the compiled
class files is located. This is because of the way in which Java locates packages. It only
checks in two locations. One is the folder in which your file is located and the other is a
folder found with the other jdk files. To learn how to make your package usable by others,
check out this article.

Abstract Classes and Methods

415

A method is declared with the abstract specifier if we wish to only declare it and not provide
its implementation. For instance, in the previous example, we could have defined the
method move() as abstract if we are sure that three does not exists any general Animal.
public abstract void move();
Note that there is a semicolon at the end of the method declaration which indicates that the
method is not yet defined. A class containing one or more abstract methods should also be
declared as abstract. Mentioning something as abstract simply means that the item under
context is not yet usable and further actions are necessary to make it usable.
abstract class Animal {
//code
}
We may also declare a class as abstract even when the class contains no abstract
methods. But when a class contains atleast a single abstract method, the class also needs
to be abstract. Otherwise, compilation errors occur. Objects of an abstract class cannot be
created. Even then, constructors may be provided for an abstract class for use by its sub
classes. An abstract class is made usable by extending it to a sub class. The sub class
needs to provide implementations of all the abstract methods defined in its super class, just
in the way methods are overridden. No special syntaxes exist for it. If one or more of the
abstract methods of the superclass are not defined in the sub class, even the sub class
needs to be defined as abstract. In addition, it may declare its own abstract methods. When
a new class extends another class, it needs to provide implementations of not just the
abstract methods of its immediate superclass but also of all the other indirect superclass's
lying in the hierarchy. Though we may not create an object of an abstract class, we are free
to declare a variable of that abstract class type. We can then assign references to objects of
the subclass type to these superclass variables.
Animal a = new Bird();
The abstract word is often used in association with the advantage provided by
polymorphism. For instance, in the example we dealt with, creating an Animal object might
seem absurd. Hence, we may declare it to be abstract with no other changes required.
During compilation, the method call move() would be resolved to the version in Animal class
itself even though it has been declared to be abstract. This is because, any object reference
that has been assigned to this variable is guaranteed to have an implantation of the move()
method failing which, an object of the Animal type (by way of inheritance) could not have
been created in the first place.

416

The keywords abstract and final may not be used together. This is because an abstract
method or a class should be extendable by other classes. Otherwise, there is no point in
defining those classes.
abstract final class A // compilation error
abstract final void meth(); // compilation error

Exception Handling
A program may not always reach to its end. It might be interrupted in several ways. A logical
error in your program could crash it. For example, you might be trying to access an element
of an array beyond its length. The misbehaved user could enter a String when asked for an
int and lastly, the computer itself could go out of memory requiring the program to end.
Some of them cannot be handled but the others can. For example, if a user enters a String
when an int is needed, the program would terminate abruptly printing an error message. We
can override this default behaviour so that the program asks for a proper input a second
time. This is attained using Java's exception handling statements.
An Exception in Java is an object which contains information about the error that has
occurred. These Exception objects are automatically created when an unexpected situation
arises. If we do not provide any exception handlers, as already told, an error message is
printed. Before we learn how to provide our own exception handlers, let us see what the
default handler provided by the compiler does. For this purpose, let us write a program
which takes an int as an input from the keyboard. Simulating a misbehaved user, let us
enter a String instead of an int. Here is the program for this purpose.
import java.util.Scanner;
public class TakeInput {
public static void main(String[] args){
Scanner s=new Scanner(System.in);
System.out.print("Enter an integer: ");
int num=s.nextInt();
System.out.println("You entered "+num);
}
}
And here is a sample output when we enter the String "Java" when we were supposed to
enter an integer.
Enter an integer: Java
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)

417

at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at TakeInput.main(TakeInput.java:7)
As you can see in the output above, the program was terminated midway. The last
statement which prints "You entered ..." was not executed. The method nextInt() expects an
int but what it received is a String. And so, the method nextInt() has thrown an
InputMismatchException which you can see on the second line of the output. This
Exception has occurred in the main thread. We shall see in a later chapter what a thread is.
And the remaining lines point out to the code where this particular Exception has occurred.
This is known as unwinding the stack trace.
To know what a stack trace is, let us consider the following program.
class Example {
public static void main(String[] args) {
a();
}
public void a() {
b();
}
public void b() {
c();
}
public void c() {
}
}
The execution of this program starts with the main() method. From main(), the method a() is
invoked. a() then invokes b() and finally b() invokes c(). After c() completes its execution,
there should be a way to know as to where which the control should be tranferred, b(), a(),
main() or a method in some other class? This information is held in method activation stack.
A stack is a data structure (data structures store information) onto which items can be
pushed or popped (removed). You can think of a stack as a pile of books. We place books
on an existing stack of books only on the top and we also remove books only from the top.
We don't insert or remove books from the middle of the pile. A stack is therefore, a first in,
last out data structure since the data item which is pushed onto the stack first is popped out
of the stack at the end. A record of method calls is held in such a stack. When a method is

418

pushed onto a stack, the line number of the other method to where it should return and the
argument variables of the current method are also pushed onto it. This is why the scope of
the argument variables end when the method completes execution as these variables are
pushed out of the stack along with the method record. So, in this program, the method
main() is first pushed onto the stack followed by a(), b() and c(). If c() invokes a method of
some other class, even that would be pushed onto the stack. Once c() completes execution,
it is popped out of the stack and control passes to the method b(). Next b() is popped out in
a similar way followed by a(). In this way, the virtual machine executing the program is
capable of knowing where to return back.
Now, we move back to the sample output of the TakeInput class. Look at the lines in the
output. The method stack has been unwound. The line numbers on which the error
occurred are also printed. We haven't explicitly invoked any method by name forNext() or
next(). These were invoked from within the nextInt() method which we have called. Hence,
they too are printed in the stack trace. The line numbers are also displayed which would
help us in finding the source of error.
However, a user using this program might get confused on seeing such lines of code. An
alternative way to program would be to display a message that he has entered an invalid
value and stop the program rather than allowing the above messages to be printed. We do
it by using try catch finally blocks. A try block encloses the code which may throw
Exceptions. You can find out if a particular method throws an Exception by looking at the
documentation of the class. Along with the method names and descriptions, the exceptions
that it may throw are also listed. The catch blocks provide a means to handle these
Exceptions. A try block may be followed by any number of catch blocks. Each catch blocks
handles a particular type of Exception. As we have already said, an Exception is an object.
The corresponding catch block receives the Exception thrown by the try block into a
variable specified in eth catch clause and processes the Exception. And lastly comes the
finally block which contains code that will be executed whether or not an Exception has
occurred.
try {
// code
} catch ( <Exception type > < identifier > ) {
// code
} // more catch blocks
finally {
}
If no Exceptions are thrown by the try block, none of the catch blocks are executed. Control
passes directly to the finally block. However, if an Exception is thrown by the try block, then
the remainder of the code in try block is skipped and the type (class type) of the Exception

419

is compared with each of the catch blocks in the same order in which they are defined until
a match if found. When an appropriate match is found, the corresponding catch block is
executed and the remaining catch blocks are skipped. And then the finally block is
executed. A try block should be followed by atleast one catch or finally block. One important
thing that should be remembered is that variables defined in any of the try, catch of finally
blocks have their scope and lifetime limited to that block itself.
The following program shows a modified version of the TakeInput program where the
statements are enclosed within the try block. The Exception that might be thrown here is a
InputMismatchException and hence a catch block has been provided to handle it. Look at
the code within the parentheses following the catch keyword. The Exception type has been
declared followed by an identifier in which the thrown Exception object would be received
just like the way a method receives arguments in its parameters. We will see later on how
we can use this Exception object to display the error that has occurred and also print the
stack trace. For now, the type is provided only to target the catch block to be executed for
that Exception. We have no intention to use the object to retrieve details of the Exception
that has occurred.
import java.util.Scanner;
import java.util.InputMismatchException;
public class TakeInput {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
try {
System.out.print("Enter an integer: ");
int num = s.nextInt();
System.out.println("You entered " + num);
} catch (InputMismatchException e) {
System.out.println("You have entered invalid data");
}
}
}
Note that the import declaration has been modified to import InputMismatchException as
well since we have used that class type in our catch statement. If you prefer to do so, you
might import the entire package as well. We have provided only a catch block and no finally
block. Run the above program and see the output. When you enter a valid integer, the
program works normally.
Enter an integer: 34
You entered 34

420

In the other case, the statement which displays the accepted integer is skipped in the try
block and the string "You have entered invalid data" is printed.
Enter an integer: Java
You have entered invalid data
Modify the above code and include a finally block also, in addition to the try and catch
blocks.
// try and catch blocks
finally {
System.out.println("Finally is always executed");
}
Run the program, first providing an int as the input value and then providing a String or a
float (anything other than an int). You will notice that the finally block is always executed.
Now modify the program to remove the catch block. Our program now contains only a try
and a finally block. Execute the program. When you give an integer as the input, the output
appears fine. Now, when you give an invalid input, a part of the try block is executed
followed by the finally block. In addition, the stack trace is also printed similar to what we
have seen when no Exception handling was provided. The reason is that even though we
have provided Exception handling statements, we haven't caught the exception. If a try
catch finally sequence doesn't catch an exception, the exception is rethrown. If these set of
try catch finally statements are enclosed within another set of try catch finally blocks, control
moves to the catch blocks of that set. Since, in this case, there were no nested blocks; the
exception was handled by the default exception handler. You will notice a similar output if
you provide catch blocks that cannot handle the InputMismatchException. For instance,
provide a catch block for ArithmeticException. This is thrown in certain situations like
dividing an integer with zero, finding the square root of a number. This exception is a part of
java.lang package. Hence, we need not import it. You will notice that the output still remains
the same. This is because, InputMismatchException was still not handled.
// try
catch ( ArithmeticException e ) {
System.out.println("ArithmeticException handled");
}
// finally
Now modify the code again and replace the ArithmeticException with Exception. This is the
superclass of all Exception types.
//try
catch ( Exception e ) {

421

System.out.println("Exception handled");
}
//finally
When you provide a String as an input, you will see in the output that this particular catch
block was executed. This is because an InputMismatchException is an Exception ( 'is a '
relationship as InputMismatchException is a subclass of Exception) In other words, a
particular catch block is executed if on operating the thrown object with the instanceof
operator and the type stated in the catch clause returns true. This means that we can also
specify an interface as a type. However, there is an Exception as to what type can be
specified. Only classes that implement the Throwable interface can be specified in the catch
clause. Define a catch clause with a String type and you will receive compilation errors. The
Throwable interface is an empty interface. It doesn't contain any methods to be implement.
It is a implemented by a class to simply state that one can catch or throw objects of that
type and the object represents an Exception.
Now, lastly modify the code to include only the try block with no catch or finally blocks. You
will receive compilation errors as a try block needs to be followed by atleast a single catch
or a finally block.
The following example shows how exception handling can be used along with loops to
repeatedly ask the user to enter some data until he enters the required type. In this
example, the program asks for an integer. If the user enters some other data of some other
type, a message is displayed and the programs asks for new input.
public class TakeInput {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean success = false;
while (!success) {
try {
System.out.print("Enter an integer: ");
int num = s.nextInt();
System.out.println("You entered " + num);
success = true;
} catch (InputMismatchException e) {
s.next();
System.out.println("You have entered invalid data");
}
}
}
}

422

Note that within the catch block, we have included the statement, s.next(). This is because
the input stream still contains an invalid data ( date other than int ). To ignore this data, we
read it as a word. If the user has entered multiple words, each of these words would be
ignored in the subsequent iterations. Here is a sample execution.
Enter an integer: java
You have entered invalid data
Enter an integer: 34793479347934793479
You have entered invalid data
Enter an integer: java programming
You have entered invalid data
Enter an integer: You have entered invalid data
Enter an integer: 347
You entered 347

Exception Hierarchy
In the previous chapter, we have seen that an InputMismatchException can be caught by a
catch block defined to handle an exception of type 'Exception' since
InputMismatchException is a subclass of Exception. It is important to know the hierarchy of
exception classes in order to write correct programs. The class Exception lies at the root of
the exception hierarchy. Every exception type in Java is a subclass of Exception. Therefore,
a catch clause designed to handle Exception can process all pre-defined exceptions of
Java. However, in addition to the subclasses of Exception, we have subclasses of Error
which represents a condition that generally cannot be handled by the programmer. The
exceptions that inherit from Error denote serious errors like VirtualMachineError from which
a program cannot normally recover. Though it is syntaxialy correct to catch Errors also, one
however should refrain from doing so. Both, Exception and Error are subclasses of
Throwable. (We have both Throwable class and Throwable interface).
A number of other Exceptions are extended from class Exception. We can group them into
two categories. We can put the Runtime Exception into one category and all other
exceptions in the other category. We will see shortly why we have grouped them in this
way. The following diagram shows this hierarchy.

423

Java distinguishes between checked and unchecked exceptions. Checked exceptions are
those Exceptions for which we need to provide exception handling while unchecked
exceptions are those for which providing exception handlers is optional. You may know the
types of exceptions that would be thrown by looking at the documentation for the method
that you are calling. For example, when we are calling the nextInt() method to take an
integer input from the keyboard, we should also be having an idea of the exceptions that it
might throw. Look at the documentation for this method. You will see that three types of
Exceptions may be thrown by this method. Even when we have not provided exception
handlers for these three methods, the compiler as not raised any objection. This is because;
these three Exceptions are unchecked exception. All exceptions of type
RunTimeExcepotion or its subclasses are considered to be unchecked Exceptions. And , all
exceptions of type Exception other than RunTimeExcepotion are checked exceptions.
Checked exceptions should be either caught or be declared to be thrown. We shall see
shortly how we may throw exceptions instead of catching them.
Here are a few Exceptions that you should be familiar with:

424

ArrayIndexOutOfBoundsException ( unchecked) : Thrown when we try to access an array


element using an invalid index, such as negative index or anindfex greater to or equal to the
length of the array StringIndexOutOfBoundsException (unchecked) : Similar to the above
but deals with Strings enacted of arrays IndexOutOfBoundsException (unchecked) : A
super class of the above two Exception types NullPointerException (unchecked) : Thrown
when we try toy dereference a null pointer i.e. when we try to access an object through a
variable when the variable holds a value of null and does not holds a reference to an object
We need to keep the hierarchy of exceptions in mind when writing exception handlers for
our program. For example, let us provide two catch blocks for the program that we have
written earlier which takes an integral and displays it. One of these catch statements will be
catching the InputMismatchException and the other would be defined to catch a general
Exception. Now, what would happen if we define the catch block for Exception first followed
by a catch block for InputMismatchException?
catch (Exception e ) {
// code
}
catch ( InputMismatchException e ) {
// code
}
Now, compile this program. You will receive an unreachable code error saying that the
second catch handler can never be reached by the program. Why does this happen?
Assume that this program compiles well and we can execute it. If we enter a valid number,
no catch statement would be executed. If we enter an invalid input like a String, an
InputMismatchException would be thrown. As already said, the type of Exception thrown will
be compared with the types specified in the catch clauses in a sequential order. So, the
type InputMismatchException would be compared with the type Exception. Since,
InputMismatchException is a subclass of Exception, a match has occurred. The first catch
block will be executed. Once a catch block is executed, the remaining blocks would be
skipped and control would pass onto the finally block if it exists. So, in conclusion the
second catch block would never be executed. That is why the unreachable code
compilation error was generated. Therefore, we needed to catch subclass exceptions
before catching superclass exceptions. The proper way to define the above code is to catch
InputMismatchException first followed by Exception as shown below.
catch ( InputMismatchException e ) {
// code
}
catch (Exception e ) {

425

// code
}

Nested try catch blocks


Exception handlers can be nested within one another. A try, catch or a finally block can in
turn contains another set of try catch finally sequence. In such a scenario, when a particular
catch block is unable to handle an Exception, this exception is rethrown. This exception
would be handled by the outer set of try catch handler. Look at the following code for
Example.
import java.util.InputMismatchException;
public class Nested {
public static void main(String[] args) {
try {
System.out.println("Outer try block starts");
try {
System.out.println("Inner try block starts");
int res = 5 / 0;
} catch (InputMismatchException e) {
System.out.println("InputMismatchException caught");
} finally {
System.out.println("Inner final");
}
} catch (ArithmeticException e) {
System.out.println("ArithmeticException caught");
} finally {
System.out.println("Outer finally");
}
}
}
The output is
Outer try block starts
Inner try block starts
Inner final
ArithmeticException caught
Outer finally Outer finally
In this example, one try catch finally sequence has been nested within another try catch
finally sequence. The inner try block throws an ArithmeticException which it could not
handle. Hence, this exception is rethrown by the inner block which is handled in the outer
finally block. Note that all the finally blocks that come in the way of the program are excited.

426

Such nesting of try catch blocks can also occur in case of method calls. Nesting may not be
very explicit in such cases. Look at the following example which contains two methods
main() and meth(). Both the methods have exception handlers. meth() is invoked from the
method main(). The try block in meth() throws an ArithmeticException which it could not
handle. Hence, it is rethrown. This try catch sequence of meth() in nested within the try
catch sequence of main() by way of method call. Therefore, the exception is processed by
the finally block of the main() method.
public class Nested {
public static void main(String[] args) {
try {
meth();
} catch (ArithmeticException e) {
System.out.println("ArithmeticException caught");
} finally {
System.out.println("Outer finally");
}
}
public static void meth() {
try {
int res = 3 / 0;
} finally {
System.out.println("Finally in meth");
}
}
}
The output is
Finally in meth
ArithmeticException caught
Outer finally

Throwing Exceptions
We have seen till now how exceptions thrown by methods we invoke such as nextInt() can
be caught. We shall now see how we ourselves can throw exceptions. An exception is
thrown by specifying the throw keyword followed by an object reference.
throw <object>;

427

Only objects that have been created from classes which have implemented the Throwable
interface can be thrown. An object of an Exception can be created just like any other object
of a class by using one of the four forms of the constructor, which every Exception type
inherits from the Throwable class. We shall see two of them for now. One of these is the
default constructor and the other is the parameterised constructor which accepts a String
which acts as a description for the exception object we are creating. The following
statement shows the use of these two forms of the constructor to create an Exception
object.
Exception e = new Exception();
Exception e = new Exception ( "This is an Exception");
The objects created above may be thrown by using the throw keyword.
throw e;
We can also combine the statement that creates the Exception and the statement which
throws the Exception into a single statement.
throw new Exception();
The following program shows the use of the throw keyword.
public class ThrowException {
public static void main(String args[]){
try{
throw new Exception();
} catch(Exception e) {
System.out.println("Exception caught");
}
}
}
The output of this program would be
Exception caught

JAVA PROGRAMMS

Reversing a Number
We will see three different ways of reversing a number.

428

Reversing a Number using Mathematical Operations


Let the input number be n. We initialize the result to zero. When the program finishes
execution, result will contain the reversed number. We extract the digits of the number
starting from the right one by one and add it to the result. The extracted digit would be
removed from the original number. This task needs to be performed repeatedly until no
more digits are left in the original number. Since this task is repetitive in nature, we use a
while number with the loop condition being n > 0, where n is the input number. The last digit
of n can is the same as the remainder obtained on dividing the number by 10. We use the
modulo operator for this purpose. To remove the extracted number from n, we divide n by
10. Note that since both n and the number we are dividing with (10) are int values, the
resulting value will be an int and not a decimal. The final step is to add the extracted digit to
the result. This can be done by multiplying the result with 10 and adding the extracted digit
to it.To illustrate the above steps, let us take an example where a particular iteration n is 97
and the result till that point of time is 34. 97 % 10 gives 7 ( rem ). Diving n (97) by 10 makes
it 9. And finally, adding 7 to the result gives 34*10+7=347.
Given below is a method which takes an integer parameter n, reverses it and returns the
result.
public void reverse(int n) {
int result = 0;
int rem;
while (n > 0) {
rem = n % 10;
n = n / 10;
result = result * 10 + rem;
}
}
Here is a complete program which takes an integer input from the user and displays the
reversed number on the screen.
public class ReverseNumber {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the number to be reversed : ");
int input = s.nextInt();
int result = reverse(input);
System.out.println("The reversed number is " + result);
}

429

public static int reverse(int n) {


int result = 0;
int rem;
while (n > 0) {
rem = n % 10;
n = n / 10;
result = result * 10 + rem;
}
return result;
}
}
Here is a sample execution.
Enter the number to be reversed : 347
The reversed number is 743

Reversing a Number using String operations


To reverse a number using String operations, we first convert the int value to a String using
the static method, valueOf(int) of the String class. Next, we extract the characters of the
String from the right, one by one and append it to the result, which in the beginning of the
program would be initialised to an empty String. Finally, the reversed String can be
converted back to an int using the parseInt(String) method of Integer class.
Here is a method implementing the above procedure.
public static int reverse(int n) {
String input = String.valueOf(n);
String result = "";
for (int i = input.length() - 1; i >= 0; i--) {
result = result + input.charAt(i);
}
int reversedInt = Integer.parseInt(result);
return reversedInt;
}

Reversing a Number using StringBuilder


In the previous method, we have reversed the String manually by reading the characters
from right to left and adding them in that order to the result String. This reversing operation
can be done in more convenient way by using the StringBuffer class and its method
reverse(). We first construct a String using the input integer. A StringBuffer object is then

430

constructed using the String. These two steps can be combined into a single step in the
following way:
StringBuffer s = new StringBuffer(n+"");
However, the following statement will give incorrect results.
StringBuffer s = new StringBuffer(n);
This is because the constructor of StringBuffer requires a String as its input from which the
StringBuffer is to be constructed. If an integer is passed as an input, that integer would be
taken as the initial length of the StringBuffer.
The integer n concatenated with an empty String results in a String which is passed to the
constructor of StringBuffer. The reverse() process is then invoked on the StringBuffer object
which will reverse its contents. Now, the StringBuffer is converted back to a String and then
to an int using toString() and parseInt() methods respectively.
We can also use the StringBuilder class instead of the StringBuffer class. The difference
between these two classes is that StringBuffer is synchronised while StringBuilder is not.
Here is the complete method illustrating the above procedure.
public static int reverse(int n) {
String inputString = String.valueOf(n);
StringBuffer stringBuffer = new StringBuffer(inputString);
stringBuffer.reverse();
String reversedString = stringBuffer.toString();
int reversedInt = Integer.parseInt(reversedString);
return reversedInt;
}

Prime Numbers
A prime number has only two factors, namely one and itself. To determine whether a given
number is prime, we need to check if it has factors others than one and itself. If we are able
to find atleast one other factor, then we can conclude that the number is not prime. To
check if a number is a factor of the given number ( hereafter referred to as n ), we obtain the
remainder on dividing n by the number. If the remainder is zero, then the number is a
factor.
The next question is what is the range of numbers we need to consider while checking if
they are factors? Since, a number is definitely not divisible by any number greater than
itself, we can place n as the upper limit. We can further reduce this upper limit by noting that

431

a number has no other factors ( except itself ) greater than sqrt(n). To sum up, within a loop,
we find the remainder on dividing the number n with the loop counter which ranges from 2
to sqrt(n). If at any time, we get the remainder as zero, we conclude that the number is not
prime. Special checks should be used for the number one, which is neither prime nor
composute. If necessary, additional checks can be done for negative numbers.
Here is a method which takes an integer n as an input and returns true or false, depending
on whether the number is prime or not.
public boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Here is a complete Java programs which accepts a number from the user, checks if the
number is prime and displays the result on the screen.
import java.util.Scanner;
public class PrimeNumbers {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter a number : ");
int n = s.nextInt();
if (isPrime(n)) {
System.out.println(n + " is a prime number");
} else {
System.out.println(n + " is not a prime number");
}
}
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {

432

if (n % i == 0) {
return false;
}
}
return true;
}
}
Here are two sample executions of the above program.
Enter a number : 7
7 is a prime number
Enter a number : 34
34 is not a prime number
Here is a program which takes two numbers as input from the user and prints all the prime
numbers that lie between these two numbers.
import java.util.Scanner;
public class PrimeNumbers {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the first number number : ");
int start = s.nextInt();
System.out.print("Enter the second number number : ");
int end = s.nextInt();
System.out.println("List of prime numbers between " + start + " and " + end);
for (int i = start; i <= end; i++) {
if (isPrime(i)) {
System.out.println(i);
}
}
}
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;

433

}
}
return true;
}
}
Here is a sample run of the above program:
Enter the first number number : 2
Enter the second number number : 10
List of prime numbers between 2 and 10
2
3
4
5
7
9

Converting a String to different Cases - Upper Case, Lower Case,


Toggle Case, Camel Case and Sentence Case
In this article, we will see how to convert a given String to different cases using simple
looping and methods of the String class and the Character class. First, we clearly specify
what these different cases are. Then, we move on to see the different methods of the
Character and String class we would be using after which we proceed to the algorithms.
Finally we present a complete program which takes a String input and outputs it in the five
different cases.

The different cases


Upper Case : A String is converted to Upper Case by capitalizing each of the letters. Letters
that are already capitalised are left as they are. Non letters like numbers and special
characters are not altered.
Lower Case : The conversion of a String to lower case is similar to upper case except that
we change each of the letter to its lower case form. Toggle Case : Small letters a-z are
converted to capital letters A-Z and vice versa.
Camel Case: In Camel Case, the first letter of every word is capitalized.
Sentence Case: The starting letter of the first word of every sentence is capitalized.

434

Given below is an example illustrating the conversion of a String to the five different cases
mentioned above.
HeLLo java. hello WORlD.
Upper Case: HELLO JAVA. HELLO WORLD.
Lower Case: hello java. hello world.
Toggle Case: hEllO JAVA. HELLO worLd.
Camel Case: Hello Java. Hello World.
Title Case: Hello java. Hello world.

Methods of String and Character classes


We would be using length() and charAt(int) methods of the String class. The length()
method returns the numbers of characters that the String contains. The charAt() method
takes an integer argument and returns the character contained at that integer index. It is to
be noted that the indices begin from 0. The following code snippet illustrates the usage of
these two methods.
String s = "Java";
int len = s.length(); // len = 4
char c0 = s.charAt(0); // c0 = 'J'
char c2 = s.charAt(2); // c2 = 'v'
The Character class contains a number of static methods which can be used to test whether
a character is upper case or lower case and also convert between the two forms. The two
methods isUpperCase(char) and isLowerCase(char) take a character as an argument and
return a boolean value indicating whether the argument passed is an upper case char or a
lower case char. The methods toUpperCase(char) and toLowerCase(char) take char
arguments and return a char which is the upper case form and the lower case form of the
passed char respectively. If the character passed is not a letter, the return value will be the
same as the character passed. Here is a code snippet illustrating the use of the above
stated methods.
boolean a = Character.isUpperCase('A'); // true
boolean b = Character.isLowerCase('A'); // false
boolean c = Character.isUpperCase('<'); // false
boolean d = Character.isLowerCase('<'); // false
char e = Character.toLowerCase('A'); // 'a'
char f = Character.toUpperCase('a'); // 'A'
char g = Character.toLowerCase('<'); // '<'
char h = Character.toLowerCase('a'); // 'a'

Converting a String to Upper Case

435

To convert a String to Upper Case, we use a for loop whose counter, say i, runs from 0
through the length of the String (-1). A String variable 'result' is initialised with an empty
String. Within the loop, we extract the character at position i, convert it to an upper case
character using the toUpperCase () method and append the returned char to the result. At
the end of the loop, the result contains the input string with all characters changed to upper
case. Scroll down to the bottom of this page to the method toUpperCase() to view the code.

Converting a String to Lower Case


This task would be similar to the above except that instead of using the method
toUpperCase (), we use the method toLowerCase() to convert the characters to their lower
case form.

Converting a String to Toggle Case


To convert the String to its toggle form, we extract each character as we have done for
upper case conversion. We then use an if else decision making statement to check if the
extracted character is upper case or lower case. If the character is upper case, we convert it
to lower case and append it to the result. Otherwise, the upper case form of the character is
appended to the result. View the code at the bottom of this page.
It should be noted that we cannot use an if else if statement decision making statement as
shown below.
if (Character.isUpperCase(currentChar)) {
...
} else if (Character.isLowerCase(currentChar)) {
...
}
This is because there is a possibility for a character to be neither upper case nor lower case
- digits and special symbols like < , > etc. If a decision making statement as shown above is
used, these characters would be ignored.
Of course, a modified form of the above code can be used where we first check if the
character is an upper case character. Then we check if it is a lower case character. And
finally, if the character is neither an uppercase character nor a lower case character, we
simply append it to the result without any conversions.
if (Character.isUpperCase(currentChar)) { // Upper Case
char currentCharToLowerCase = Character.toLowerCase(currentChar);
result = result + currentCharToLowerCase;
} else if (Character.isLowerCase(currentChar)) { // Lower Case

436

char currentCharToUpperCase = Character.toUpperCase(currentChar);


result = result + currentCharToUpperCase;
} else { // Not a letter
result = result + currentChar;
}

Converting a String to Camel Case


As already said, in camel case, we capitalise the first letter of each word. To do so, we use
a loop similar to what we have used in the previous conversions. Within the loop, we check
if the character at index i-1 is a space. If it is so, we capitalise the current character at index
i and append it to the result. Otherwise, we convert the current char to lower case and
append it.
However, we will experience a problem when the loop counter i has the value of zero as
accessing character at index (0-1) will result in an exception. To avoid this, before the loop,
we check if the length of the input string is zero. If it is so, we simply return an empty String.
Otherwise, we initialise the result with the capitalized version of the character at index zero
and then start the loop from i = 1. The code is shown at the bottom of this page.

Converting a String to Sentence Case


In sentence case, the first letter of each sentence is capitalized. This conversion cannot be
solved in a way similar to the camel case problem, replacing the space with a period. The
reason is that a sentence does not always end in a period. Sentences also end with
question marks and exclamation marks. The second reason is that the first letter of the
sentence doesn't always immediately follow the period. In most cases, there is a space
between the two.
To tackle the above problems, we maintain an array of terminal characters - the characters
with which a sentence ends such as period, exclamation mark and question mark. We will
also use a boolean variable 'terminalCharacterEncountered' which will be set to true
whenever one of the terminal characters is encountered. Within the loop, we first extract a
character, if the terminalCharacterEncountered flag is false, we simply append the
character to the output String. If the flag was true, the current character is capitalized and
appended to the result. And then, the flag is reset to false. After performing the above task,
we check if the current character is one of the terminal characters. If so, the flag is set to
true again so that the first character of the next sentence will be capitalised. The code is
shown in the next section ( scroll down).

The Program

437

Given below is a complete program which takes an input String from the user, converts it
into different cases and displays them on the console.
import java.util.Scanner;
public class CaseManipulation {
public static String toUpperCase(String inputString) {
String result = "";
for (int i = 0; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
char currentCharToUpperCase = Character.toUpperCase(currentChar);
result = result + currentCharToUpperCase;
}
return result;
}
public static String toLowerCase(String inputString) {
String result = "";
for (int i = 0; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
char currentCharToLowerCase = Character.toLowerCase(currentChar);
result = result + currentCharToLowerCase;
}
return result;
}
public static String toToggleCase(String inputString) {
String result = "";
for (int i = 0; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
if (Character.isUpperCase(currentChar)) {
char currentCharToLowerCase = Character.toLowerCase(currentChar);
result = result + currentCharToLowerCase;
} else {
char currentCharToUpperCase = Character.toUpperCase(currentChar);
result = result + currentCharToUpperCase;
}
}
return result;
}
public static String toCamelCase(String inputString) {
String result = "";

438

if (inputString.length() == 0) {
return result;
}
char firstChar = inputString.charAt(0);
char firstCharToUpperCase = Character.toUpperCase(firstChar);
result = result + firstCharToUpperCase;
for (int i = 1; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
char previousChar = inputString.charAt(i - 1);
if (previousChar == ' ') {
char currentCharToUpperCase = Character.toUpperCase(currentChar);
result = result + currentCharToUpperCase;
} else {
char currentCharToLowerCase = Character.toLowerCase(currentChar);
result = result + currentCharToLowerCase;
}
}
return result;
}
public static String toSentenceCase(String inputString) {
String result = "";
if (inputString.length() == 0) {
return result;
}
char firstChar = inputString.charAt(0);
char firstCharToUpperCase = Character.toUpperCase(firstChar);
result = result + firstCharToUpperCase;
boolean terminalCharacterEncountered = false;
char[] terminalCharacters = {'.', '?', '!'};
for (int i = 1; i < inputString.length(); i++) {
char currentChar = inputString.charAt(i);
if (terminalCharacterEncountered) {
if (currentChar == ' ') {
result = result + currentChar;
} else {
char currentCharToUpperCase = Character.toUpperCase(currentChar);
result = result + currentCharToUpperCase;
terminalCharacterEncountered = false;
}
} else {
char currentCharToLowerCase = Character.toLowerCase(currentChar);
result = result + currentCharToLowerCase;
}

439

for (int j = 0; j < terminalCharacters.length; j++) {


if (currentChar == terminalCharacters[j]) {
terminalCharacterEncountered = true;
break;
}
}
}
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter an input String: ");
String inputString = scanner.nextLine();
System.out.println("Upper Case: " + toUpperCase(inputString));
System.out.println("Lower Case: " + toLowerCase(inputString));
System.out.println("Toggle Case: " + toToggleCase(inputString));
System.out.println("Camel Case: " + toCamelCase(inputString));
System.out.println("Title Case: " + toSentenceCase(inputString));
}
}

Finding Factorial of a Number in Java


The factorial of a number is defined is the product of natural numbers from one to that
particular number. Mathematically,
n! = 1 * 2 * 3 * .... * (n-1) * n
For example, the factorial of 4 is
4! = 1 * 2 * 3 * 4 = 24
This article will explain you how to find the factorial of a number through iteration as well as
recursion.

Finding factorial of a number in Java using Iteration


Let the number whose factorial is to be found be stored in the variable n. A new variable
'result' of type int is declared and initialised with the integer 1.
int result = 1;

440

Now, our task is to multiply the variable result with all natural numbers from 1 to n. For this
purpose, we use a for loop with a counter i that ranges from 1 to n. Within the loop, the
existing value of result will be multiplied with the loop counter.
for (int i = 1; i <= n; i++) {
result = result * i;
}
Let us take a small number n = 3 to understand how the above loop works. Before entering
the loop, result would be initialised to one. The loop will execute thrice with the value of i =
1, 2 and 3. When the value of i becomes 4, the loop condition fails. When the value of i is 1,
the existing result would be multiplied with 1 which again gives one. In the second iteration,
result will be multiplied with 2 and in the third iteration with 3. These calculations are shown
below:
result = 1
i = 1 result = result * i = 1 * 1 = 1
i = 2 result = result * i = 1 * 2 = 2
i = 3 result = result * i = 2 * 3 = 6
When the loop exists, the value result which was initially one would be already multiplied by
all natural numbers from 1 to n. Thus, result holds the factorial of the number.
Given below is a program which finds the factorial of the number 7.
public class Factorial {
public static void main(String[] args) {
int n = 7;
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
System.out.println("The factorial of 7 is " + result);
}
}
The output of the above program would be
The factorial of 7 is 5040
We can start the loop counter, i from 2 instead of 1 because in the first iteration the value of
result gets multiplied by 1 which again gives one. The modified loop can be written as

441

for (int i = 1; i <= n; i++) {


result = result * i;
}
We can also start the loop counter from n and decrement it till 2 or 1. In that case, the loop
would look like
for (int i = n; i >= 1; i--) {
result = result * i;
}
Given below is another program where the number whose factorial is to be calculated is
taken as an input from the user and the result is displayed on the screen.
import java.util.Scanner;
public class Factorial {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the number whose factorial is to be found: ");
int n = scanner.nextInt();
int result = factorial(n);
System.out.println("The factorial of " + n + " is " + result);
}
public static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
}
Here is a sample execution
Enter the number whose factorial is to be found: 7
The factorial of 7 is 5040

Finding factorial of a number in Java using Recursion

442

The factorial of a number be found using recursion also. The base case can be taken as the
factorial of the number 0 or 1, both of which are 1. The factorial of some number n is that
number multiplied by the factorial of (n-1). Mathematically,
factorial ( 0 ) = 1
factorial ( n ) = n * factorial ( n - 1 )
Given below is a program which calculates the factorial of 7 using recursion.
public class Factorial {
public static void main(String[] args) {
int n = 7;
int result = factorial(n);
System.out.println("The factorial of 7 is " + result);
}
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}

Integer Overflow when finding factorial


When the factorial program is run with certain inputs 13 and above, we get incorrect results
- negative numbers or results which do not match with the actual factorial of that number.
The reason is that the factorial of numbers greater than or equal to 13 is too large for the int
data type. We can use the long data type but still it wouldn't be large enough to hold the
factorial of even higher numbers. The solution is to use the BigInteger class which can
handle arbitrarily large numbers which is discussed here. (link will be updated soon )

Java Program to print Finbonacci Series


The following sequence of numbers is known as Fibonacci numbers or sequence or series.
0, 1, 1, 2, 3, 5, 8, 13, 21 ....
To obtain the sequence, we start with 0 and 1 after which every number is the sum of the
previous two numbers.

443

For example, the first two numbers will be 0 and 1


0, 1
To obtain the next number, we add the previous two numbers - 0 and 1 which gives one.
0, 1, 1
The next number would be 1 + 1 = 2
0, 1, 1, 2
Now, the next number would be 1 + 2 = 3
0, 1, 1, 2, 3
Continuing in this way gives the Fibonacci series. A particular term in the series is
represented as Fn where n is the position of that number from the beginning. For example,
F0 = 0, F1 = 1, F2 = 1, F3=2, F4 = 3, F5 = 5 and so on...
The Fibonacci series can be expressed as a recurrence relation as shown below:
F0 = 0
F1 = 1
Fn = Fn-1 + Fn-2 ; n>=2

Printing the Fibonacci Series using Iteration


We will see how recursion can be used to print the Fibonacci Series. We will write a
program which takes an input n and prints the first (n+1) terms of the Fibonacci series. n = 0
and n = 1 will be considered as special cases and the series for these input values of n will
be printed directly. We will use two variables a and b which will hold the last two terms of
the Fibonacci series that has already been printed. For example, after printing the first five
terms of the sequence, i.e. 0, 1, 1, 2, 3; the value of a will be 2 and b will be 3. The next
term in the sequence will be the sum of a and b. Now, the values of a and b should be
updated so that they will again hold the last two terms that were printed. To do so, we copy
b to a, and the sum of the previous values of a and b to b. The loop will be repeated n-1
times.
The program is given below.
import java.util.Scanner;
public class FibonacciSeries {

444

public static void main(String[] args) {


Scanner s = new Scanner(System.in);
System.out.print("Enter the value of n: ");
int n = s.nextInt();
fibonacci(n);
}
public static void fibonacci(int n) {
if (n == 0) {
System.out.println("0");
} else if (n == 1) {
System.out.println("0 1");
} else {
System.out.print("0 1 ");
int a = 0;
int b = 1;
for (int i = 1; i < n; i++) {
int nextNumber = a + b;
System.out.print(nextNumber + " ");
a = b;
b = nextNumber;
}
}
}
}
Here is a sample execution
Enter the value of n: 7
0 1 1 2 3 5 8 13

Fibonacci Series using Recursion


The recursive definition of Fibonacci Series has already been stated at the start of this
article. The Java program is given below.
import java.util.Scanner;
public class FibonacciSeries {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the value of n: ");
int n = s.nextInt();

445

for (int i = 0; i <= n; i++) {


System.out.print(fibonacci(i) + " ");
}
}
public static int fibonacci(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}

Armstrong Numbers - Java Program


An Armstrong number is the one that equals the sum of its digits raised to the power of the
number of digits in that number which is to be checked. To be more clear, let the number be
n and the number of digits be x. We represent the number as nxnx-1nx-2...n3n2n1 where n1, n2,
n3...nx are single digits 0-9. n is an Armstrong number if
n1x + n2x + n3x + nx-1x + nxx = n
153, 371, 9474 and 54748 are few Armstrong numbers.
153 = 13 + 53 + 33
371 = 33 +73 +13
9474 = 94 + 44 +74 + 44
54748 = 55 + 45 + 75 + 45 + 85

Java Program to check whether a given number is an Armstrong number


Let the number that is to be checked be stored in an int variable input. We make a copy of
that input and store it in copyOfInput. It is required that we make a copy because the
number to be checked will be changed during the execution of the program and towards the
end, we need the original input number to declare whether it is an Armstrong number or
not.
We first find the number of digits in the input number. To do so, we construct a String by
concatenating the input number with a null string. We can also use the valueOf(int) method

446

of the String class. The length of the resultant string obtaining using the length() method will
give us the number of digits in the input number.
We also declare a variable sum and initialise it to zero. This variable will hold the sum of the
digits raised to the appropriate powers.
Next, in a while loop, we extract the digits of the input from right to left, raise them to the
appropriate power and add to the existing value of sum. To extract the last digit of the
number, we find the remainder obtained don dividing that number by 10 using the modulo
operator. The remainder is raised to the power numberOfDigits using the Math.pow()
function. This function returns a double value which we explicitly cast to an int so that we
can add it to the existing sum. Now, the last digit of copyOfInpuit will be truncated by diving
it with 10. The while loop executes as long as copyOfInput is not zero. When it is zero, all
the digits would have been processed.
Finally, we check if sum equals the input number. If it is so, the number is an Armstrong
number. Given below is the complete code for this program.
import java.util.Scanner;
public class ArmstrongNumber {
public static boolean isArmstrong(int input) {
String inputAsString = input + "";
int numberOfDigits = inputAsString.length();
int copyOfInput = input;
int sum = 0;
while (copyOfInput != 0) {
int lastDigit = copyOfInput % 10;
sum = sum + (int) Math.pow(lastDigit, numberOfDigits);
copyOfInput = copyOfInput / 10;
}
if (sum == input) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a number: ");
int inputNumber = scanner.nextInt();

447

boolean result = isArmstrong(inputNumber);


if (result) {
System.out.println(inputNumber + " is an armstrong number");
} else {
System.out.println(inputNumber + " is not an armstrong number");
}
}
}
Here are two sample executions of the program.
Enter a number: 153
153 is an armstrong number
Enter a number: 3479
3479 is not an armstrong number

Java Program to print Armstrong Numbers


Here is another Java program which takes a start and an end number and prints all the
Armstrong numbers that lie between the above two numbers.
import java.util.Scanner;
public class ArmstrongNumber {
public static boolean isArmstrong(int input) {
String inputAsString = input + "";
int numberOfDigits = inputAsString.length();
int copyOfInput = input;
int sum = 0;
while (copyOfInput != 0) {
int lastDigit = copyOfInput % 10;
sum = sum + (int) Math.pow(lastDigit, numberOfDigits);
copyOfInput = copyOfInput / 10;
}
if (sum == input) {
return true;
} else {
return false;
}
}
public static void printAll(int start, int end) {
System.out.println("List of Armstrong Numbers between " + start + " and " + end + " :");

448

for (int i = start; i <= end; i++) {


if (isArmstrong(i)) {
System.out.println(i);
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter start number: ");
int start = scanner.nextInt();
System.out.print("Enter end number: ");
int end = scanner.nextInt();
printAll(start, end);
}
}
Here is a sample execution
Enter start number: 1
Enter end number: 3479
List of Armstrong Numbers between 1 and 3479 :
1
2
3
4
5
6
7
8
9
153
370
371
407
1634

Matrix Addition and Subtraction


We will see how to perform matrix addition and subtraction in java. The two operations are
similar except for a small difference.
A matrix can be represented in Java as a two dimensional array with the length of the 2D
array equal to the number of rows of the matrix and the length of the sub arrays equal to the

449

number of columns of the matrix. For example, a matrix of order 3*7 will be represented as
a 2D array matrix[3][7]. A two level nested for loop will be used to read the input matrices
from the keyboard. The outer loop counter, i ranges from 0 to the number of rows of the
matrix while the inner loop counter, j ranges from 0 to the number of columns of the matrix.
Within the inner loop, the input integers will be read using nextInt() method of the scanner
class and stored at position [i][j] of the array.
Once the two matrices are read, we use a two level nested for loop with loop counters
similar to the ones used for adding the matrices. The elements at [i][j] of the two input
matrices are added and the result is stored at position [i][j] of the result matrix. For
subtraction, the same procedure is followed except that we subtract the elements at [i][j]
instead of adding them.
Finally, we print the matrices using a nested for loop. We wish to print the array in the form
of a rectangular matrix. For this purpose, we use print() instead of println() for displaying the
values within the inner loop. At the end of the inner loop, we use a println() statement
without any arguments to move to the next line.
The complete Java program for addition of two matrices is given below.
import java.util.Scanner;
public class MatrixAddition {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter number of rows: ");
int rows = s.nextInt();
System.out.print("Enter number of columns: ");
int columns = s.nextInt();
int[][] a = new int[rows][columns];
int[][] b = new int[rows][columns];
System.out.println("Enter the first matrix");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
a[i][j] = s.nextInt();
}
}
System.out.println("Enter the second matrix");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
b[i][j] = s.nextInt();
}

450

}
int[][] c = new int[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
c[i][j] = a[i][j] + b[i][j];
}
}
System.out.println("The sum of the two matrices is");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
}
Here is a sample execution.
Enter number of rows: 2
Enter number of columns: 3
Enter the first matrix
347
184
Enter the second matrix
321
104
The sum of the two matrices is
668
288
For subtraction, the plus sign in line 'c[i][j] = a[i][j] + b[i][j];' should be changed to a minus
sign.
In the above program, a lot of code was repetitive in nature. We have used the same code
to read the two matrices. If both addition and subtraction are to be performed, the code for
printing the matrices will also be duplicated twice. Instead of writing the same code a
number of times, we can use methods. Given below is a modified version of the previous
program which takes two input matrices A and B and performs three operations, A+B, A-B,
B-A.
import java.util.Scanner;
public class Matrices {

451

public static void main(String[] args) {


Scanner scanner = new Scanner(System.in);
System.out.print("Enter number of rows: ");
int rows = scanner.nextInt();
System.out.print("Enter number of columns: ");
int columns = scanner.nextInt();
System.out.println();
System.out.println("Enter first matrix");
int[][] a = readMatrix(rows, columns);
System.out.println();
System.out.println("Enter second matrix");
int[][] b = readMatrix(rows, columns);
int[][] sum = add(a, b);
int[][] difference1 = subtract(a, b);
int[][] difference2 = subtract(b, a);
System.out.println();
System.out.println("A + B =");
printMatrix(sum);
System.out.println();
System.out.println("A - B =");
printMatrix(difference1);
System.out.println();
System.out.println("B - A =");
printMatrix(difference2);
}
public static int[][] readMatrix(int rows, int columns) {
int[][] result = new int[rows][columns];
Scanner s = new Scanner(System.in);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
result[i][j] = s.nextInt();
}
}
return result;
}
public static int[][] add(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] result = new int[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {

452

result[i][j] = a[i][j] + b[i][j];


}
}
return result;
}
public static int[][] subtract(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] result = new int[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
result[i][j] = a[i][j] - b[i][j];
}
}
return result;
}
public static void printMatrix(int[][] matrix) {
int rows = matrix.length;
int columns = matrix[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}
Here is a sample output.
Enter number of rows: 2
Enter number of columns: 2
Enter first matrix
34
79
Enter second matrix
12
34
A+B=

453

46
10 13
A-B=
22
45
B-A=
-2 -2
-4 -5

Matrix Multiplication - Java Program


This article shows you how to write a matrix multiplication program in Java. A three level
nested loop is used to perform the multiplication.
Let the two matrix to be multiplied be A and B. Let A be a matrix of order d*e - d rows and e
columns and B be the second matrix of order e*f. Note that the number of columns in the
first matrix should be the same as the number of rows in the second matrix. The product
matrix will be of order d*f. Now, our task is to find what numbers go into each of the
positions of matrix C with d rows and f columns. We use an outer loop with loop counter i
ranging from 0 to d. An inner loop has the loop counter j ranging from 0 to f. At any iteration
of the loop, i refers to the row number and j to the column number of the position in matrix C
that we are trying to fill. Now, within the body of the inner loop, we have to write some code
which will calculate the value to be filled. This body will in turn consist of a loop. When we
are obtaining the value at C[i][j], row i of matrix A and column j of matrix B are multiplied
element wise.
C[i][j] = A[i][0] * B[0][j] + A[i][1] * B[1][j] + A[i][2] * B[2][j] + .... A[i][e-1] * B[e-1][j]
Both row i and column j have e elements. An loop is used whose counter k, ranges from 0
to e-1. Within the loop, A[i][k] and B[k][j] are multiplied and the product obtained is added to
the existing value of C[i][j]. We can also declare a variable sum before the start of the
innermost loop, add the element wise products to this variable and assign the resulting sum
to C[i][j].
The complete Java program for matrix multiplication is given below.
import java.util.Scanner;
public class MatrixMultiplication {
public static void main(String[] args) {

454

Scanner s = new Scanner(System.in);


System.out.print("Enter number of rows in A: ");
int rowsInA = s.nextInt();
System.out.print("Enter number of columns in A / rows in B: ");
int columnsInA = s.nextInt();
System.out.print("Enter number of columns in B: ");
int columnsInB = s.nextInt();
int[][] a = new int[rowsInA][columnsInA];
int[][] b = new int[columnsInA][columnsInB];
System.out.println("Enter matrix A");
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
a[i][j] = s.nextInt();
}
}
System.out.println("Enter matrix B");
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[0].length; j++) {
b[i][j] = s.nextInt();
}
}
int[][] c = multiply(a, b);
System.out.println("Product of A and B is");
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c[0].length; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
public static int[][] multiply(int[][] a, int[][] b) {
int rowsInA = a.length;
int columnsInA = a[0].length; // same as rows in B
int columnsInB = b[0].length;
int[][] c = new int[rowsInA][columnsInB];
for (int i = 0; i < rowsInA; i++) {
for (int j = 0; j < columnsInB; j++) {
for (int k = 0; k < columnsInA; k++) {
c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
}
}
return c;

455

}
}
Here is a sample execution of the above program.
Enter number of rows in A: 2
Enter number of columns in A / rows in B: 3
Enter number of columns in B: 3
Enter matrix A
134
256
Enter matrix B
156
254
111
Product of A and B is
11 24 22
18 41 38

Finding factorial of large numbers in Java using BigInteger


The factorial of numbers greater than or equal to 13 cannot be found using the program
shown on this page due to overflow. These factorials are too large to fit in an int variable.
Even if we use the long data type, factorials greater than or equal to 21 will generate an
overflow. To find the factorial of arbitrarily large numbers, we use the BigInteger class which
is a part of the java.math package.
Given below is the program to find factorial using the BigInteger. The explanation of the
program follows it.
import java.math.BigInteger;
import java.util.Scanner;
public class Factorial2 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter a number: ");
int n = s.nextInt();
String fact = factorial(n);
System.out.println("Factorial is " + fact);
}
public static String factorial(int n) {

456

BigInteger fact = new BigInteger("1");


for (int i = 1; i <= n; i++) {
fact = fact.multiply(new BigInteger(i + ""));
}
return fact.toString();
}
}
The BigInteger class is used to represent arbitrarily large numbers. Overflow doesn't occur
as is the case with int and long. A BigInteger object is created by passing a String which
contains an integer value. We have created a BigInteger object named 'fact' which will hold
the factorial of the number and initialised it with 1.
BigInteger fact = new BigInteger("1");
The loop that follows is identical to the one we use in a normal factorial program.
Multiplication of two BigIntegers is performed using the multiply function which takes a
BigInteger as an argument. The BigInteger class is immutable which means that the object
on which the multiply function was invoked doesn't change the integer it is holding. The
multiplication is performed and a new BigInteger is returned which needs to be stored in the
variable fact.
fact = fact.multiply(new BigInteger(i + ""));
If the following statement is used instead of the above line, the programs always returns
one as the answer.
fact.multiply(new BigInteger(i + ""));
This is because, we have initialised fact with '1'. The multiplication has no effect on the
integr value stored in fact since the object returned by multiply() was not stored back in fact.
Even after the end of the loop, fact still holds the value '1'. Here is a sample execution of the
program.
Enter a number: 34
Factorial is 295232799039604140847618609643520000000

Towers of Hanoi
The 'Towers of Hanoi' is a classical problem used to illustrate the power of recursion. The
puzzle goes as follows.
There are three poles and 64 discs of different sizes. Initially, all the discs are placed on the
first pole with the largest disc at the bottom and the smallest one at the top. We need to

457

move all the discs from the first pole to the third pole, with the smallest disc at the top and
the largest at the bottom. We can move only one disc at a time (which should be the
topmost disc) and at any point of time, a larger disc cannot be placed over a smaller one i.e.
all the discs on a pole must be placed in such a way that the smallest is at the top and the
largest at the bottom. The second pole can be used as an intermediate pole to help us in
transferring the discs.
This puzzle can be solved using recursion. For a moment, assume that there are just two
discs (disc 1 and 2; disc 2 being the larger one) on the first pole. The solution consists of
three steps.
Step
Step
Step

1:
2:
3:

Move
Move
Move

disc
disc
disc

1
2
1

from
from
from

pole
pole
pole

1
1
1

to
to
to

pole
pole
pole

2.
3.
3.

Now, assume that disc 1 is not a single disc but a collection of discs. The procedure would
be similar to the above three steps, but steps 1 and 3 would be a collection of steps. Step 1
would be to move the n-1 discs (assuming that there were a total of n discs) from pole 1 to
pole 2. For moving these (n -1) discs, we again follow the same strategy of considering
them as 1 disc plus a set of n-2 discs. Step 3 would also be similar. This gives us the
recursive solution.

Recursive Algorithm
The recursive solution to move n discs from the start pole to the end pole using an auxiliary
pole is given below.
Base
Case
Move the disc from start pole to end pole

When

Recursive
Case
When
n
Step
1:
Move
(n-1)
discs
from
start
pole
to
Step
2:
Move
the
last
disc
from
start
pole
Step
3:
Move
the
(n-1)
discs
from
auxiliary
pole
Steps 1 and 3 are recursive invocations of the same procedure.

Java Program
The recursive program for the puzzle in Java is given below:
public class TowersOfHanoi {

>
auxiliary
to
end
to
end

1
pole.
pole.
pole.

458

public void solve(int n, String start, String auxiliary, String end) {


if (n == 1) {
System.out.println(start + " -> " + end);
} else {
solve(n - 1, start, end, auxiliary);
System.out.println(start + " -> " + end);
solve(n - 1, auxiliary, start, end);
}
}
public static void main(String[] args) {
TowersOfHanoi towersOfHanoi = new TowersOfHanoi();
System.out.print("Enter number of discs: ");
Scanner scanner = new Scanner(System.in);
int discs = scanner.nextInt();
towersOfHanoi.solve(discs, "A", "B", "C");
}
}
The method solve() takes four arguments :
n
the
number
of
discs
in
the
puzzle
start, auxiliary, end -the names of the three poles which will be used for printing the solution
We first check if the number of poles, n is equal to one. If so, the base case solution will be
used which consists of moving a disc from the start peg to the end peg. If not, the recursive
solution is used which consists of two recursive calls to the same procedure solve(). When
we need to move n-1 discs from the start pole to the auxiliary pole, the auxiliary pole
becomes the end pole and the end pole becomes the auxiliary pole. That is why we have
written
solve(n - 1, start, end, auxiliary)
instead of
solve(n - 1, start, auxiliary, end)

Next we print ' start -> end ' which corresponds to moving the largest disc at the bottom
from the start peg to the end peg.
Finally, we have recursive invocation of solve(). Here, the auxiliary peg becomes the start
peg and the start peg becomes the auxiliary peg.
Here is a sample output with n = 3.

459

Enter number of discs: 3


A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C

Pascal's Triangle
This article intends to show the different ways to print a Pascal's triangle and also format it
so that it looks like an isosceles triangle.
Understanding how a Pascal's triangle is built would be easier by considering the following
figure which shows the first six rows of the Pascal's triangle.
1
11
121
1331
14641
1 5 10 10 5 1
Each row begins and ends with the number one. The remaining numbers are obtained by
summing the two numbers that lie directly above that number on the previous row and the
number that follows it. So, in order to find the numbers in the nth row of the triangle, we
need the values of the (n-1) the row. Let's say that we have computed the fourth row - 1 3 3
1. Now, the fifth row has five elements. The first and the last element would be one. The
remaining elements would be (1+3), (3+3), (3+1) = 4, 6, 4. So, the complete fifth row would
be 1 4 6 4 1.

Pascal's triangle using loops


We will first see how to generate a (unformatted ) Pascal's triangle using simple looping
statements. We maintain two int arrays, named currentRow and previousRow. Initially,
previousRow would be initialised with { 1 } - the contents of the first row of the Pascal's
triangle. After that, we have a loop whose loop counter, i runs from 2 to n where n is the
number of rows that we wish to display. At any iteration, I represents the row number that
we are printing. The currentRow will be initialised with an array of i (the loop counter)
elements with the first and the last element of the array set to '1'. Next, we have an inner
loop whose task is to compute the elements of currentRow. To do so, the loop counter, j
runs from 0 to i-3. The numbers in the array previousRow at indices j and j+1 are added and

460

the result is stored at the index j+1 of currentRow. When the inner loop exits, currentRow
would be populated. The values stored in currentRow are printed and previousRow is
assigned with currentRow so that it can be used in the next iteration of the outer loop.
Given below is a complete program which takes an input n from the user and prints the first
n lines of the Pascal's triangle.
import java.util.Scanner;
public class PascalTriangle {
public static void print(int n) {
int[] previousRow;
int[] currentRow = {1};
printArray(currentRow);
previousRow = currentRow;
for (int i = 2; i <= n; i++) {
currentRow = new int[i];
currentRow[0] = 1;
currentRow[i - 1] = 1;
for (int j = 0; j <= i - 3; j++) {
currentRow[j + 1] = previousRow[j] + previousRow[j + 1];
}
printArray(currentRow);
previousRow = currentRow;
}
}
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the row number upto which Pascal's triangle has to be printed:
");
int row = scanner.nextInt();
print(row);
}
}

461

Here is a sample execution of the above program.


Enter the row number up to which Pascal's triangle has to be printed: 7
1
11
121
1331
14641
1 5 10 10 5 1
1 6 15 20 15 6 1

Pascal's triangle as binomial coefficients


The Pascal's triangle can also be visualised as the binomial coefficients in the expansion of
(x+y)n where n is the row of the Pascal's triangle, with the rows labelled starting from n=0.
Using this observation, one can calculate the values in the Pascal's triangle by the direct
application of the nCk formulae. Now, the rows would be labelled from n=0 and the
elements within a row would be labelled from k=0. Using this numbering scheme, the
element in row n and at position k can be calculated as
nCk = n!/(k! * (n-k)! )
Given below is the program which uses this method to print the Pascal's triangle.
import java.util.Scanner;
public class PascalTriangle {
public static void print(int row) {
for (int n = 0; n < row; n++) {
for (int k = 0; k <= n; k++) {
System.out.print(nCk(n, k) + " ");
}
System.out.println();
}
}
public static int nCk(int n, int k) {
int numerator = fact(n);
int denominator = fact(k) * fact(n - k);
int result = (int) (numerator / denominator);
return result;
}

462

public static int fact(int num) {


int result = 1;
for (int i = 1; i <= num; i++) {
result = result * i;
}
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the row number upto which Pascal's triangle has to be printed:
");
int row = scanner.nextInt();
print(row);
}
}

Generating Pascal's triangle using recursion


Since calculating the value of a particular position in the triangle uses previously calculated
values, this problem can also be solved using recursion. The number at position row i and
column j would be represented as pascal(i,j) with I and j starting from 0. There would be two
base conditionswhich are related to the first and last elements, which are always one.
These two conditions can be expressed as
pascal ( i, 0 ) = 1
pascal ( i, i ) = 1
Following is the recursive formula used to calculate the remaining elements :
pascal ( i, j ) = pascal ( i - 1 , j -1 ) + pascal ( i - 1 , j )
Given below is the program which uses the recursive definition of the Pascal's triangle
import java.util.Scanner;
public class PascalTriangle {
public static void print(int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
System.out.print(pascal(i, j) + " ");
}
System.out.println();

463

}
}
public static int pascal(int i, int j) {
if (j == 0) {
return 1;
} else if (j == i) {
return 1;
} else {
return pascal(i - 1, j - 1) + pascal(i - 1, j);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the row number upto which Pascal's triangle has to be printed:
");
int row = scanner.nextInt();
print(row);
}
}

Java program to convert decimal number to binary number


The program for conversion of decimal to binary depends on the problem specification. It
may be given that the decimal number is always positive or it can be both positive and
negative. Another thing to consider is the number of bits we are allotted for the binary
representation. Finite number of bits in binary cannot represent any arbitrary large decimal
number. The program given here assumes that the decimal number that we are given as
input is positive. We first explain the procedure for converting a positive decimal number to
a binary number and then give the program.

Procedure
First, let us see how humans perform the computation. We start with the given decimal
number, and repeatedly divide it by 2 (whole number division where the result will be only
the quotient, a whole number) and note down the remainder at every step till we obtain the
quotient as 0. The remainders obtained in each step when concatenated together (the last
remainder taken as the first digit of the binary number) give the binary form of the decimal
number.
Shown below is the repeated division of 14.

464

The remainders obtained when concatenated together give the binary representation of 14
which is 1110.

Java Program
The program is given below. The explanation follows it.
import java.util.Scanner;
public class DecimalToBinary {
public String toBinary(int n) {
if (n == 0) {
return "0";
}
String binary = "";
while (n > 0) {
int rem = n % 2;
binary = rem + binary;
n = n / 2;
}
return binary;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

465

System.out.print("Enter a number: ");


int decimal = scanner.nextInt();
DecimalToBinary decimalToBinary = new DecimalToBinary();
String binary = decimalToBinary.toBinary(decimal);
System.out.println("The binary representation is " + binary);
}
}
The method toBinary() accepts an integer n that should be converted to binary format. As
we said earlier, the number n should be repeatedly divided by 2 till we obtain 0 and the
remainders should be concatenated. We use the String variable 'binary' to hold the result.
The while loop has the condition n!=0 which will repeatedly perform the operations in the
while block as long as n is not zero.
The while loop contains three statements.
The first is finding the remainder on dividing n by 2 which is obtained by using the modulo
operator.
The next step concatenates the remainder to the binary representation we have obtained so
far. Note that we have written 'rem + binary' and not 'binary + rem'. This is because the last
remainder will be the first bit in the binary representation. Consider that just before the last
division, we have binary = 100. If the last step gives rem = 1, then 'rem + binary' will be
1100 which is correct as the last remainder was placed in the beginning of the binary
representation. If we had used 'binary + rem', the result would have been '1001' which is
incorrect.
The third statement in the while loop updates the value of n to n/2 i.e. it divides the value by
2 and takes the quotient. Note that both n and 2 are integers which on division will return an
integer and not a real number.
Now, let us see what will happen if we invoke the method toBoolean() with decimal = 0
(when the special check for n == 0 is not present). The variable binary will be initialised to
"". The condition n!=0 is false, so the loop will not be executed even once and the result
returned would be "". But the correct answer is "0". So, we add a special check for decimal
= 0 and return "0" as the result.
Given below is a sample output.
Enter a number: 14
The binary representation is 1110

466

Sieve of Eratosthenes
The sieve of Eratosthenes is an efficient method for computing primes upto a certain
number. We first look at the algorithm and then give a program in Java for the same.

Algorithm
If you want to calculate all the primes up to x, then first write down the numbers from 2 to x.
Remove the first number from this list (say y) and add it to the list of primes. Find all the
multiples of y (excluding y) less than or equal to x and remove them out from the list.
Repeat the above process until there you are left with no numbers.
We illustrate this procedure by finding all primes less than 15. (To indicate removal of an
item from the list, we simply strike it out and to indicate addition of a number to the primes
list, we put a tick mark over it)
First, we write down all the numbers from 2 to 15.

Iteration 1: Select the first number, 2. The multiples of 2 less than or equal to 15 are 4, 6, 8,
10, 12 and 14. We strike them out to indicate that they are not primes and mark 2 as a
prime by keeping a tick mark over it.

Iteration 2: Now, we select the next number, 3. We again strike out the multiples of 3 less
than or equal to 15 which are - 6, 9, 12, 15. Note that 6 and 12 have already been crossed
out. If you want, you can strike them out again. It wouldn't make any difference to the final
result but there is no need of doing so. However, when we implement the program in Java,
you will see that we do strike out these numbers a second time ( by setting a flag to false
which is already false) which is simpler than first checking if it is already struck out ( the flag
already set to false ). We also put a tick mark over 3 to indicate that it is a prime number.

467

Iteration 3: The number 5 is selected. The multiples of 5 are 10 and 15 which are already
struck out. 5 is marked as a prime.

Iteration 4: 7 is selected. Here too, its only multiple 14 is already struck out. 7 is marked as
a prime number.

Iteration 5: 11 is selected. It has no multiples up to 15. 11 is marked as a prime number.

Iteration 6: 13 is selected. As was the case with 11, 13 too doesn't have any multiples in
the list we are considering. We just mark 13 as a prime.

There are no more numbers left. So, the process stops. We have obtained 2, 3, 5, 7, 11 and
13 as the primes up to 15.

Implementation in Java
Following is the Java program for Sieve of Eratosthenes.
import java.util.Scanner;
public class SieveOfEratosthenes {
public void primes(int n) {
boolean[] primes = new boolean[n + 1];
for (int i = 2; i < primes.length; i++) {
primes[i] = true;
}

468

int num = 2;
while (true) {
for (int i = 2;; i++) {
int multiple = num * i;
if (multiple > n) {
break;
} else {
primes[multiple] = false;
}
}
boolean nextNumFound = false;
for (int i = num + 1; i < n + 1; i++) {
if (primes[i]) {
num = i;
nextNumFound = true;
break;
}
}
if (!nextNumFound) {
break;
}
}
for (int i = 0; i < primes.length; i++) {
if (primes[i]) {
System.out.println(i);
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a number: ");
int n = scanner.nextInt();
SieveOfEratosthenes sieve = new SieveOfEratosthenes();
sieve.primes(n);
}
}
The method sieve() accepts a parameter n up to which primes are to be calculated. We
create a boolean array names primes of size (n+1) and set all the values (except 0 and 1) to
true i.e. initially, we consider all numbers from 0 to n as primes (indicated by the boolean
value true) As the execution proceeds, some of these true false will be changed to false to
indicate that they are not primes. primes[i] tells us whether the number i is a prime or not.

469

We have a variable num to hold the current number we are considering i.e. the number
whose multiples we are finding out. num is initially set to 2.
The while loop has two parts. In the first part, we find all the multiples of num up to n and
set primes[multiple] to false. The multiples are found by multiply the number num with 2, 3,
4... in the for loop. If the multiple obtained is less than n, then it is present in the list we are
considering and so we set primes[multiple] to false. If not, then it means that, we have
crossed the limit n and so, we break out of the loop.
In the second part, we find the number which we will be considering in the next iteration of
the while loop i.e. we find a new value for num. To do so, we use a for loop with its loop
counter ranging from num+1 to n (inclusive) and check if primes[i] is true. If so, i is the next
value for num. At the end of the loop if no value is found for num (indicated with a value of
false for the variable nextNumFound), then it means that we have finished checking all the
numbers and so, we break out of the for loop.
Finally, we print the primes.
Here is a sample run of the program.
Enter a number: 13
2
3
5
7
11
13

String Concatenation using Java


In general, Java does not allow operators to be applied to String objects. The one exception to this rule is
the + operator, which concatenates two strings, producing a String object as the result. This allows you to
chain together a series of + operations. For example, the following fragment concatenates three strings:
String age = "9";
String s = "He is " + age + " years old.";
System.out.println(s);
This displays the string "He is 9 years old."
One practical use of string concatenation is found when you are creating very long strings. Instead of
letting long strings wrap around within your source code, you can break them into smaller pieces,
using the + to concatenate them.

Here is an example:
// Using concatenation to prevent long lines.

470

class ConCat {
public static void main(String args[]) {
String longStr = "This could have been " +
"a very long line that would have " +
"wrapped around. But string concatenation " +
"prevents this.";
System.out.println(longStr);
}
}
String Concatenation with other Data Types
You can concatenate strings with other types of data. For example, consider this slightly different
version of the earlier example:
int age = 9;
String s = "He is " + age + " years old.";
System.out.println(s);
In this case, age is an int rather than another String, but the output produced is the same as before.
This is because the int value in age is automatically converted into its string representation within
aString object. This string is then concatenated as before. The compiler will convert an operand to
its string equivalent whenever the other operand
of the + is an instance of String. Be careful when you mix other types of operations with string
concatenation expressions, however. You might get surprising results. Consider the following:
String s = "four: " + 2 + 2;
System.out.println(s);
This fragment displays
four: 22
rather than the
four: 4
that you probably expected. Here's why. Operator precedence causes the concatenation of "four"
with the string equivalent of 2 to take place first. This result is then concatenated with the string
equivalent of 2 a second time. To complete the integer addition first, you must use parentheses, like
this:
String s = "four: " + (2 + 2);
Now s contains the string "four: 4".

String Array in Java

This tutorial demonstrates using string array in Java. Here, you will see how to declare a string
array and the syntax for using in the program.
Following code of the program declares a string array and stores some strings of first names like
"Lee", "Freddy", "Dorris", "Mary", and "Anne" to it. And in the main method these string are displayed
one by one by retrieving from the specified string array namedfirstnames. In this program all the
string values are stored in thefirstnamesstring array at the declaration time.

471
Sample Code:
class StringCharacter
{
static String[] firstnames={"Lee", "Freddy", "Dorris", "Mary","Anne"};
public static void main(String args[]){
for(int i=0;i<5;i++){
System.out.println(firstnames[i]);
}
}
}
Output of program:

C:\>javac StringCharacter.java
C:\>java StringCharacter
Lee
Freddy
Dorris
Mary
Anne
C:\>

Palindrome String in Java


Checking if a String is a Palindrome is a common assignment given to Java students. This sample class
is a helpful class that checks for various scenarios to find out if the given string is a palindrome.
public class Palindrome {
private String pal;

public Palindrome(String initPal) {


pal = initPal.toUpperCase();
}

public boolean isPalindrome() {

if (pal.length() <= 1) {
// String has only one character so it
// is a Palindrome by definition.

472

return true;

// BASE CASE.

// Get the first and last characters of the String.


char first = pal.charAt(0);
char last = pal.charAt(pal.length()-1);

if (Character.isLetter(first) &&
Character.isLetter(last)) {
// The first and last characters are both letters..

if (first != last) {
// The first and last letters are different
// so the string is not a Palindrome.
return false;

// BASE CASE.

}
else {
// The first and last characters are both letters,
// and they are both the same. So, the string is
// a palindrome if the substring created by dropping
// the first and last characters is a palindrome.
Palindrome sub = new Palindrome(
pal.substring(1,pal.length()-1));

473

return sub.isPalindrome();

// RECURSIVE CASE.

}
}
else if (!Character.isLetter(first)) {
// The first character in the string is not a letter.
// So the string is a palindrome if the substring created
// by dropping the first character is a palindrome.
Palindrome sub = new Palindrome(pal.substring(1));
return sub.isPalindrome();

// RECURSIVE CASE.

}
else {
// The last character in the string is not a letter.
// So the string is a palindrome if the substring created
// by dropping the last character is a palindrome.
Palindrome sub = new Palindrome(
pal.substring(0,pal.length()-1));
return sub.isPalindrome();

// RECURSIVE CASE.

}
}

public static void main(String[] args) {


Palindrome p1 = new Palindrome("Madam, I'm Adam.");

474

System.out.println(p1.isPalindrome());
Palindrome p2 = new Palindrome("Nope!");
System.out.println(p2.isPalindrome());
Palindrome p3 = new Palindrome("dad");
System.out.println(p3.isPalindrome());
Palindrome p4 = new Palindrome("Go hang a salami, I'm a lasagna
hog.");
System.out.println(p4.isPalindrome());
}
}

concat(), replace(), and trim() Strings in Java


concat()
You can concatenate two strings using concat(), shown here:
String concat(String str)
This method creates a new object that contains the invoking string with the contents of str appended
to the end. concat( ) performs the same function as +. For example,
String s1 = "one";
String s2 = s1.concat("two");
puts the string "onetwo" into s2. It generates the same result as the following sequence:
String s1 = "one";
String s2 = s1 + "two";
replace()
The replace( ) method replaces all occurrences of one character in the invoking string with another
character. It has the following general form:
String replace(char original, char replacement)
Here, original specifies the character to be replaced by the character specified by replacement. The
resulting string is returned. For example,
String s = "Hello".replace('l', 'w');
puts the string "Hewwo" into s.
trim()
The trim( ) method returns a copy of the invoking string from which any leading and trailing
whitespace has been removed. It has this general form:
String trim( )
Here is an example:
String s = " Hello World ".trim();
This puts the string "Hello World" into s.

475
The trim( ) method is quite useful when you process user commands. For example, the following
program prompts the user for the name of a state and then displays that state's capital. It uses trim(
)to remove any leading or trailing whitespace that may have inadvertently been entered by the user.
// Using trim() to process commands.
import java.io.*;
class UseTrim {
public static void main(String args[])
throws IOException
{
// create a BufferedReader using System.in
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println("Enter 'stop' to quit.");
System.out.println("Enter State: ");
do {
str = br.readLine();
str = str.trim(); // remove whitespace
if(str.equals("Illinois"))
System.out.println("Capital is Springfield.");
else if(str.equals("Missouri"))
System.out.println("Capital is Jefferson City.");
else if(str.equals("California"))
System.out.println("Capital is Sacramento.");
else if(str.equals("Washington"))
System.out.println("Capital is Olympia.");
// ...
} while(!str.equals("stop"));
}
}

String Class Constructors in Java


The String class supports several constructors. To create an empty String, you call the default
constructor. For example,
String s = new String();
will create an instance of String with no characters in it. Frequently, you will want to create strings
that have initial values. The String class provides a variety of constructors to handle this. To create
aString initialized by an array of characters, use the constructor shown here:
String(char chars[ ])
Here is an example:

476
char chars[] = { 'a', 'b', 'c' };
String s = new String(chars);
This constructor initializes s with the string "abc".
You can specify a subrange of a character array as an initializer using the following constructor:
String(char chars[ ], int startIndex, int numChars)
Here, startIndex specifies the index at which the subrange begins, and numChars specifies the
number of characters to use. Here is an example:
char chars[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
String s = new String(chars, 2, 3);
This initializes s with the characters cde.
You can construct a String object that contains the same character sequence as
another String object using this constructor:
String(String strObj)
Here, strObj is a String object. Consider this example:
// Construct one String from another.
class MakeString {
public static void main(String args[]) {
char c[] = {'J', 'a', 'v', 'a'};
String s1 = new String(c);
String s2 = new String(s1);
System.out.println(s1);
System.out.println(s2);
}
}
The output from this program is as follows:
Java
Java
As you can see, s1 and s2 contain the same string.
Even though Java's char type uses 16 bits to represent the Unicode character set, the typical format
for strings on the Internet uses arrays of 8-bit bytes constructed from the ASCII character set.
Because 8-bit ASCII strings are common, the String class provides constructors that initialize a
string when given a byte array. Their forms are shown here:
String(byte asciiChars[ ])
String(byte asciiChars[ ], int startIndex, int numChars)
Here, asciiChars specifies the array of bytes. The second form allows you to specify a subrange. In
each of these constructors, the byte-to-character conversion is done by using the default character
encoding of the platform. The following program illustrates these constructors:
// Construct string from subset of char array.
class SubStringCons {
public static void main(String args[]) {
byte ascii[] = {65, 66, 67, 68, 69, 70 };
String s1 = new String(ascii);
System.out.println(s1);
String s2 = new String(ascii, 2, 3);
System.out.println(s2);
}
}
This program generates the following output:
ABCDEF
CDE
Extended versions of the byte-to-string constructors are also defined in which you can specify the
character encoding that determines how bytes are converted to characters. However, most of the
time, you will want to use the default encoding provided by the platform.

477

Note: The contents of the array are copied whenever you create
a Stringobject from an array. If you modify the contents of the array
after you have created the string, theString will be unchanged.

String Conversion and toString() in Java


When Java converts data into its string representation during concatenation, it does so by calling
one of the overloaded versions of the string conversion method valueOf( ) defined
by String. valueOf( ) is overloaded for all the simple types and for type Object. For the simple
types, valueOf( ) returns a string that contains the human-readable equivalent of the value with
which it is called. For objects,valueOf( ) calls the toString( ) method on the object. We will look
more closely at valueOf( ) later in this chapter. Here, let's examine the toString( ) method, because
it is the means by which you can determine the string representation for objects of classes that you
create.
Every class implements toString( ) because it is defined by Object. However, the default
implementation of toString( ) is seldom sufficient. For most important classes that you create, you
will want to override toString( ) and provide your own string representations. Fortunately, this is
easy to do. The toString( ) method has this general form:
String toString( )
To implement toString( ), simply return a String object that contains the human-readable string that
appropriately describes an object of your class.
By overriding toString( ) for classes that you create, you allow the resulting strings to be fully
integrated into Java's programming environment. For example, they can be used in print(
) and println( ) statements and in concatenation expressions. The following program demonstrates
this by overridingtoString( ) for the Box class:
// Override toString() for Box class.
class Box {
double width;
double height;
double depth;
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
public String toString() {
return "Dimensions are " + width + " by " +
depth + " by " + height + ".";
}
}
class toStringDemo {

478

public static void main(String args[]) {


Box b = new Box(10, 12, 14);
String s = "Box b: " + b; // concatenate Box object
System.out.println(b); // convert Box to string
System.out.println(s);
}
}
The output of this program is shown here:
Dimensions are 10 by 14 by 12.
Box b: Dimensions are 10 by 14 by 12.
As you can see, Box's toString( ) method is automatically invoked when a Box object is used in a
concatenation expression or in a call to println( ).

Count number of vowels, consonants and digits in a


String in Java
This java program accepts a string from the console and counts number of vowels, consonants,
digits, tabs and blank spaces in a string.
import java.io.*;
class q5vowels
{
public static void main(String args[]) throws IOException
{
String str;
int vowels = 0, digits = 0, blanks = 0;
char ch;

BufferedReader br = new BufferedReader(new


InputStreamReader(System.in));

System.out.print("Enter a String : ");

479

str = br.readLine();

for(int i = 0; i < str.length(); i ++)


{
ch = str.charAt(i);

if(ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E'


|| ch == 'i' ||
ch == 'I' || ch == 'o' || ch == 'O' || ch == 'u' ||
ch == 'U')
vowels ++;
else if(Character.isDigit(ch))
digits ++;
else if(Character.isWhitespace(ch))
blanks ++;
}

System.out.println("Vowels : " + vowels);


System.out.println("Digits : " + digits);
System.out.println("Blanks : " + blanks);
}
}
Output:

480

Enter a String : ABC DE 123


Vowels : 2
Digits : 3
Blanks : 2

indexOf( ) and lastIndexOf( ) in Java


The String class provides two methods that allow you to search a string for a specified character or
substring: indexOf( ) Searches for the first occurrence of a character or
substring.
lastIndexOf( ) Searches for the last occurrence of a character or
substring.
These two methods are overloaded in several different ways. In all cases, the methods return the
index at which the character or substring was found, or 1 on failure.
To search for the first occurrence of a character, use int indexOf(int ch)
To search for the last occurrence of a character, use int lastIndexOf(int ch)
Here, ch is the character being sought. To search for the first or last occurrence of a substring, use
int indexOf(String str)
int lastIndexOf(String str)
Here, str specifies the substring.
You can specify a starting point for the search using these forms:
int indexOf(int ch, int startIndex)
int lastIndexOf(int ch, int startIndex)
int indexOf(String str, int startIndex)
int lastIndexOf(String str, int startIndex)
Here, startIndex specifies the index at which point the search begins. For indexOf( ), the search
runs from startIndex to the end of the string. For lastIndexOf( ), the search runs from startIndex to
zero.
The following example shows how to use the various index methods to search inside of Strings:
// Demonstrate indexOf() and lastIndexOf().
class indexOfDemo {
public static void main(String args[]) { String s = "Now is the time for all
good men " +
"to come to the aid of their country.";
System.out.println(s);
System.out.println("indexOf(t) = " +
s.indexOf('t'));
System.out.println("lastIndexOf(t) = " +
s.lastIndexOf('t'));
System.out.println("indexOf(the) = " +
s.indexOf("the"));
System.out.println("lastIndexOf(the) = " +
s.lastIndexOf("the"));
System.out.println("indexOf(t, 10) = " +
s.indexOf('t', 10));
System.out.println("lastIndexOf(t, 60) = " +
s.lastIndexOf('t', 60));
System.out.println("indexOf(the, 10) = " +
s.indexOf("the", 10));
System.out.println("lastIndexOf(the, 60) = " +
s.lastIndexOf("the", 60));

481
}
}
Here is the output of this program:
Now is the time for all good men to come to the aid of their country.
indexOf(t) = 7
lastIndexOf(t) = 65
indexOf(the) = 7
lastIndexOf(the) = 55
indexOf(t, 10) = 11
lastIndexOf(t, 60) = 55
indexOf(the, 10) = 44
lastIndexOf(the, 60) = 55

How to use equals( ) and equalsIgnoreCase( ) in Java


To compare two strings for equality, use equals( ). It has this general form:
boolean equals(Object str)
Here, str is the String object being compared with the invoking String object. It returns true if the
strings contain the same characters in the same order, and false otherwise.
The comparison is case-sensitive. To perform a comparison that ignores case differences,
callequalsIgnoreCase( ). When it compares two strings, it considers A-Z to be the same as a-z. It
has this general form:
boolean equalsIgnoreCase(String str)
Here, str is the String object being compared with the invoking String object. It, too, returns true if
the strings contain the same characters in the same order, and false otherwise. Here is an example
that demonstrates equals( ) and equalsIgnoreCase( ):

// Demonstrate equals() and equalsIgnoreCase().


class equalsDemo {
public static void main(String args[]) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good-bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " +
s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " +
s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " +
s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " +
s1.equalsIgnoreCase(s4));
}
}
The output from the program is shown here:
Hello equals Hello -> true
Hello equals Good-bye -> false

482
Hello equals HELLO -> false
Hello equalsIgnoreCase HELLO -> true

Converting Numbers to and from Strings using Java


One of the most common programming chores is converting the string representation of a number into its
internal, binary format. Fortunately, Java provides an easy way to accomplish this.
The Byte, Short,Integer, and Long classes provide the parseByte( ), parseShort( ), parseInt( ),
and parseLong( )methods, respectively. These methods return the byte, short, int, or long equivalent of
the numeric string with which they are called. (Similar methods also exist for
the Float and Double classes.)
The following program demonstrates parseInt( ). It sums a list of integers entered by the user. It
reads the integers using readLine( ) and uses parseInt( ) to convert these strings into
their int equivalents.

/* This program sums a list of numbers entered


by the user. It converts the string representation
of each number into an int using parseInt().
*/
import java.io.*;
class ParseDemo {
public static void main(String args[])
throws IOException
{
// create a BufferedReader using System.in
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
String str;
int i;
int sum=0;
System.out.println("Enter numbers, 0 to quit.");
do {
str = br.readLine();
try {
i = Integer.parseInt(str);
} catch(NumberFormatException e) {
System.out.println("Invalid format");
i = 0;
}
sum += i;

483

System.out.println("Current sum is: " + sum);


} while(i != 0);
}
}
To convert a whole number into a decimal string, use the versions of toString( ) defined in
the Byte, Short,Integer, or Long classes. The Integer and Long classes also provide the
methods toBinaryString( ),toHexString( ), and toOctalString( ), which convert a value into a binary,
hexadecimal, or octal string, respectively.
The following program demonstrates binary, hexadecimal, and octal conversion:

/* Convert an integer into binary, hexadecimal,


and octal.
*/
class StringConversions {
public static void main(String args[]) {
int num = 19648;
System.out.println(num + " in binary: " +
Integer.toBinaryString(num));
System.out.println(num + " in octal: " +
Integer.toOctalString(num));
System.out.println(num + " in hexadecimal: " +
Integer.toHexString(num));
}
}
The output of this program is shown here:
19648 in binary: 100110011000000
19648 in octal: 46300
19648 in hexadecimal: 4cc0

Using toLowerCase( ) and toUpperCase( ) in Java


The method toLowerCase( ) converts all the characters in a string from uppercase to lowercase.
ThetoUpperCase( ) method converts all the characters in a string from lowercase to uppercase.
Nonalphabetical characters, such as digits, are unaffected. Here are the general forms of these methods:
String toLowerCase( )
String toUpperCase( )
Both methods return a String object that contains the uppercase or lowercase equivalent of the
invoking String.

Here is an example that uses toLowerCase(


) and toUpperCase( ):
// Demonstrate toUpperCase() and toLowerCase().

484

class ChangeCase {
public static void main(String args[])
{
String s = "This is a test.";
System.out.println("Original: " + s);
String upper = s.toUpperCase();
String lower = s.toLowerCase();
System.out.println("Uppercase: " + upper);
System.out.println("Lowercase: " + lower);
}
}
The output produced by the program is shown here:
Original: This is a test.
Uppercase: THIS IS A TEST.
Lowercase: this is a test.

valueOf() in Java
The valueOf( ) method converts data from its internal format into a human-readable form. It is a static
method that is overloaded within String for all of Java's built-in types, so that each type can be converted
properly into a string. valueOf( ) is also overloaded for type Object, so an object of any class type you
create can also be used as an argument. (Recall that Object is a superclass for all classes.) Here are a
few of its forms:
static String valueOf(double num)
static String valueOf(long num)
static String valueOf(Object ob)
static String valueOf(char chars[ ])
As we discussed earlier, valueOf( ) is called when a string representation of some other type of data
is neededfor example, during concatenation operations. You can call this method directly with any
data type and get a reasonable String representation. All of the simple types are converted to their
commonString representation. Any object that you pass to valueOf( ) will return the result of a call
to the object's toString( ) method. In fact, you could just call toString( ) directly and get the same
result.
For most arrays, valueOf( ) returns a rather cryptic string, which indicates that it is an array of some
type. For arrays of char, however, a String object is created that contains the characters in
the chararray. There is a special version of valueOf( ) that allows you to specify a subset of
a char array. It has this general form:
static String valueOf(char chars[ ], int startIndex, int numChars)
Here, chars is the array that holds the characters, startIndex is the index into the array of characters
at which the desired substring begins, and numChars specifies the length of the substring.

Calculate gross salary in Java

This Java program defines a class Employee to accept emp_id, emp _name, basic_salary from the
user and display the gross_salary.

485

import java.lang.*;
import java.io.*;
class Employee
{
int emp_id;
String emp_name;
float basic_salary;
Employee(int id, String name, float sal)
{
emp_id=id;
emp_name=name;
basic_salary=sal;
}
void display()
{
float da=basic_salary*15/100;
float hra=basic_salary*10/100;
float gross_sal=basic_salary+da+hra;
System.out.println ("Employee Id= "+emp_id);
System.out.println ("Emplyee Name= "+emp_name);
System.out.println ("Gross Salary= "+gross_sal);
}

486

}
class q4Employee
{
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
System.out.println ("Enter Employee id");
int id = Integer.parseInt(br.readLine());
System.out.println ("Enter Employee Name");
String name = br.readLine();
System.out.println ("Enter Basic Salary");
Float sal = Float.parseFloat(br.readLine());
Employee e = new Employee(id, name, sal);
e.display();
}
}

Calculate average sale of the week in Java


This java program accepts value of apple sales for each day of the week (using array of type float)
and then, calculates the average sale of the week.
import java.lang.*;
import java.io.*;
class q7Apple

487

{
public static void main(String args[]) throws IOException
{
double avg;
float sum=0;
float sales[]=new float[7];
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
for(int i=1;i<=7;i++)
{
System.out.println ("Enter sales for day"+i+" of week
=");
sales[i-1] = Float.parseFloat(br.readLine());
sum=sum+sales[i-1];
}
System.out.println ("Sum = "+sum);
avg=sum/7;
System.out.println ("Average sale of week="+avg);
}
}

Multiple Inheritance sample in Java


This Java program implements the following Multiple Inheritance:

488

Class Student
Name, roll_no
Mark 1, Mark2

Interface: Exam
Percent_cal( )

Class: Result
Display( )
import java.lang.*;
import java.io.*;
interface Exam
{
void percent_cal();
}
class Student
{
String name;
int roll_no,mark1,mark2;
Student(String n, int r, int m1, int m2)
{
name=n;
roll_no=r;

489

mark1=m1;
mark2=m2;
}
void display()
{
System.out.println ("Name of Student: "+name);
System.out.println ("Roll No. of Student: "+roll_no);
System.out.println ("Marks of Subject 1: "+mark1);
System.out.println ("Marks of Subject 2: "+mark2);
}
}
class Result extends Student implements Exam
{
Result(String n, int r, int m1, int m2)
{
super(n,r,m1,m2);
}
public void percent_cal()
{
int total=(mark1+mark2);
float percent=total*100/200;
System.out.println ("Percentage: "+percent+"%");

490

}
void display()
{
super.display();
}
}
class q10Multiple
{
public static void main(String args[])
{
Result R = new Result("Ra.one",12,93,84);
R.display();
R.percent_cal();
}
}

arraycopy example in Java


TheSystemclass has anarraycopymethod that you can use to efficiently copy data from one array into
another:
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
The twoObjectarguments specify the array to copy from and the array to copy to. The
threeintarguments specify the starting position in the source array, the starting position in the destination
array, and the number of array elements to copy.
The following program,ArrayCopyDemo, declares an array ofcharelements, spelling the word
"decaffeinated". It usesarraycopyto copy a subsequence of array components into a second array:

491

class ArrayCopyDemo {
public static void main(String[] args) {
char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];

System.arraycopy(copyFrom, 2, copyTo, 0, 7);


System.out.println(new String(copyTo));
}
}
The output from this program is:
caffein

How to use ArrayList in Java


The ArrayList class extends AbstractList and implements the List interface. ArrayList supports
dynamic arrays that can grow as needed. In Java, standard arrays are of a fixed length. After arrays
are created, they cannot grow or shrink, which means that you must know in advance how many
elements an array will hold. But, sometimes, you may not know until run time precisely how large of
an array you need. To handle this situation, the collections framework defines ArrayList. In
essence, anArrayList is a variable-length array of object references. That is, an ArrayList can
dynamically increase or decrease in size. Array lists are created with an initial size. When this size is
exceeded, the collection is automatically enlarged. When objects are removed, the array may be
shrunk.
ArrayList has the constructors shown here:
ArrayList( )
ArrayList(Collection c)
ArrayList(int capacity)
The first constructor builds an empty array list. The second constructor builds an array list that is
initialized with the elements of the collection c. The third constructor builds an array list that has the
specified initial capacity. The capacity is the size of the underlying array that is used to store the
elements. The capacity grows automatically as elements are added to an array list.
The following program shows a simple use of ArrayList. An array list is created, and then objects of
type String are added to it. (Recall that a quoted string is translated into a String object.) The list is
then displayed. Some of the elements are removed and the list is displayed again.
// Demonstrate ArrayList.
import java.util.*;
class ArrayListDemo {
public static void main(String args[]) {
// create an array list
ArrayList al = new ArrayList();
System.out.println("Initial size of al: " +

492

al.size());
// add elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("Size of al after additions: " +
al.size());
// display the array list
System.out.println("Contents of al: " + al);
// Remove elements from the array list
al.remove("F");
al.remove(2);
System.out.println("Size of al after deletions: " +
al.size());
System.out.println("Contents of al: " + al);
}
}
The output from this program is shown here:
Initial size of al: 0
Size of al after additions: 7
Contents of al: [C, A2, A, E, B, D, F]
Size of al after deletions: 5
Contents of al: [C, A2, E, B, D]
Notice that a1 starts out empty and grows as elements are added to it. When elements are removed,
its size is reduced.
Although the capacity of an ArrayList object increases automatically as objects are stored in it, you
can increase the capacity of an ArrayList object manually by calling ensureCapacity( ). You might
want to do this if you know in advance that you will be storing many more items in the collection that
it can currently hold. By increasing its capacity once, at the start, you can prevent several
reallocations later. Because reallocations are costly in terms of time, preventing unnecessary ones
improves performance. The signature for ensureCapacity( ) is shown here:
void ensureCapacity(int cap)
Here, cap is the new capacity. Conversely, if you want to reduce the size of the array that underlies
anArrayList object so that it is precisely as large as the number of items that it is currently holding,
call
trimToSize( ), shown here:
void trimToSize( )
Obtaining an Array from an ArrayList

493
When working with ArrayList, you will sometimes want to obtain an actual array that contains the
contents of the list. As explained earlier, you can do this by calling toArray( ). Several reasons exist
why you might want to convert a collection into an array such as:
To obtain faster processing times for certain operations.
To pass an array to a method that is not overloaded to accept a collection.
To integrate your newer, collection-based code with legacy code that does not understand
collections.
Whatever the reason, converting an ArrayList to an array is a trivial matter, as the following
program shows:
// get array
Object ia[] = al.toArray();
int sum = 0;
// sum the array
for(int i=0; i<ia.length; i++)
sum += ((Integer) ia[i]).intValue();
System.out.println("Sum is: " + sum);
}
}
The output from the program is shown here:
Contents of al: [1, 2, 3, 4]
Sum is: 10
The program begins by creating a collection of integers. As explained, you cannot store primitive
types in a collection, so objects of type Integer are created and stored. Next, toArray( ) is called and
it obtains an array of Objects. The contents of this array are cast to Integer, and then the values are
summed.

S-ar putea să vă placă și