0% found this document useful (0 votes)
4 views391 pages

Object Oriented Programming With Java Compress

The document is a comprehensive guide on Object Oriented Programming (OOP) using Java, authored by Neha Kaul and published by Arcler Press. It covers fundamental concepts of OOP, the Java language, its history, and various programming constructs, including classes, inheritance, polymorphism, and encapsulation. The book aims to teach the basics of Java and OOP through clear explanations and practical programming examples, making it suitable for learners and practitioners alike.

Uploaded by

olgun.kucuk
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views391 pages

Object Oriented Programming With Java Compress

The document is a comprehensive guide on Object Oriented Programming (OOP) using Java, authored by Neha Kaul and published by Arcler Press. It covers fundamental concepts of OOP, the Java language, its history, and various programming constructs, including classes, inheritance, polymorphism, and encapsulation. The book aims to teach the basics of Java and OOP through clear explanations and practical programming examples, making it suitable for learners and practitioners alike.

Uploaded by

olgun.kucuk
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Object Oriented Programming

with Java
Object Oriented Programming with
Java

Neha Kaul

ARCLER
P r e s s

[Link]
Object Oriented Programming with Java
Neha Kaul

Arcler Press
2010 Winston Park Drive,
2nd Floor
Oakville, ON L6H 5R7
Canada
[Link]
Tel: 001-289-291-7705
001-905-616-2116
Fax: 001-289-291-7601
Email: orders@[Link]

© 2018 Arcler Press

ISBN: 978-1-77361-208-9 (Hardcover)

This book contains information obtained from highly regarded resources. Reprinted material
sources are indicated and copyright remains with the original owners. Copyright for images and
other graphics remains with the original owners as indicated. A Wide variety of references are
listed. Reasonable efforts have been made to publish reliable data. Authors or Editors or Publish-
ers are not responsible for the accuracy of the information in the published chapters or conse-
quences of their use. The publisher assumes no responsibility for any damage or grievance to the
persons or property arising out of the use of any materials, instructions, methods or thoughts in
the book. The authors or editors and the publisher have attempted to trace the copyright holders
of all material reproduced in this publication and apologize to copyright holders if permission has
not been obtained. If any copyright holder has not been acknowledged, please write to us so we
may rectify.

Notice: Registered trademark of products or corporate names are used only for explanation and
identification without intent of infringement.

Arcler Press publishes wide variety of books and eBooks. For more information about
Arcler Press and its products, visit our website at [Link]
ABOUT THE AUTHOR

NEHA KAUL
Neha Kaul is an experienced Java consultant currently residing in Paris, France. She
is working at BNP Paribas, one of the leading banks in France. She received her
double Master’s Degree in Computer and Communication Networks and Information
Technology from Telecom SudParis and University Paris-Saclay in 2016. She is a
recipient of the prestigious Telecom Scholarship for Excellence provided by Fondation
Telecom, France. She received the Bachelor of Engineering degree in Computer
Engineering from the University of Pune, India in 2011. From 2011 to 2014, she was
employed as a Senior Software Engineer with Geometric Ltd, Pune, India. Her major
interests include Advanced Java frameworks, Logging Frameworks, Network Security
and Data Mining.
TABLE OF CONTENTS

Preface..........................................................................................................xi

Chapter 1 Object Oriented Programming.................................................................. 1


• Object Oriented Concepts ............................................................... 2

Chapter 2 Introduction to the Java Language ............................................................ 7


• History of Java .................................................................................. 7
• Java Version History.......................................................................... 8
• Features of Java ................................................................................ 8

Chapter 3 Getting Started with Java ........................................................................ 13


• Components of the Java Platform.................................................... 13
• Setting Up Your Local Environment ................................................ 15
• Basic Java Syntax............................................................................ 30

Chapter 4 Classes and Objects................................................................................. 35


• Java Objects ................................................................................... 35
• Java Classes .................................................................................... 36
• Methods ......................................................................................... 37
• Variables Types............................................................................... 37
• Packages ........................................................................................ 42
• Access Modifiers in Java ................................................................. 48
• Non-Access/Other Modifiers ......................................................... 55
• Constructors in Java........................................................................ 58
• This Keyword ................................................................................ 63
• Super Keyword ............................................................................... 69
• Java Memory Management ............................................................ 69
Chapter 5 Extending Java classes ............................................................................. 71
• Inheritance ..................................................................................... 71

Chapter 6 Statements, Arrays and Operators......................................................... 101


• Control Flow Statements in Java ................................................... 101
• Arrays in Java ............................................................................... 114
• Operators in Java .......................................................................... 120

Chapter 7 Miscellaneous Classes ........................................................................... 131


• String Class in Java ....................................................................... 131
• The Object Class .......................................................................... 137
• Date Class in Java......................................................................... 147

Chapter 8 Exceptions in Java ................................................................................. 157


• Handling Exceptions .................................................................... 160

Chapter 9 Input Output ......................................................................................... 169


• Byte Streams ................................................................................ 170
• Character Streams ........................................................................ 172
• Buffered Streams .......................................................................... 174
• Java Standard I/O Streams ............................................................ 175
• I/O Hierarchy .............................................................................. 177

Chapter 10 New I/O (NIO) ..................................................................................... 195


• Channels and Buffers ................................................................... 195
• Nio Path and Files Class ............................................................... 205
• Nio Scatter and Gather................................................................. 217
• Selectors ...................................................................................... 218
• Non-Blocking I/O......................................................................... 219

Chapter 11 Advanced Java Concepts ....................................................................... 221


• Nested Classes ............................................................................. 221
• Wrapper Classes in Java ............................................................... 228
• Immutable Classes and Objects.................................................... 230
• Serialization and Deserialization In Java....................................... 232

Chapter 12 The Collections Framework................................................................... 237


• List Interface and its Implementations........................................... 238

viii
• Queue Interface and its Implementations ..................................... 243
• Set Interface and its Implementations ........................................... 246
• Map Interface and its Implementations ......................................... 248
• Iterator ......................................................................................... 251
• Legacy Collection Classes ............................................................ 255
• Collections Class ......................................................................... 257
• Comparable Interface ................................................................... 259
• Comparator Interface ................................................................... 261

Chapter 13 Generics in Java .................................................................................... 267


• Defining Generic Types ................................................................ 267
• Bounded Type Parameters ............................................................ 272
• Wildcards .................................................................................... 274

Chapter 14 Regular expressions ............................................................................... 281


• Examples of Regular Expressions in Java ....................................... 283
• Character Classes in Pattern Class ................................................ 286
• Java Regex Quantifiers ................................................................. 288
• Predefined Character Classes ....................................................... 290
• Regex Boundary Matchers ........................................................... 292
• Groups in Regex .......................................................................... 297

Chapter 15 Graphical User Interface (GUI) ............................................................ 305


• Components of AWT .................................................................... 306
• Layout Manager ........................................................................... 308
• Examples...................................................................................... 310
• Event Handling in AWT ................................................................ 314
• Java Swing API ............................................................................. 318

Chapter 16 Multithreading ...................................................................................... 325


• Threads ........................................................................................ 325
• Thread Life Cycle ......................................................................... 326
• Thread Creation ........................................................................... 327
• The Thread Class .......................................................................... 329
• Examples...................................................................................... 330
• Synchronisation ........................................................................... 336

ix
• Deadlock ..................................................................................... 343
• Thread Pools ................................................................................ 346
• Concurent Collections.................................................................. 350

Chapter 17 Garbage collection in Java .................................................................... 353


• Working of the Garbage Collector ................................................ 354
• The Concept of Generations ........................................................ 355

Chapter 18 Reflection in Java .................................................................................. 361


• Reflection API .............................................................................. 361
• Examples of Reflection ................................................................. 362

References ............................................................................................ 371

Index ..................................................................................................... 375

x
PREFACE

Java is a language that is very well suited to object oriented programming and design.
Java applications are stand-alone applications similar to the application we develop
using other object oriented languages such as C++, .Net etc. This book describes the
Java language as its purpose is to teach the basics of object-oriented programming. In
this book, we introduce the java language as its design is clean and easy to follow. The
creators of this language took a fresh, minimalistic perspective and approach towards
the design of this language. They included only useful, indispensible features and
eliminated features that do not add value or are redundant. This innovative approach
taken by them makes Java an easier language to learn and master and provides an edge
over alternative programming languages. This language is an ideal, useful instrument
to teach the fundamentals of object oriented programming and hence has been chosen
for this book.
This book covers the fundamentals of Java and object oriented programming and shows
how well they work together. Several programming samples; tested against the latest
Java version 8.0 have been provided.
CHAPTER

1
OBJECT ORIENTED PROGRAMMING

Before we dive into the study of the Java programming language let us
take a look at object oriented programming in brief.

What is Object oriented Programming?


Object Oriented Programming is a programming archetype or a model
firmly based on the concept of ‘objects’. Objects are units that contain data
in many forms. Object-oriented programming (OOP) refers to a type of
computer programming (software design) in which programmers define
not only the data type of a data structure, but also the types of operations
(functions) that can be applied to the data structure ([Link],
2017).
Data may be possessed by the object in a wide variety of forms such
as fields; also known as attributes, and code, in the form of procedures,
often known as methods (Development, 2017).
As a part of object oriented programming, computer applications are
designed in way that enables interaction among objects that are based on
a hierarchy of classes and objects that are well defined.
2 Object Oriented Programming with Java

To explain ‘objects’ in simpler terms, they are similar to people. As


explained by Steve Jobs objects are like people. Below is an excerpt from
an interview given by Steve Jobs (Rolling Stone, 2017)
“Objects are like people. They’re living, breathing things that have
knowledge inside them about how to do things and have memory inside
them so they can remember things. And rather than interacting with
them at a very low level, you interact with them at a very high level of
abstraction, like we’re doing right here.
You have no idea how I did that. You have no knowledge of the laundry
place. Maybe you speak French, and you can’t even hail a taxi. You can’t
pay for one, you don’t have dollars in your pocket. Yet I knew how to do
all of that. And you didn’t have to know any of it. All that complexity was
hidden inside of me, and we were able to interact at a very high level of
abstraction. That’s what objects are. They encapsulate complexity, and
the interfaces to that complexity are high level.”
An object is the main unit of object oriented Programming. An object
in software can be any real world object that we see daily like cars, people,
books, a lamp and so on. Some real world objects are shown in Figure 1.

Figure 1: Real world objects.

OBJECT ORIENTED CONCEPTS


Before diving into the Java programming language and writing some
code, we need to be familiar with certain object oriented concepts that
have been described below.
Object Oriented Programming 3
1. Objects: Formally an object represents an instance of a class
(Horstmann and Cornell, 2002).
For example, consider a simple table lamp; it has two possible states:
on and off. It has two behaviors: you can either turn it on or turn it off.
This is similar for all real world objects which can be described in terms
of behavior and state. These observations all translate into software
objects in the world of object-oriented programming.
Each object is made up/constitutes different states (attributes/fields),
and shared behaviors, called methods. The states of a real world object
are stored in the fields of an object and the behaviors are stored and
described via methods.
2. Classes: A class is a blueprint or a template for how an object is
built. It describes the state and behavior of the object (Wu, 2006).
Building on the previous example of a table lamp, consider the
following class lamp:
public class Lamp {
String on;
String off;

void turnOff() {
}

void turnOff() {
}

}
The above class represents the object lamp in a simple way having
two states and two behaviors.
3. Inheritance: This is a very important concept of OOP. The
acquisition of all the properties and behaviors of its parent
object by a child object is known as inheritance. By means of
inheritance, behaviors can be passed down to objects and the
code can be reused. It enables you to create new classes that
4 Object Oriented Programming with Java

reuse, extend, and modify the behavior that is defined in other


classes. The class whose members are inherited by another
class is called as the base class, and the class that inherits those
members from the base class is called as the derived class (Wu,
2006).
4. Polymorphism: Polymorphism is known as the ability of an
object to behave/react to a stimulus in different ways. It is the
ability of an object to take on many behaviors. It defined as
the ability of different objects to have the same interface, but
different implementation of this interface.
For example consider the interface – speak.
Different real world objects can use the interface speak in different
ways. For example, a cat meows, a dog barks and a duck says quack.

Figure 2: Real-world polymorphism (Javatpoint, 2017).


5. Abstraction: It is the mechanism of providing just the
functionality to the user and hiding internal details of the
implementation from the end user.
As explained by Steve Jobs using the laundry object example (Rolling
Stone, 2017), the user just uses the functionality of cleaning, but he in
unaware of the low level details or the actions performed by the laundry
object to clean the clothes. The actual implementation of the laundry
Object Oriented Programming 5
functionality is hidden from the user. The user is provided only with
‘what’ the object does, not ‘how’ the object does it.
6. Encapsulation: It is process of wrapping together the data
(variables) and code that acts on the data (methods) in a single
unit.
It means putting together all the variables and methods into a single
unit called Class. It also means concealing data and methods within an
Object. It is a way to provide security to the data and methods from
changes. This process is also referred to as a “black box,” or a tool that
can be used without knowledge of the internal implementations and
mechanisms. In this way, an end user can access and use the data and
methods present inside the black box, but cannot change them.
CHAPTER

2
INTRODUCTION TO THE
JAVA LANGUAGE

HISTORY OF JAVA
Java is an object oriented programming language and a computing
platform that was first released by Sun Microsystems in 1995 (Gosling
and McGilton, 1995). The development of this language was started in
1991 by James Gosling from Sun Microsystems. James Gosling along
with Mike Sheridan, and Patrick Naughton commenced this project in
June 1991. At that time, James Gosling and his team (a.k.a. The Green
Team) began designing and developing the first version of this language
which was mainly targeted at programming digital home appliances such
as televisions, set-top boxes, etc that were controlled by a wide range of
computer processors. This language needed to be available for use for by
several computer processors.
But in 1994, James Gosling came to the realization that this language
would be perfect for use with Internet and web browsers which led to
the worldwide release of the Java language. In the following year of
1995, Netscape Incorporated released its newest version of the Netscape
browser which had the functionality of running Java programs within the
browser.
8 Object Oriented Programming with Java

The naming history of this language is quite riveting. Its first name
‘Greentalk’ was given by James Gosling. This version provided files with
the extension ‘.gt’. Later, it was named as Oak by the Green Team as
‘Oak’ represented a symbol of strength. But, unluckily this name was
already a trademark for Oak Technologies. The legendary story goes as
follows: The team discussed for endless hours to find a new name. They
were looking for a name that reflected the very essence of the language.
Certain words that were suggested were “revolutionary”, “jolt”, “Silk”,
“DNA”, “dynamic” etc. They wanted something that was fun to say, cool,
unique, and easy to spell. During these discussions, one of the engineers
while drinking a cup of Peet’s Java suggested ‘Java’ as a name and it was
added to the list. Among the top 3 names suggested, Java was the most
unique and hence it was chosen.

JAVA VERSION HISTORY


There are many java versions that have been released. The current stable
release of Java is Java SE 8 (Gosling and McGilton, 1995).
• JDK Alpha: 1995
• JDK 1.0: 23rd Jan, 1996
• JDK 1.1: 19th Feb, 1997
• J2SE 1.2: 8th Dec, 1998
• J2SE 1.3 8th May, 2000
• J2SE 1.4 6th Feb, 2002
• J2SE 5.0: 30th Sep, 2004
• Java SE 6:11th Dec, 2006
• Java SE 7: 28th July, 2011
• Java SE 8 18th March, 2014

FEATURES OF JAVA
Features are a set of facilities and functionalities provided by the language
that help the end users develop good applications using the programming
language. Some of the features provided by Java are as follows:
Introduction to the Java Language 9

Figure 3: Features of Java (Javatpoint, 2017).

1) Simple
Java is described as a simple programming language as it has a simple
user friendly syntax and hence it is quite easy to learn. Certain complex
C++ concepts such as pointers and operator overloading have been
eliminated in Java. Further, Java consists of an excellent memory
management mechanism called the garbage collector that automatically
collects unreferenced objects and frees up memory.

2) Object Oriented
In java, objects are building blocks of all its applications. As discussed
in Chapter 1, Java supports all object oriented concepts and hence it is an
object oriented language (Gosling and McGilton, 1995).

3) Robust
Robustness, in simple words means sturdy or strong. Java is a sturdy
programming language because of its capabilities of handling exceptions
10 Object Oriented Programming with Java

– run-time and compile time, use of an automatic garbage collector,


elimination of pointers and run-time error handling.

4) Platform Independent/Architecturally Neutral/Portable


This is one of the most useful features of Java. Unlike traditional
programming languages like C or ++, java code can be compiled once
and run on any machines. Java follows the WORA concept, which means
write-once, run-anywhere (Curtin, 1998).
A simple java file with extension .java, once compiled is converted
into bytecode. This bytecode can be run on any machine be it Linux,
Windows or Solaris operating system making it platform independent.
Additionally, the bytecode format also provides security.
The compilation process of Java is shown below:

Figure 4: Compilation of a java class.


As the compiler generates bytecodes, which have nothing to do with
specific or particular computer architectures, java is an architecturally
neutral language.
Moreover, Java Byte code can be carried to any platform. No
implementation dependent features. Everything related to storage is
predefined, example: size of primitive data types

5) Secure
Java is a language that was designed keeping in mind that security is
a major concern. Hence, security mechanisms and features were put
Introduction to the Java Language 11
in place during the development of this system which enables users to
develop tamper free and virus free applications.
Some of the security features of Java are as follows:
• No pointers: As pointers have been removed from Java, it is
impossible to gain access to memory locations without proper
authorization. Additionally the memory allocation model
is completely controlled by the run time platform and is not
accessible to the programmer and hence malicious users cannot
manipulate the memory.
• Static type-checking at compile time.
• Runtime checking with the security manager.
The above features, along with additional functionalities provided
by Java help you create applications that are string and not susceptible
to attacks.

6) Multi-Threading
Java supports the feature of multi-threading which means that using Java
a program can be logically divided in parts and each part can be executed
simultaneously (Gosling and McGilton, 1995). In this way, a program
can complete several tasks simultaneously which reduces the execution
time and enables better memory utilization.

7) High Performance
Java programs, once compiled are converted to an intermediate format
known as bytecode format rather than to machine level code and this
code is executed by the JVM. This unique architecture (WORA) of Java
means that programs written in Java are faster than programs written
in compiled languages such as C or C++ (Curtin, 1998). Java, being
an interpreted language, makes use of an interpreter and a just in time
compiler Just in time (JIT) compiler that rapidly converts Java bytecodes
to native machine code.

8) Distributed
Java supports the development of distributed applications which means
that multiple client server applications can be developed using Java
12 Object Oriented Programming with Java

and run on different computer networks. A sizable library of classes are


provided by this language that enable communication in a distributed
environment using network (TCP/IP) protocols such as FTP/HTTP/
HTTPS. These features simplify the creation of distributed network
applications as compared to languages such as C or C++. In this way,
using Java, people separated via geographical boundaries can work
together with ease.

9) Dynamic
Java supports a dynamic behaviour as on execution the end user can load
the files required for execution either locally or remotely from a machine
located far away just by connecting to the internet.

10) Interpreted
In contrast to most programming languages which are either compiled
or interpreted, java is both. A java source file is compiled to a bytecode
form by the compiler and the interpreter executes this bytecode directly
on the system implementing the Java virtual machine. The combined
steps of compilation and interpretation enable code checking and provide
added security.
CHAPTER

3
GETTING STARTED WITH JAVA

Before we start writing java classes, the development environment needs


to be setup. The system configuration recommended is as follows:
• A system that supports Java SE 8 and consists of a minimum
of 2 Gigabits of memory.
The various systems that support java are: Windows®, Linux®, Mac
OS and Solaris®.
• Available disk space of not less than 250 Mb which is
required to install and store all the java environment software
components.

COMPONENTS OF THE JAVA PLATFORM


The Java platform is made up of the JDK, JRE, JVM along with certain
other components as shown in figure 5.
14 Object Oriented Programming with Java

Figure 5: JDK.

1. The Java Runtime Environment


The Java Runtime Environment (JRE) includes the Java Virtual Machine
(JVM), property settings, code libraries and components that are necessary
for running java programs and is available for multiple platforms (Eckel,
2003). The JRE is a component of JDK.

2. The Java Virtual Machine (JVM)


The JVM, as its name suggests, is a virtual or abstract machine that
supplies the runtime environment for executing java bytecode. At
runtime it reads and interprets the .class file (the bytecode) and executes
the instructions of the java program on the underlying hardware platform.
This interpretation of the bytecode by the JVM is similar to that of the
CPU of a computer. Hence, a JVM, JRE and JDK are platform dependent.
The JVM forms the very center of the WORA principle of Java. JVMs
are freely available for several software and hardware platforms (Curtin,
1998).
The main responsibilities of the JVM are as follows:
• It loads the java bytecode
• It verifies the bytecode
Getting Started with Java 15
• It understands the instructions given by the program and
executes them
• It provides a runtime environment for execution of the bytecode

3. The Java Development Kit (JDK)


This is the featured software development kit for Java. It is a development
environment that helps programmers build components, applets and
applications using Java. This kit tools useful for developing and testing
programs written in the Java and running on the Java platform (Gong and
Ellison, 2003).
The latest stable version of the Java Software environment is 8 and
can be downloaded from the following link:
[Link]
[Link]
The JDK provides you with a compiler along with a complete set of
inbuilt utilities that help in software application development.

4. The Java compiler


The compiler forms a part of the JDK. The java source code is a file with an
extension of .java. The java compiler checks the java source code against
the language’s syntax and converts the file into a .class file that contains
bytecodes. These codes are a simple set of commands/instructions that
are further translated/understood/interpreted and then executed by the
JVM as explained above. Bytecode is a set of instructions targeted to run
on a Java virtual machine (JVM).

SETTING UP YOUR LOCAL ENVIRONMENT


In this book, the environment used is: Windows 10 Enterprise Edition
and Java 8.
The steps to install Java jdk 8 on windows environment are as follows:
1. Installation process of the JDK.
• Go the Java SE downloads page and download the latest
JDK.
• Follow the instructions and run the exe file to install the
JDK on your machine.
16 Object Oriented Programming with Java

2. Once the installation of JDK is done, the environment variable


‘PATH’ needs to be updated with location of the Java binaries.
3. On a windows machine, if you have installed JDK at the
following location: G:\java\ jdk1.8.0_131, go to Control
Panel-> System and Security -> Advanced System Settings
and click on Environment Variables.

Figure 6: Environment Variables.


Now go to the list of variables and select the variable path. Append
the path of the java binaries to the existing path by clicking on edit as
follows:

Figure 7: Setting the path variable.


Getting Started with Java 17
1. Install the Eclipse IDE from the Eclipse Downloads page. This
serves as an advanced multifunctional editor that helps you
write, compile and debug Java programs (Shavor et al., 2003).
a. Chose the platform that you are working on (Windows/
Linux/Mac, etc) along with the correct processor type
(32 bit or 64 bit)
b. Follow the default instructions and complete the
installation of eclipse on your machine, maintaining the
default settings while installation.
2. Setup Eclipse
a. To setup eclipse, launch the [Link] file from the
directory where eclipse was installed.
b. The setup will ask you to provide a workspace. Select the
default workspace or add a workspace of your choosing.
c. The eclipse welcome page is displayed.

Figure 8: Eclipse Welcome page.


• Go to Windows-> Preferences -> Java -> Installed JREs as
shown below:
18 Object Oriented Programming with Java

Figure 9: Adding JDK to your eclipse workspace.


• Add the newly installed JDK by clicking on the ‘Add’ button.
• Select the option Standard VM and click on Next.

Figure 10: Adding JDK to your eclipse workspace (1).


Getting Started with Java 19
• Specify the home directory of the installed JDK. In our case
it is C:\Program Files\Java\ jdk1.8.0_131 on our Windows
system.

Figure 11: Adding JDK to your eclipse workspace (2).


• Click on finish.
• Verify that the JDK that you installed has been selected and
click on OK.
20 Object Oriented Programming with Java

Figure 12: Adding JDK to your eclipse workspace (3).


• The setup is done!

Running your first Java Program in Eclipse


• In eclipse go to File->New -> Java Project as shown in Figure
13 below:
Getting Started with Java 21

Figure 13: Creating a new Java project.


• Provide the name ‘Trial’ for the project and use same workspace
location that you entered while starting eclipse
• Verify that the version of JDK that you’re using is correct and
click on Finish.
22 Object Oriented Programming with Java

Figure 14: Creating a new Java project (1).


• Now that you have successfully created a project, we now
proceed to create our very first java class.
• To create a class, right-click on the name of your project ‘Trial’
and go to new-> Class.
Getting Started with Java 23

Figure 15: Adding a class to your Java project.


• The following dialog Box will appear.
24 Object Oriented Programming with Java

Figure 16: Adding a class to your Java project (1).


• Provide the class name as FirstJavaProgram, select the option
‘provide static void main (String args[]) from the ‘Which
method stubs would you like to create?’ section and click on
Finish.
• The following screen is displayed.
Getting Started with Java 25

Figure 17: Adding a class to your Java project (2).


• Add the following code to print a simple output on the console.
[Link](“Hi! This is my first Java Program!”);
• Save the file. Right-click on the file and go to Run as -> Java
Application. The following output is displayed on the console.

Figure 18: Running your Java program.


26 Object Oriented Programming with Java

Here is high level breakdown of the above example:


• The name of the program/application and the class name must
be identical. In our example, ‘FirstJavaProgram’ is the class
name and hence the file name is stored as ‘FirstJavaProgram.
java’ by default by eclipse.
• Java is a language that is case sensitive; hence the identifiers
First and first are considered to be different.
• The class FirstJavaProgram has been declared as public which
means it can be accessed publicly. This identifier has been
discussed further in chapter 4.
• The ‘class’ identifier is the reserved keyword in Java that is
used to create a class.
• For running stand-alone java programs the ‘main’ method is
compulsory and it needs to be declared using the identifier
‘public’. These identifiers will be discussed in detail in Chapter
4.
• ‘Main’ method takes an array of strings as an argument.
• To display the desired output on the console, the string is
passed as an input to ‘[Link]’ method which prints
the given string on the console.

Running your first Java Program using the Command


Prompt
Section 3.2.1 describes the process of creation and execution of a java
program with the use of the Eclipse IDE. An IDE is used as it simplifies
the development process. However, we can execute a java program with
the use of a simple text editor for writing and the command line for
executing as well.
This section describes this process.
• Open a simple text editor such as notepad and write down your
code.
Getting Started with Java 27

Figure 19: Write a Java program using notepad text editor.


• Save the file as a ‘Java’ file with the extension ‘.java’ in the
desired location on your machine. Since the name of our
program is FirstJavaProgram, save the file as FirstJavaProgram.
java. Make sure the file type is either set to ‘All Files (*) or
‘Java’.

Figure 20: Save a java source file.


• Open the command prompt using the cmd command in the
main menu as shown below.
28 Object Oriented Programming with Java

Figure 21: Launch the command prompt.

The following window showing the prompt is displayed.

Figure 22: Command prompt .


Getting Started with Java 29
• Traverse to the directory where you stored the file
‘[Link]’.
• Run the command - javac [Link]
• If there are no compilation errors, nothing is displayed. This
step compiles and creates a .class file in the same folder as the
source file.

Figure 23: Running your java program from the command prompt.
• Then to run your program, run the command - java
FirstJavaProgram. This command launches your application
and prints the output as follows:

Figure 24: Running your java program from the command prompt (1).
30 Object Oriented Programming with Java

BASIC JAVA SYNTAX


• Identifiers - Identifiers, in most programming languages
including java are names that we give to classes, variables,
packages, methods and interfaces. They must be made up of
letters, numbers, the dollar sign or the connecting punctuations
such as underscore(_). They can begin with a letter (a-z A-Z),
the dollar sign or the underscore.
The following restrictions apply to an identifier:
a. It cannot begin with a digit
b. It cannot contain spaces
c. Should not be a reserve word
• Variables – These are nothing but named memory locations. Fol-
lowing the conventions of Java identifiers certain legal examples
of variable names are as follows:
a. myVar
b. MYVAR
c. MyVar
d. MyVar1
e. $MyVar
f. _MyVar
g. i
h. j
Some examples of illegal variable names are as follows:
• 9My_Var: //begins with a digit

• My Var // Contains a space


• my+var // The plus sign is not an alphanumeric character
• variables1-2 // The hyphen is not an alphanumeric character
Getting Started with Java 31
• O’Donald // Apostrophe is not an alphanumeric character
• My&Var // ampersand is not an alphanumeric character
• Case Sensitivity − Java is case sensitive, which means the iden-
tifier Hello and hello would have different meanings in this lan-
guage.
• Class Names – In case of class names the first letter of the class
name should be in Upper Case. In case the class name is made up
of several words, each word’s first letter should be made capital.
Example: class FirstJavaProgram
• Method Names – The naming convention in case of method
name is that the method names should start with a lower case
letter. In case a method name is formed from many words, all the
words except the first word should have their first letter capital-
ized.
Example: public void myFirstJavaMethod()
• Program File Name – In java, the name of the class file, when
saved should be the same as the class name. This should take into
consideration the case sensitivity of java. Hello and hello do not
mean the same thing.
When we save the file, it should be saved using the class name and
append a ‘.java’ at the end to specify the file type. In case of mismatch
of the file name and the class name, the java program will not compile.
• Data Types - They stand for the different types of values that can
be stored in a variable.
The primitive types of variables in java are the following:
Table 1: Primitive Data types (Wu, 2006)

Data Type Default Value Default Size


char ‘\u0000’ 2 bytes
byte 0 1 byte
Int 0 4 bytes
32 Object Oriented Programming with Java

float 0.0f 4 bytes


long 0L 8 bytes
double 0.0d 8 bytes
boolean false 1 bit

public static void main (PSVM) Meaning


As explained in section 3.2, the main method is the first method called
when a java program begins.
To execute your program, the JVM needs to locate your program.
But, JVM does not belong to the same package as any declared java class.
Hence, the main method needs to be declared as public. This specifier
permits accessibility across all packages.
The static keyword is used as it permits main( ) to be called without
the need to create a particular instance of the class. This is needed as the
JVM is not capable of creating class objects; hence a way to access the
main method is provided by the static keyword. Any method declared
as static can be called outside the class without the need for creating an
object using the syntax [Link]().
In a similar way, the JVM can call the main method as
<ClassName>.<main>
The keyword void simply tells the compiler that main( ) does not
return a value.
In the main( ) method, string arguments are passed. The argument
is declared as String args[ ]. This declaration means that a parameter
named args of type stringArray is passed with the main method. These
String arguments in the form of an array are necessary because the main
method is called by the JVM by passing command line arguments.

Comments in java
Java has 3 different types of comments namely: Block/Traditional, end of
line and documentation (Wu, 2006).
Block Comments are the ones that start with /* and end with */ and
can extend upto several lines long. For example:
/* This is a long comment.
Getting Started with Java 33
This comment is two lines long. */
End-of-Line Comments commence with a double forward slash (//)
and apply just to the current line. For example:
// This is an single line comment
Documentation comments are those that are processed by the Javadoc
tool that is used to generate documentation. The documentation comment
is the same as block comments apart from the fact that it starts with /**
and respects certain conventions that have been defined by the Javadoc
tool. For example:/**
* This is a Javadoc documentation comment.
*
* @author XYZ
*/

Reserved Words/ Keywords


Similar to most languages of programming, Java has a set of special
words that are recognized only by the compiler. Hence, as these words
are specific to the java compiler, we are not allowed to use them for
naming our Java elements. Below is the list of java keywords:

Table 2: Keywords in Java ([Link], 2017)

assert*** default goto* package synchroni-


zed
boolean do if private This
break double implements protected Throw
byte else import public Throws
case enum**** instanceof return transient
catch extends int short Try
char final Interface static Void
class finally Long strictfp** volatile
const* float Native super While
34 Object Oriented Programming with Java

Legend:
*
not used
**
added in 1.2
***
added in 1.4
****
added in 5.0
Additional literals that cannot be used are: true, false and null.
Although the list is quite short, we aren’t obligated to remember this
list as IDE’s such as Eclipse help us identify the reserve words by use of
syntax colouring.
Consider the following class:

Figure 25: Syntax Highlighting.


As we can see, the keywords public static class and void have been
highlighted clearly by the use of a colour.
The next chapter discusses additional fundamental concepts of Java
such as objects, classes, keywords, packages, interfaces and so on.
CHAPTER

4
CLASSES AND OBJECTS

This section covers java classes and its components such as objects,
methods, variables and so on.

JAVA OBJECTS
As discussed in chapter 3, an object has state and behavior. On observing
real or day to day life, we can clearly see many objects such as buildings,
streets, cars, houses and so on. These real life objects are similar to
software objects. These objects are made up of a state and associated
behaviors.
Example: Consider the object Person. It has several states such as
name, address, height, weight, etc. Further, it has behaviors such as
eating, breathing, walking and so on.
An object in software stores its state in fields and its behavior is
exhibited by methods. In the course of software development, methods
are the entities that work/operate on the object.
36 Object Oriented Programming with Java

JAVA CLASSES
Class – Classes are nothing but blueprints that help create individual
objects. A class describes the state and behavior of the object of its type.
Example: Class Person
public class Person {
String firstName;
String lastName;
String address;
int age;

void eating() {
}

void breathing() {
}

void sleeping() {
}

void setAge(int age) {


age= age + 1;
}
}
Classes and Objects 37
In this example, as we can see the class Person has the states:
firstName, lastName, age and address.
The behaviors are described by the following methods: eating(),
sleeping() and breathing().
An important point to note is that the a single file (.java) can hold
many classes, but only one class that is declared with the access modifier
public. Access modifiers have been discussed in section 4.6.

METHODS
As discussed in the previous section, a method describes the behaviour of
a class. A class can have several behaviours and hence several methods.
The methods contain the logic for that behaviour and manipulate data
and perform actions on the data.
In the above example of the class Person, eating(), breathing() and
sleeping() are examples of methods.
Methods can be with or without arguments. For example, the methods
eating(), breathing() and sleeping() have no arguments or parameters.
But, the method setAge has been passed the parameter age which has
been manipulated.
void setAge(int age) {
age= age + 1;
}

VARIABLES TYPES
A class can contain any of the following variable types.
1. Local variables – These variables are those that are defined
inside constructors or methods or blocks and are called
local variables. They are declared and initialized within the
method. Once the method has been executed, the variable will
be destroyed. They are visible only within the scope of the
declared method/constructor or block.
For example, consider the following method.
38 Object Oriented Programming with Java

public void calculateDiscount(int sellingPrice )


{
int finalPrice =0;
finalPrice = 0.99 * sellingPrice;
[Link](“Final Selling Price is : “ + finalPrice);
}
In the above method, the variable finalPrice has been declared an
initialized first. Then, it has been used to store a value. This value has
then been printed on the console. Once the method has been exited from,
the variable finalPrice will be destroyed.
2. Instance variables - Instance variables are variables that
are declared within a class but outside any of its method
declarations (Wu, 2006). The minute the class is instantiated;
its instance variables are initialized. These variables can
be accessed from inside any of the class’s constructors
or method or block of the concerned class.
For example consider the class Person.
public class Person {
String firstName;
String lastName;
String address;
int age;

void eating() {
[Link](“This person loves ice cream. “+ firstName)
}
Classes and Objects 39
void breathing() {
}

void sleeping() {
}

public static void main(String[] args){


Person person = new Person();
[Link] = “Mark”;
[Link](“First Name: “ + firstName);

[Link] = “Anthony”;
[Link](“Last Name:” + lastName);

The above code on execution will print the following output on the
console:

First Name: Mark


Last Name: Anthony
40 Object Oriented Programming with Java

When we use the operator ‘new’ to create an object of class Person


as shown in the example above, the instance variables are created. These
variables will be destroyed when the object will be destroyed. Each
object of the class Person will hold a copy of all the instance variables
that have been declared. So, in case of Person class, each object of this
class will hold a value of the instance variables firstName, lastName, age
and address. The values held by the instance variables may be referenced
or used by the methods, constructors or other blocks of code.
Access modifiers (as will be discussed in the next section) can be
allotted for the instance variables. These variables have default values
allotted to them.
As shown in the above code, the instance variables have been accessed
in two ways:
- Directly in a defined method as follows:
void eating() {
[Link](“This person loves ice cream. “+ firstName)
}
- By an object of the class using the dot (.) reference as seen in the
main methods follows:
Person person = new Person();
[Link] = “Mark”;
Also, if changes are made to instance variables of one object, the
instance variables held by other objects are not affected. If changes are
made to instance variables held by one object, they will not be reflected
in the instance variables held by other objects.
3. Class variables - Class variables, also known as static member
variables are variables declared at class level with the keyword
static. These variables are common to and are shared by the
entire class. Only one copy of this variable is created and
shared by all the instances of the class. Changes made to class
variables are visible to all instances of the class.
Classes and Objects 41
Their value can be manipulated by any class objects but these
variables can be manipulated without the use of an instance of a class
using the class reference.
This is demonstrated by figure 26 where the static variable has been
accessed in two ways: 1. By an instance/object of the class 2. By using
the class reference.

Figure 26: Static variables.


Additionally as per naming conventions, it is discouraged to access
static members in a non-static way as it promotes disambiguation. When
we declare a variable as static, we are saying that this variable belongs to
the class. Hence, it should be accessed via the class.
4. Class Methods – In addition to class variables java supports
class level methods as well. Class methods are also called
as static methods. A method can be declared as static using
the keyword static in the method declaration. These methods
should be invoked using the class name and not using an
instance of the class. Like static variables, these methods can
also be accessed using the class instance, but this is discouraged
as it results in ambiguity as to the type of method. If a method
42 Object Oriented Programming with Java

is accessed using the Class name, it is pretty clear that the


method is a static method and not a regular method.
A typical use of these static methods is to access and manipulate
static fields (Figure 26).
The following combinations of instance variables and class variables
are not permitted:
a. Instance methods can access and manipulate class/static methods
and variables directly
b. Instance methods can access instance variables and methods di-
rectly.
c. Class methods can be accessed by class/static variables and meth-
ods directly.
d. Instance variables and methods cannot be directly accessed by
class methods or variables. They must use an instance/object ref-
erence.

PACKAGES
A package is a grouping of similar/related types that help encapsulation
of groups of classes, interfaces, enumerations and annotation types
providing access protection and namespace management (Naughton and
Schildt, 1996).
Packages in Java can be of two types: built-in and user-defined
Built-in packages are those that have been previously defined and
provided by Java. Some examples are [Link], [Link]. Some of these
packages will be discussed in later chapters.
User defined packages are the packages created by the user/
programmer. Before discussing these packages in detail, let us see certain
merits of using packages in Java:
a. The use of packages promotes reusability which is an impor-
tant requirement in the software industry as it helps save time
and effort. With the help of packages, classes can be reused
by several java programs.
Classes and Objects 43
b. Secondly, with the help of packages, the location of classes/
files is defined which makes it easy to look for the files. This
is extremely useful in case of large-scale applications that
contain hundreds of classes.
c. Several times, in real world situations, there is a need for cre-
ating classes with the same name.
For example, consider an application that has an Age class that
maintains the age of the Person class. Similarly, the class Dog can also
have an Age class. In this case, the compiler will not let us create another
class named Age. This is called a ‘name-space collision’. The use of
packages solves this problem and allows us to have separate packages for
the Person and Dog Class; each with its own Age class.

Naming Conventions and points to remember:


1. In each type (class/interface/enumeration) only a single
package declaration can be done.
2. The statement that declares a package must be the first
statement in the class/interface/enumeration.
3. A standard for defining package names has been put into place.
Most organizations use their reversed Internet domain name to
define and identify their packages in a unique way.
For example, if the domain name is [Link] then the package
name is [Link]

Defining and using a Package using Command Line

1. Defining and Executing via Packages


A package can be easily defined with the package keyword. If you use
the notepad to edit your java code (execution using command line) as
described in Chapter 3 section 3.2.2, then add the following line at the
very beginning of your class.
package myJavaPackageName;
Use the following command to compile the java class that is in the
package.
44 Object Oriented Programming with Java

javac –d directory . [Link]


The directory parameter specifies the destination where the compiled
class files will be created. If you want to keep the destination of the
compiled class files as the same directory in which the .java file is present,
you can use the dot (.) operator.
Consider the class Person in package myPackage.
This class can be compiled as follows:

java –d . [Link]
The following command is used to run the class.

java [Link]
The Person class is run as follows:

Java [Link]

2. Accessing a Package in another Class


A package can be accessed in another package in the following ways:
a. Using import
The import statement is used to access one package in another package
Consider the following example
Package myPackage;
Class Person{
public void printMessage(){[Link](«Hello»);}
}
Now, if we want to use/import all the classes that fall under the
package myPackage in another class named Cars, we use the following
statement right after the package statement as shown below. The * after
myPackage imports all the classes present under the package myPackage.
package carPackage;
import myPackage.*;
Class Cars{
Classes and Objects 45
public static void main(String args[]){
Person person = new Person();

[Link]();
}

}
The output of the above program is Hello.
Additionally, if we want to import a single class or if we want to
explicitly note all the classes of a package, this is possible in the following
way.
package carPackage;
import [Link];
Class Cars{
public static void main(String args[]){
Person person = new Person();

[Link]();
}

}
The output of the above program is Hello.

b. Qualified Names
Further, if you don’t want to write import statements in your current
class, you can use the fully qualified package name (the package that you
wish to import) when required to access the classes from this package as
follows:
package carPackage;
Class Cars{
public static void main(String args[]){
[Link] person = new [Link]();
46 Object Oriented Programming with Java

[Link]();
}

3. Subpackages and their access in Java


A package that is created within a package is called a subpackage. An
interesting thing regarding the psubpackages in Java is that subpackages
need to be explicitly imported. If you import the parent package, its
subpackages are not imported.
Consider the following package hierarchy:

Figure 27: myPackage hierarchy.


The class Person is present in myPackage and the class Country is
present in mySubPackage. So now if the class Cars want to access the
class Country, another import statement must be added as shown below.
package carPackage;
import myPackage.*;
import mySubPackage.*;
Class Cars{
public static void main(String args[]){
Person person = new Person();
Classes and Objects 47
[Link]();
Country country = new Country();
}

}
The class country can be compiled and executed in the following
way:
Javac –d . [Link]
java [Link]

Defining and using a Package using Eclipse IDE


In eclipse, package creation is quite simple. Once you create a project,
you need to just right click on it and click on New-> Package.
The following dialog box appears:

Figure 28: Creating a new package in Eclipse.


48 Object Oriented Programming with Java

Enter the package name and click on the finish button. The package
is added to your Java project as shown below.

Figure 29: Creating a new package in Eclipse (1).


As explained in section 4.5.1, when we use eclipse we do not need to
explicitly run the javac and java commands as Eclipse does this for us.
This makes it very easy to manage and use packages in our applications.

ACCESS MODIFIERS IN JAVA


In any object oriented programming language, there is always a need
to provide different levels of access to different components of your
application. In java, certain access modifiers have been provided that
provide different levels of access to your classes, variables and methods.
Four modifiers have been provided by java; namely public private
protected and default.

a. Private
This is the most restrictive access modifier. When a class/variable/
method is declared as private, it means that it is visible only within the
Classes and Objects 49
current class. This modifier is not applicable to classes. Out of the four
modifiers, only 2 are applicable to a class: public and default access.
Consider the following example:
Class Person has a private variable named age.
We try to access this variable in another class named Cars in the same
package
We get a compile time error as shown in the figure below.
The class Person:

Figure 30: private modifier.


The class Cars:

Figure 31: private modifier (1).


The private keyword restricts direct access to the variable age. To
enable other classes to access and manipulate this variable, we provide
50 Object Oriented Programming with Java

methods called as getters and setters. Getters return the value of the
variable and setters set the value of the variable to the value specified by
the programmer.
This is demonstrated in figure 19 and 20.
Class Person with getters and setters

Figure 32: getters and setters.


Class Cars using the getters and setters to access the private variable
age.

Figure 33: getters and setters (1).


As we can see, the getters and setters permit class Cars to indirectly
access the variable age via a getter and setter. The above code produces
Classes and Objects 51
the following output:

Figure 34: getters and setters (2).

Default
This level of access is allotted to the class in case no modifier has been
explicitly specified.
A variable/class/package declared with this modifier is visible to all
the classes in the same package.
This has been demonstrated by the following example.
Consider the class Person. The variable age has been defined with
no modifier hence its access is default. As we can see, the age variable is
accessible throughout this class.

Figure 35: default modifier.


52 Object Oriented Programming with Java

Additionally, this variable can be accessed by other classes in the


same package. This is shown by the class Cars which is able to access
the variable age.

Figure 36: default modifier (1).


However, this variable is not visible to a class situated in another
package. This is demonstrated by the class Country (located in package
[Link]) that tries to create an instance of the class
Person that has been declared with no modifier. We get the compile time
error that says ‘Person’ is not visible which means that at this level, we
don’t have access to the class Person and its variables.

Figure 37: default modifier (2).


Classes and Objects 53
However if we change the access modifier of the class Person to public
as follows and retry to access the variable ‘age’ in the class Country, we
still get a compile time error. This is seen due to the fact that although the
class Person is now public, its variable ‘age’ is still not public and hence
not accessible.

Figure 38: default modifier (3).

Protected
In java, the types (variables/methods/constructors) can be declared as
protected. The protected modifier enables access in the package and its
subpackages. So, all the classes in the package as well as the subclasses
(child classes) in other packages have access to a field declared as
protected.
Consider the following example:
The class Person with a protected variable
54 Object Oriented Programming with Java

Figure 39: protected modifier.


The class Country then accesses this variable through inheritance via
its instance.

Figure 40: protected modifier (1).


As we can, the variable age is accessed using an instance of the class
Country. We cannot access the variable age of Person directly in class
Country. This is because although the class Person has been declared
as a public class, the variable age is protected and hence it is accessible
only at the same package level and subclass-package level. The access
at subclass level is achieved via Inheritance which will be discussed in
Chapter 5.
d. Public
This access modifier means that the item declared as public can be
accessed everywhere throughout your application. This modifier provides
the widest scope among all the modifiers.
Classes and Objects 55
The following table shows the access to members permitted by each
modifier.

Table 3: Access Modifiers and their scope ([Link], 2017)

Access Modifier/scope Class Package SubClass Global/outside package


level
Public Yes Yes Yes Yes
Protected Yes Yes Yes No
Default/no access modifier Yes Yes No No
Private Yes No No No

The above table describes the access provided by each modifier and
their visibility in a particular scope. As we see, at class level or within
a class, all types (methods/variables/classes) are visible as shown in
column 1, which means that a class always has access to its members.
The 2nd column shows the visibility at package level. All modifiers
except for the private modifier provide access at the package level. The
3rd column depicts the access at sub class level. As we can see, members
declared as protected and public are the only ones that are visible at
the sub class level. The 4th column shows the visibility of the member
outside package level; at a global application level. At this level/scope,
only public members are visible.
The instance variables of a class are visible to all the members of the
class. Generally it is recommended to declare these variables private as
it promotes encapsulation.

Another important point to note is that access modifiers


cannot be used/assigned for local variables.

NON-ACCESS/OTHER MODIFIERS
In addition to access modifiers, java has some non-access modifiers
a. Final
This modifier is given to a member if you do not want its value to
change.
56 Object Oriented Programming with Java

It is applicable to the following types:


• Class
• Methods
• Local Variables
• Instance variables
• Method Arguments
Consider the following class that has a final method and instance
variable:

Figure 41: final modifier.


As seen in the above example, when we try to assign a new value to
the variable ‘a’ we get a compile time error, which shows that the value
of a variable declared as final cannot be modified. These variables can be
used as constants in Java.
Classes and Objects 57
A method that is declared as final cannot be overridden in its subclass.
But it can be reused by the subclass.

Figure 42: final modifier (1).


A class declared as final cannot be inherited and extended by any
other class.

Transient
This modifier is applicable to a variable. A variable (local or instance)
declared as transient will be skipped during the process of serialization.
Serialization is a way to persist/save the state of an object which is
discussed in Chapter 11.

Volatile
This modifier is applicable to variables. A variable marked as volatile
means that its value will be modified and accessed by several threads.
Further this indicates that its value should be accessed from the main
58 Object Oriented Programming with Java

memory and not cache. This comes in use in the context of multithreading
which has been discussed in Chapter 16.

Synchronized
This keyword is applicable to a method or a block of code within a
method. It is also applicable to static methods. This keyword is used in
the context of multithreading in Java. It means that only one thread can
access that block of code at one time. All the other threads have to wait
for the object to be available again. This is discussed in Chapter 16.

Strictfp
This keyword is used in case floating point arithmetic. It can be applied
to classes, interfaces and methods. This keyword makes sure that the
results of floating point arithmetic operations are same throughout
different operating systems.

Native
This keyword is applicable only to methods and it marks that the
method will be implemented in a language other than Java. This works
in combination with the Java provided interface called the Java Native
Interface (JNI).

CONSTRUCTORS IN JAVA
A constructor in Java is a piece/block of code that helps you create
objects. Every time the new() operator is invoked, the constructor is
called. Constructors look a lot like methods, the only difference being
that they don’t have return types and that they have the same name as the
class. A class can have 0 or more constructors.
There are classified into two types:

Default Constructor
A default constructor is the one that has no parameters. The syntax is as
follows:
Java_Class_Name(){
//optional block of code
Classes and Objects 59
}
For example, consider the following constructor of the Person class:

Figure 43: Default Constructor.


The output is as follows.

Figure 44: Default constructor (1).


Additionally, a constructor with no method body can be passed as
well. Its syntax is same the default constructor except it is empty. It is
essential to note that in the absence of a user defined constructor, the
compiler by default creates a no-argument/zero argument constructor at
compile time. This type of constructor is used to provide default values/
default state of the object. This constructor assigns the same default
value to all the objects that are created. Constructors can be assigned the
access modifiers public, protected, private, or none (default).
60 Object Oriented Programming with Java

Parameterized Constructor
This is a constructor that takes one or more arguments or parameters.
This constructor is used to provide values to the object’s properties. This
constructor can provide values other than the default values. In this way,
different values can be assigned to different objects. This is shown in
figure 45.

Figure 45: Parameterized constructor.


As we can see, two objects of type Person have been instantiated and
assigned different values.
An essential thing to note is that if we provide a parameterized
constructor only (no default constructor), then the default constructor
will not be auto-generated by the compiler.
This behavior/concept is shown by the example below:
Classes and Objects 61

Figure 46: Parameterized constructor (1).


We get a compile time error as shown in the above figure.

Constructor Overloading
Overloading a constructor means having many constructors in a class
that differ in their parameters. The parameters can differ in terms of
types, count and order.
The following example shows the class Person with 3 different
constructors and their respective outputs.
62 Object Oriented Programming with Java

Figure 47: Constructor overloading.


The output is as follows:

Figure 48: Constructor overloading (1).


Classes and Objects 63

THIS KEYWORD
‘This’ keyword refers to the current instance of the class. This reference is
used to refer the current instance if there is a possibility that the reference
is ambiguous.
For example, consider the class Person. In the constructor, the
parameters that have been provided are the same as the class variables to
provide meaning names. Hence, we use the ‘this’ variable to separate the
instance variables from the local variables.

Figure 49: this keyword.


Programmers may argue that in the above case the keyword doesn’t
need to be used and the ambiguous nature of the variables can be corrected
by giving different names to the instance variables and local variables.
This could be done as follows:
64 Object Oriented Programming with Java

Figure 50: this keyword (1).


As we can see, the local variables of the constructor have been named
differently as compared to the instance variables. In programming, a
good practice is to give meaningful names to variables (Naughton and
Schildt, 1996).
But, the names given in the example do not carry any meaning. The
names do not explain what the parameter is. One needs to dive into the
constructor and read the entire class to understand what the variables
mean. In a small code, this is easy to decode. But imagine a large scale
application with numerous classes and packages and projects. In that
case, it is extremely difficult to process all the code in a quick way.
Hence, meaningful names must be given to all members of a class.
Doing this makes the code more readable and easy to follow and
understand.
An important point to note is that the ‘this’ keyword cannot be used
by class member functions/static members as they belong to the class and
not to a particular instance of that class. There is no instance for ‘this’ to
refer to.
Classes and Objects 65
Additionally, the ‘this’ keyword can also be used in the following
manner:

calling an overloaded constructor in the current class


If a class has several constructors, one constructor can be called from
another constructor by means of the keyword ‘this’ as follows:

Figure 51: this keyword (2).


As we can see, in the constructor with 3 arguments a this statement
has been used. The statement calls the 2 argument constructor that
accepts the parameters age and firstName respectively. This helps reuse
the existing constructor.
Further, the default constructor can be called from a parameterized
constructor using ‘this’ as follows.
66 Object Oriented Programming with Java

Figure 52: this keyword (3).


As shown in the class Person above, the parameterized constructor
has been called from the default constructor by using the ‘this’ keyword.
The output generated by the program is as follows:

Figure 53: this keyword (4).


Classes and Objects 67
return current instance/object from a method
The keyword this can also be used to return an object from a method and
it is a valid return value as it represents an instance of the class. This is
shown as follows:

Figure 54: this keyword (5).


As seen in the figure above, the method getCountryInstance() returns
an instance of the country object which is then passed on to the display
method.
The output of the program is as follows:

Figure 55: this keyword (6).


68 Object Oriented Programming with Java

as an argument to a method
‘This’ can also be used to invoke another method by passing it as an
argument. This enables method chaining. This situation arises in case we
want to pass the reference of an object to several methods.
This has been explained in the following example:

Figure 56: this keyword (7).


As seen in the above figure, the method displayCountry() passes
the ‘this’ reference which in turn calls the display() method. The output
generated by the above program/code is as follows:
Classes and Objects 69

Figure 57: this keyword (8).

SUPER KEYWORD
This keyword is used to refer to the superclass/parent class of the current
class. It serves to differentiate members of superclass from the subclass
(Horstmann and Cornell, 2002). This keyword is used in the context of
Inheritance and is discussed in detail in Chapter 5.

JAVA MEMORY MANAGEMENT


The JVM in java consists of the following sections: Stack, Heap and
Data Area.
The memory is divided in the above components as follows:

Figure 58: JVM memory.


70 Object Oriented Programming with Java

The data area is used to store the class variables and global variables.
The local variables or instance variables are always stored on the stack.
The stack and heap space are dynamic with a movable boundary.
Consider the following example:
Person person;
person = new Person();

Figure 59: JVM heap and stack.


The instance variable ‘person’ is first created on stack. On execution
of the ‘new’ command, the object is created and stored on the heap. The
reference to this Person object is stored on the stack.
Whenever we create an object in Java using the ‘new’ operator or by
other means, memory is allocated to the object from Heap.
The life cycle of objects on heap is longer than that of stack. The
values on stack exist only within the scope of their creation.
When the object is no longer referenced its memory is released by the
garbage collector. This process is discussed in Chapter 17.
CHAPTER

5
EXTENDING JAVA CLASSES

INHERITANCE
As discussed in Chapter 1, inheritance is an important pillar of object
oriented programming. Using inheritance we pass properties and
behaviors from one class to another.
In Java, this is achieved via the keyword extends.
The class that inherits from another class is called as the subclass or
the derived class and the class whose properties are inherited is called as
the parent/base/super class.
The syntax is as follows:
class SuperClass{
}
class subclass extends SuperClass{
}
A very simple example of inheritance in Java can be demonstrated by
the following example:
Consider the class Vehicle:
72 Object Oriented Programming with Java

Figure 60: Inheritance Example-1.


The class TwoWheeler inherits from the class Vehicle. Hence, it now
has access to the method display of Vehicle as shown below:

Figure 61: Inheritance Example-1 (1).


The output is as follows:

Figure 62: Inheritance Example-1 (2).


Extending Java classes 73
As we can see, the statement “Hi! You are in class Vehicle” has been
printed which serves as proof that the subclass TwoWheeler has access
to the method display() of its superclass Vehicle.
Here are some key points to note about inheritance in Java:
• All the members (methods and fields) of the superclass are
inherited by the subclass, thereby giving the subclass the
possibility of reusing them.
• The single exception to rule number 1 is that the private
members of the superclass cannot be referred or used directly
in the subclass.
• Each time a subclass object is created, a copy of the superclass
contents is made within this object which gives the subclass
access to the superclass.
• Java supports multilevel inheritance, but only upto 2 levels.
This means that a class can extend upto two levels below. For
example, consider the hierarchy:
Vehicle -> TwoWheeler -> Bike
The class TwoWheeler inherits from the Vehicle and the class Bike
further inherits from the class TwoWheeler. But, in this case, the class
Bike cannot have a subclass.
• Constructors are not inherited by the subclass. Nevertheless,
they can be invoked from the subclass by means of the super
keyword.
• New members (methods and fields) can be declared in the
subclass that is not present in the superclass.
• An extension to point 4, we have the possibility of adding a
method with the same name and signature as that of a method
in the superclass inside the subclass. This phenomenon is
called overriding (Wu, 2006). This principle will be discussed
further in section 5.2.4.
• In addition to methods, variables/instance variables with the
same name as the one in the superclass can be declared in
the subclass which hides the superclass variable. This is also
known as shadowing.
74 Object Oriented Programming with Java

As mentioned in chapter 3, the super keyword is used in the context


of inheritance, being primarily used to reference the parent class from the
subclass. It can be used in the following scenarios:
1) Refer to immediate parent class’s instance variables
In case the superclass and the subclass have the same member
variable/field, super is used to get access to the superclass variable. This
is shown clearly by the example in figure 63.

Figure 63: Inheritance Example-2: Super Keyword.

Figure 64: Inheritance Example-2: Super Keyword (1).


Extending Java classes 75
As we can see, on using the super keyword, the value belonging to
the superclass has been displayed.
2) To invoke a method in the superclass
This keyword can be used to invoke/access a superclass method as
well. It must be used if the subclass has a method with the same name
as that in the superclass. This phenomenon is also called as method
overriding.
This has been demonstrated in figure 65,66 and 67.

Figure 65: Inheritance Example-3: Super Keyword.

Figure 66: Inheritance Example-3: Super Keyword (1).


76 Object Oriented Programming with Java

The output is the following:

Figure 67: Inheritance Example-3: Super Keyword (2).


In the above example, Both classes Vehicle and TwoWheeler have
the same method namely display(). If we call the display() method from
the TwoWheeler class, it will call the display() method of the class
TwoWheeler as java gives priority to the local class over the superclass.
Hence, if we want to access any method that has the same name in the
superclass from the subclass, the super keyword needs to be used.
3) To invoke the constructor of the superclass
The keyword can also be used to call the superclass constructor from
the subclass.
Let’s see a simple example;consider the class Vehicle as follows:

Figure 68: Inheritance Example-4: Super Keyword.


The class TwoWheeler inherits from class Vehicle and we instantiate
an object of this class.
Extending Java classes 77

Figure 69: Inheritance Example-4: Super Keyword (1).


As we can see, in the constructor, super() has been called, which
invokes the superclass constructor. The output is as follows:

Figure 70: Inheritance Example-4: Super Keyword (2).


The output shows that the superclass constructor has been successfully
invoked.

An important point to note is that super() has to be the


first call in the constructor.
The keyword super can further be used to call/invoke the super/parent
class’s parameterized constructor. This is shown in the following example:
78 Object Oriented Programming with Java

Figure 71: Inheritance Example-5: Super Keyword.

Figure 72: Inheritance Example-5: Super Keyword (1).


As we can, we have the superclass Vehicle with the parameterized
constructor Vehicle(int wheels, String color). As these 2 parameters are
Extending Java classes 79
common for all types of vehicles, the subclasses can reuse the parent
class constructor instead of initializing these instance variables in the
superclass FourWheeler.
Using the super keyword, the parameters have been passed to the
superclass constructor as shown in figure 72.

Upcasting and downcasting in Inheritance


In java, in context of inheritance, we are allowed to treat an object of
subclass type as an object of type superclass. This called as upcasting.
It can be done whenever there exists and IS-A relationship between 2
classes.
This is demonstrated by the following example. Consider the class
Vehicle:

Figure 73: Upcasting in Inheritance.


Now the class, FourWheeler, which IS-A Vehcile that inherits from
this class. It has been upcasted as follows:
80 Object Oriented Programming with Java

Figure 74: Upcasting in Inheritance (1).


The above example shows automatic upcasting. This upcasting can
be done manually as well as follows:
TwoWheeler twoWheeler = new TwoWheeler();
Vehicle vehical = (Vehicle)twoWheeler;
In java, if you want to upcast a subclass to a parent class, this is done
automatically without habing the need to implicitly specify the parent
class’s name. This is because upcasting can never generate errors and fail
as All TwoWheelers are Vehicles!
But downcasting is a little tricky. When we try to downcast a parent
class to a subclass we get a compile time error as follows.
Extending Java classes 81

Figure 75: Downcasting in Inheritance.


This can be fixed by simple adding a cast to the instance declaration
as follows:
82 Object Oriented Programming with Java

Figure 76: Downcasting in Inheritance (1).


Although, the above code doesn’t generate compile time errors, on
execution of this code, a runtime exception called as ClassCastException
is thrown as follows:

Figure 77: Downcasting in Inheritance (2).


This exception is thrown since all TwoWheelers are Vehicles, but all
Vehicles aren’t TwoWheelers.
Hence, downcasting should not be performed in Java.
Additional points about inheritance:
• All classes in java inherit have the Object class as their parent
class, they inherit from it by default.
• Java supports multilevel inheritance upto 2 sublevels from the
baseclass. As shown below, we can go down only upto levels
from class A:
Extending Java classes 83

Figure 78: Multilevel Inheritance.


• Java does not support multiple inheritance. Multiple inheritance
is supported by certain languages such as C++. Multiple
inheritance means that a subclass can inherit from two parent
classes. It is also called as diamond inheritance (Tempero and
Biddle, 2000). This is depicted as follows:
84 Object Oriented Programming with Java

Figure 79: Multiple Inheritance (Stack Overflow, 2013).


This type of architecture causes ambiguity.
If in the above design, class B and class C have a method print() and
class D does not override it, then in class D, how is one supposed to call
the method print() ?
The compiler is unable to resolve this ambiguity as it does not know
which parent class’s print() method has been called.
Hence, Java does not support this type of inheritance. This behavior
can be achieved with the help of interfaces which will be described in
section 5.2.3.

Abstraction
As per dictionary, abstraction is the quality of dealing with ideas rather
than events (Liskov and Guttag, 2000). For instance, when you consider
the case of e-mail, complex details such as what happens as soon as you
send an e-mail, the protocol your e-mail server uses are hidden from
the user. Therefore, to send an e-mail you just need to type the content,
mention the address of the receiver, and click send.
Extending Java classes 85
Likewise in Object-oriented programming, abstraction is a
mechanism/process of hiding the actual implementation details from the
user, providing only the functionality to the user. In other words, the user
will have the information on what the object does instead of how it does
it.
In Java, abstraction is achieved using Abstract classes and interfaces.

Abstract Classes
An abstract class is a class that is declared using the keyword abstract.
An abstract class may or may not include abstract methods. These classes
cannot be instantiated, but they can be inherited by other classes (Gosling
and McGilton, 1995). Any class that contains the keyword ‘abstract’ is
known as an abstract class.
A simple example of an abstract class declaration is as follows:
public abstract class Fruits{
}
A method is said to be abstract if it has been declared using the
keyword abstract. An abstract method cannot have a body and it should
be declared as follows:
Abstract void displayName();
Some key points about abstract classes are as follows:
• Any class that has at least 1 abstract method must be declared
as abstract.
• When a class is declared as abstract we cannot instantiate it
using the operator new() for instance.
• A class that is abstract can have methods that are abstract as
well as methods that are regular, that is not abstract. These
methods are the methods that we have been studying so far.
• In order to use an abstract class, it must be inherited by
another class. In this case, the subclass needs to provide all
implementations for the abstract methods of its superclass.
Here is a sample abstract class:
86 Object Oriented Programming with Java

Figure 80: Abstract Classes.


As we can see, the class Fruits has been declared with the keyword
abstract. Apart from this change, it is just like any other Java class.
This class can be used by way of inheritance. So we create a class
Apple that inherits from this class. This is shown in figure 81.
Extending Java classes 87

Figure 81: Abstract Classes (1).


As we can see, the class Apple now has access to the class Fruits and
its members.
The output on execution of class Apple is as follows:

Figure 82: Abstract Classes (2).


88 Object Oriented Programming with Java

If we try to instantiate the Fruits class in its subclass Apple, then we get
the following error:

Figure 83: Abstract Classes (3).

Abstract Methods
Methods that contain the keyword abstract in their declaration are
called as abstract methods. These methods are used when you want the
behaviour to be defined by the subclass and not the superclass.
Extending Java classes 89
By way of abstract methods, the subclasses that inherit from the parent
class can provide their own implementations for the abstract methods.
As shown below the syntax of an abstract method is as follows:
abstract void display();
By default, on declaring a method as abstract the class needs to be
declared as abstract. Moreover, when a class inherits from the abstract
class, it needs to provide the implementation of all the methods that have
been declared as abstract. If the subclass doesn’t provide implementations
of all the abstract methods of the superclass, then it has no choice left, but
to declare itself as an abstract class. But, in the end, a subclass/descendent
will have to implement the methods that are abstract as you will end up
with a family/hierarchy of classes that are abstract which you cannot
instantiate. This is bad design as the class can never be used.
Consider the class Fruits that we used earlier. An abstract method has
been added to it as follows:

Figure 84: Abstract Methods.


90 Object Oriented Programming with Java

As we can see, an abstract method called fruitShape() has been added


to the class. The subclass Apple now needs to provide an implementation
This is shown below.

Figure 85: Abstract Methods (1).


Interfaces
Java includes the notion of interfaces. Interfaces are defined as reference
types in Java (Gosling and McGilton, 1995).
Extending Java classes 91
It is, in simpler words, a collection of abstract methods. They are a
collection of behaviors that can be implemented by a class. It may look
and feel like a class, but it is slightly different. Principally, interfaces are
made up of abstract methods.
They are declared as follows:

Figure 86: Interfaces.


Similar to a java class, the extension of an interface is ‘.java’. Like
classes, they can be stored in packages for management of namespace.
An interface is implemented by a java class. The java class that
implements the interface is obligated to implement all the methods of
an interface. Otherwise, similar to abstract methods, the subclass of the
class implementing the interface must provide implementations for the
interface methods. Else, the class needs to be declared as an abstract as
well.
Implementing an interface is like signing an agreement; the class
has to abide by the rules and implement the behaviour described by the
interface.
Interfaces are used for providing abstraction and solving the diamond
inheritance problem as discussed in section 5.1. Using interfaces multiple
inheritance can be achieved and hence the diamond problem is solved.
The implements keyword is used to say that a class implements it.
Consider the following class the implements the above interface:
92 Object Oriented Programming with Java

Figure 87: Interfaces (1).


But, we get a compile time error as shown above. Only using the
implements keyword isn’t enough. The implementations need to be
provided as well. Once the implementation has been provided, the errors
go away.

Figure 88: Interfaces (2).


Extending Java classes 93
Key points to know about interfaces are as follows:
• They are abstract by default. Hence, the keyword abstract isn’t
needed in its declaration
• Interface methods are public by default. Hence, the keyword
public isn’t required.
• By default, an interface is abstract and doesn’t need to be
declared as abstract. So, the interface that we declared above
can also be declared as follows:

Figure 89: Interfaces (3).


As we can see, the above declaration generates no errors.
- A class has the possibility of implementing several interfaces at a
time, but a class can extend at most one class.
o The following declaration of a class is completely valid:
public class Class1 implements interface1, interface2
{
//implementations of interface methods
}
- An interface has the right to extend another interface; similar to
classes.
- The method signature defined in the interface must be respected
by the class that implements the interface.
- Like classes, interfaces can have any number of methods
94 Object Oriented Programming with Java

- Similar to abstract classes, interfaces hold abstract methods


An interface can extend another interface as follows:

Figure 90: Extending Interfaces.


As we can, the interface MySecondInterface extends from the interface
that we created above. Any class that implements MySecondInterface
will have to implement the methods declared in both, MySecondInterface
and MyFirstInterface as well.
An interface can inherit two interfaces as well. This is shown by the
example below.
Consider the interface MyThirdInterface as follows:

Figure 91: Extending Interfaces (1).


The interface MySecondInterface extends two interfaces now:
MyFirstInterface and MyThirdInterface.
This is shown in figure 92.
Extending Java classes 95

Figure 92: Extending Interfaces (2).


Any class that implements MySecondInterface now has to
implement all the methods in MyFirstInterface, MySecondInterface and
MyThirdInterface.
Suppose class X implements MySecondInterface, then I has
to implement 3 methods from MyFirstInterface, 2 methods from
MySecondInterface and 1 method from MyThirdInterface. So, in total
class X will have to implement 6 methods.
In this way, a class can support multiple inheritance by use of several
interfaces where it can implement different behaviours that can be shared
among several classes.
Interfaces should be used when there is a possibility of frequent
changes in your design; whereas abstract classes should be used when
the design of your system is more or less stable and fixed.
For example, application frameworks can use Abstract classes as they
need default services to be provided, like the Java collections framework
which will be discussed in chapter 12.
Interfaces can be used when a particular behaviour is similar across
classes. For example consider the class Person. A person walks; but so
do many other mammals. So, instead of creating a base class for every
other mammal that works such as Giraffe and so on, an interface walk is
more practical.
Despite certain similarities between abstract classes and interfaces
such as the commonality of having abstract methods and inability to
instantiate them, they are different from one another in the following
ways:
96 Object Oriented Programming with Java
Table 4: Interfaces vs Abstract classes

Interfaces Abstract Classes


Cannot have constructors Can have constructors
All the methods are abstract Can have non-abstract methods
It needs to be implemented using An abstract class needs to be inherited by another
the keyword ‘implements’ class using the keyword ‘extends’
It can extend multiple interfaces An abstract class can extend at most one class
All fields in an interface are public, An abstract class can have non public, non static
final static by default and non-final fields
Members of an interface are public Abstract classes can have methods with other
by default access modifiers such protected, private and
default(no modifier)

Tagged Interfaces
Another use of interfaces is the possibility of tagging them. A tagged
interface is nothing but an interface without any methods. This interface
is used to carry information about the object type.
The Serialization mechanism in Java is a tagged interface. The java
documentation (Serializable (Java Platform SE 8), 2015) states: “The
serialization interface has no methods or fields and serves only to identify
the semantics of being serializable.”
A tagging interface serves the following purpose:
- It helps in the creation of a common super-interface/parent. Many
interfaces can extend from a particular interface which serves as
their parent class. A tagging interface is understood and is mean-
ingful only to the JVM. For example, if a class X implements
the Serializable interface, it declares itself to be a member of the
classes that are serializable in nature, and so when the JVM sees a
class like this, it does certain operations that help in this process.
- If a class implements a tagging interface in Java, it becomes a
type; like Serializable for instance.

Compile-Time and Runtime polymorphism in Java

Compile Time Polymorphism


It is nothing but method/function overloading. A method is said to be
Extending Java classes 97
overloaded if a class consists of many methods with the same names,
but different arguments. This is called as compile time polymorphism
(Johnson and Foote, 1988).
An example of a class with overloaded methods is shown below:

Figure 93: Compile Time Polymorphism.


As shown in the above figure, the class Addition has several methods
named add; each with different method parameters. This is called
98 Object Oriented Programming with Java

compile-time or static polymorphism as a method has several forms/


behaviors at compile time. This means that the compiler understands
which method is being called at compile time and hence the apt name –
compile time polymorphism.
An important point to note is that methods with the exact same
arguments and different return types are not considered to be overloaded.
The parameters need to be different else the compiler generates an error
that says that the method has been duplicated.

Figure 94: Compile Time Polymorphism (1).

Runtime Polymorphism
Runtime polymorphism is a way in which the call to a method is resolve
dynamically. This means that the method type is determined at run-time.
This is achieved by way of inheritance and method overriding. Method
overriding is when a subclass implements a method present in its parent
class maintaining the signature of the method. This is called as overriding
the parent class implementation. The JVM determines which method it
needs to call (method from the super class/subclass) at runtime.
Extending Java classes 99
Example:
Consider the following hierarchy
Vehicle-> TwoWheeler-> Bike
Here, the Vehicle class is the super class from which the class
TwoWheeler extends and the class TwoWheeler is extended by the Bike
Class.

Figure 95: Runtime Polymorphism.


100 Object Oriented Programming with Java

As clearly seen from the above example, each of the subclasses has
overridden the method printHello(). There are 4 variables/instances/
references of type Vehicle at compile time. But they hold the reference
to the subclasses. Only the object vehicle truly refers to the Vehicle
class. All the other instances refer to the subclasses of Vehicle class. The
real ‘Type’ of the references car, bike and cycle are determined by the
compiler dynamically or at run time. Hence, this is called as runtime/
dynamic polymorphism. From the output results, you can confirm that
version of a method is invoked based on the actually object’s type as
shown below:

Figure 96: Runtime Polymorphism (1).


In Java, an object that has been declared to be of type X can refer to
an object of class X or it can hold a reference to any of its subclasses.
The compiler has the capability of resolving/invoking the right method/
function related to subclasses of class X at runtime; thereby allowing
method overriding that is available in the hierarchy of class X. The
compiler is able to choose which method of the subclass will be chosen
based on actual ‘type’ of reference of the object, not the ‘type’ of the
reference variable. This is done dynamically or at runtime, hence the apt
name runtime polymorphism.
CHAPTER

6
STATEMENTS, ARRAYS AND
OPERATORS

CONTROL FLOW STATEMENTS IN JAVA


In a java program, the code is generally executed in a sequential order.
But, there some special statements that we can add to our code to
selectively execute a block of code based on one or many conditions.
These are called as control flow statements (Wu, 1996).
These statements are classified into the following types of control
statements:
• Loop
• Decision
• Branch
We shall now proceed to see their definition and description in detail.

Loops
Loops help you to execute a particular piece of code in a repetitive
manner until a condition has been met. In java, we have 3 types of loops.
• The for loop
102 Object Oriented Programming with Java

For loops help you execute a block of code for a specific fixed number
of times.
Consider the following example:

Figure 97: For Loop.


As we can see, we execute the loop 5 times: from index 0 to index 4
The above code produces the following output:

Figure 98: For Loop (1).


If you want the counter to start from 1, the ‘for loop’ can be manipulated
as follows:
Statements, Arrays and Operators 103

Figure 99: For Loop (2).


The above code produces the following output:

Figure 100: For Loop (3).


Furthermore, there exists 2 more variations of the ‘for loop’ that shall
be discussed in Arrays and collections respectively.
• The while loop
This loop will execute a particular code/ block of code/statements
until the given condition holds true.
This is shown by the following example:
104 Object Oriented Programming with Java

Figure 101: While Loop.


The output is as follows:

Figure 102: While Loop (1).


As depicted by the output, the value of i has been incremented until it
reaches 5, after which the control exits from the while loop.
The exit condition should be chosen carefully because if the condition
is always true, we will stuck in the while loop forever. In this case the
program has to be forcefully terminated else the JVM will run out of
memory.

The do-while loop


This loop is an extension to the while loop. It is very similar to the while
loop except that it executes the block of code at least once.
This is shown from the following example:
Statements, Arrays and Operators 105

Figure 103: Do-while Loop.


The output is as follows:

Figure 104: Do-while Loop (1).

Decision Statements
Decision statements are used to make a decision to execute a particular
block of code only if a particular condition or a set of conditions evaluate
to true.
There are three types of decision statements:
1. If statements
2. If else statements
3. Nested If else statements
4. Switch statement
106 Object Oriented Programming with Java

If Statements
An if statement is basically a condition that is checked before execution
of a statement.
An example is as follows:

Figure 105: If statement.


The output is as follows:

Figure 106: If statement (1).

If else statement
This statement is an extension to the if statement that provides an
alternate course of action in case the given condition evaluates to false.
This is demonstrated by the following example:
Statements, Arrays and Operators 107

Figure 107: If-else statement.


The output is as follows:

Figure 108: If-else statement (1).


As the value of i is 5 we get the above output. If the value of i is
anything other than i we get the following statement as output.

Figure 109: If-else statement (2).

Nested If Else Statement


This statement is an addition to the if else where we can nest an if-else
statement within another if or else statement.
This is shown by the example below:
108 Object Oriented Programming with Java

Figure 110: Nested If-else statements.


As shown in the above example, there is an if else loop nested
inside an if loop. Depending on the value of the variable i the respective
statement is printed. The output of the above program is as follows:

Figure 111: Nested If-else statements (1).

Switch Statement
This type of statement provides several paths of execution for a wide
variety of values. Based on the value, selective code can be executed.
This statement can be used instead of complicated and long nested if else
statements.
The structure of a switch statement is as follows:
switch ( variable ) {
case value: code to execute;
Statements, Arrays and Operators 109
break;
case value: code to execute;
break;
default:
values_not_found_in_above_cases;
}
For instance, if we take the nested if else loop shown in figure 112, if
we need to check for each value ranging from 1 to 5, the loop becomes a
little tedious to handle and difficult to read as follows:

Figure 112: Switch statement.


This can be better done with the help of a switch statement as follows:
110 Object Oriented Programming with Java

Figure 113: Switch statement (1).


The switch statement can work with the following types of primitive
variables: int, byte, char and short. Starting from Java 8, switch statements
work with Strings as well.
Although the above example is not very complicated and can be
implemented using a nested if else loop, in real life applications, nested
if else loops make the code difficult to read and understand, which is why
switch cases are preferred.

Branch Statements
There are three branch statements in Java:

Break
This statement is used in the context of loops: for,while and do-while.
This loop basically exits from/terminated a loop. If there are many nested
loops, this statement terminates the innermost looping statement.
Statements, Arrays and Operators 111
This is shown by the class BreakExample:

Figure 114: Break statement.


As shown in the example, two loops are iterating. In the inner loop
a break statement has been added for a specific value of the variable j.
Now, whenever the value of j is 1, the control exits from the loop.
This is evident from the output shown below:

Figure 115: Break statement (1).


112 Object Oriented Programming with Java

The output clearly shows that the value of j never goes past 0 as each
time it reaches 1, the control exits from that for loop.

Continue
This statement is used in the context of a for, while or do-while loop.
Basically, it skips the current iterative cycle. If the program encounters
this keyword and goes back to beginning of the loop.
This is shown by the example below:

Figure 116: Continue statement.


In the class ContinueExample, we iterate over a for loop. If the value
of the variable i is 2, we call the continue statement that skips the current
iteration. This is shown by the output below:

Figure 117: Continue statement (1).


Statements, Arrays and Operators 113
As seen in the output, the value of the variable i is not printed when
it is 2.

Return
This statement exits from the method in which it is called or the current
method. This causes the flow of the control to return back to that point
in the program where the current method was called. This statement can
be used in two ways: first to return a value from a method and second to
return control from a method.
To return a value from a method we simply use the keyword return
followed by the value/local variable/object to be returned.
This has been shown in the figure below:

Figure 118: Return statement.


As shown by the class ReturnExample, the method getSum returns an
int value. Please take a note that the data type of the value returned should
always match the return type specified in the signature of the method.
To return the control from a method we simply use the return keyword
without a value as follows:
public void method1(){
return;
}
114 Object Oriented Programming with Java

ARRAYS IN JAVA
Arrays are objects in java that store many values of a particular type. The
number of elements held by the array is specified at the time of creation.
It is like a container that holds values of a particular type. An array has a
fixed size, given at the time of creation.
An array is made up of elements and indexes that help in easy access
to the individual elements of an array. The index starts from 0 in an array
(Gosling, McGilton, 1995).
Each individual item held by an array is called an element and is
accessed by its index. As shown below, if you want to access the 9th
element in the array, its index is 8 as the indexes start with 0.

Figure 119: Array Indexes (Gosling, 2000).


The memory location of arrays is mostly contiguous which means
that the blocks in memory have consecutive addresses.
Arrays have the capability of holding primitive types, objects and
object references as well.
In order to create an array we need to first declare it and then create it.
Upon creation, it can be initialized with the desired values. The following
example shows how to create array an array of integers:
int[] arr; or int arr[]
The latter declaration is a legal way to declare an array but it is not
the preferred way to declare an array as it has been adopted from C/C++.
The next step is to create the array. This is done as follows:
int arr = new int[10];
The above statement creates and array of 10 integers.
Another way to create and initialize the array at the same time is by
Statements, Arrays and Operators 115
directly providing the values it holds as follows:
int[] arr = {19, 2, 4, 35};
The above declaration both creates and initializes the array at the
same time.
Arrays are advantage in terms of access and optimization. A set
of data can be easily sorted and retrieved using an array. Further, any
element of an array can be directly accessed using its index. But, it has a
disadvantage in terms of size due to its fixed size as it does not permit us
to change the size dynamically. This issue has been addressed using the
collections framework that will be discussed in chapter 12.
The following example shows the declaration, creation, initialization
of an array and displays its contents.

Figure 120: Arrays.


116 Object Oriented Programming with Java

In the above example, two arrays – one array of integers and another
array of doubles have been created, initialized and displayed. The output
of the example is as follows:

Figure 121: Arrays (1).


The above example makes use of the simple for loop to display the
elements of the array. But, starting from java 5 (jdk 1.5 and above), we
can use the for each loop which is shown below:

Figure 122: Arrays (2).


Statements, Arrays and Operators 117
The output is as follows:

Figure 123: Arrays (3).


Arrays can be used as method arguments as well. This is shown in
the example below where a method that calculates the sum of all the
elements in an array takes an array as an argument and returns the sum
of all of its elements.

Figure 124: Arrays (4).


118 Object Oriented Programming with Java

The output given by the program is as follows:

Figure 125: Arrays (5).

Copying an Array
In java, we have the functionality of copying of an array that is system
defined. The System class has a method called arraycopy that enables
you to copy the content of one array into another.
The syntax of this method is as follows (Gosling, 2000):
public static void arraycopy(Object src, int srcPos, Object dest, int dest-
Pos, int length)
where srcPos and destPos are the source and destination positions re-
spectively.
The following example shows the use of arraycopy method:

Figure 126: Arrays (6).


The output of the use of arraycopy is shown below:
Statements, Arrays and Operators 119

Figure 127: Arrays (7).

Multidimensional arrays
In java, we have the possibility of having arrays of arrays (embedded/
nested) with the help of multidimensional arrays (Gosling, 2000). The
data/information is stored in the form of rows and column; similar to a
matrix or a database.
The declaration of a multidimensional array can be done in the
following ways:
- int[][] array;
- int [][] array;
- int array [][];
- int []array [];
A multidimensional array can be initialized in the following way:
int[][] array = new int[2][3];// two rows and three columns:
This array can be initialized as follows:
arr[0][0]=1;
arr[0][1]=2;
arr[1][0]=3;
arr[1][1]=4;
arr[2][0]=5;
arr[2][1]=6;
120 Object Oriented Programming with Java

The example below shows how to correctly declare, initialize and


display the values of a multidimensional array.

Figure 128: Multidimensional Arrays.


The output is as follows:

Figure 129: Multidimensional Arrays (1).

OPERATORS IN JAVA
Operators are nothing but special characters/symbols that execute
operations on one or more operands. In java, a wide variety of operators
have been provided that help in manipulation of variables.
Operators in Java are divided into the following groups:
Statements, Arrays and Operators 121
• Assignment Operators
• Arithmetic Operators
• Unary Operators
• Relational Operators
• Conditional Operators
• Bitwise Operators
We shall now see each of the operators in detail.

Assignment Operator
This is one of the most commonly used operators in any programming
language. It is visible in almost all types of code.
The assignment operator assigns the value of the operand on the right
side to the operand on the left side.
A simple example:
int x =20;
Here the value 20 is assigned to the variable x.

Arithmetic Operators
Java supports arithmetic operations such as addition, subtraction,
multiplication, division and remainder with the help of arithmetic
operators.
The subsequent example shows the use of the operators +,-,*,/ and
% for the operations addition, subtraction, multiplication, division and
remainder respectively.
122 Object Oriented Programming with Java

Figure 130: Arithmetic Operators.


The output of the above code is as follows:

Figure 131: Arithmetic Operators (1).

Unary Operators
Unary operators, as their name suggests work only on a single operand.
The work on one operand and perform operations such as incrementing a
value, decrementing a value, inverting a value and so on.
Statements, Arrays and Operators 123
There are 5 different types of unary operators in java. They are as
follows:
+ is used to describe positive values, although all values are positive
without the need to specify this symbol with it
The ‘–‘ operator is used to specify that a value is negative
The ‘++’ operator increments the value of the operand by 1
The ‘–‘operator decrements the value of the operand by 1
The ! operator is used to negate/complement the value of the operand.
In case of a Boolean value, its value is inverted from true to false or vice
versa
They following class UnaryOperators tests these operators:

Figure 132: Unary Operators.


The output produced by the program UnaryOperators is as follows:
124 Object Oriented Programming with Java

Figure 133: Unary Operators (1).

Relational Operators
These operators help determine if an operand is less than, greater than or
equal to another operand. They are as follows:
== equal to
< less than
<= less than or equal to
> greater than
>= greater than or equal to
!= not equal to
The following class RelationalOperators demonstrated the use of
these operators:

Figure 134: Relational Operators.


Statements, Arrays and Operators 125
The output produced by the class RelationalOperators is as follows:

Figure 135: Relational Operators (1).

Conditional AND and OR Operators


These two operators perform logical AND and OR operations on two
expressions of Boolean nature respectively.
The important thing to note in case of these operators is that they
show ‘short circuit’ behaviour, which means that if the first operand is
false; the second operand/expression is not evaluated.
The conditional operators have been demonstrated using the class
ConditionalOperators as follows:

Figure 136: Conditional Operators.


The output of the class is as follows:
126 Object Oriented Programming with Java

Figure 137: Conditional Operators (1).

The Bitwise Operators


In java there are operators that work on bits, performing bit by bit
operations. These are defined by Java and can be applied to the following
primitive types: int, long, char, short and byte.
There are four different bitwise operators and two bitshift opeartors
in Java.
The bitwise opeartors are: & or AND, | or OR, ^ or EXOR and ~
Negation/complement.
The bitshift operators are: left shift (<<) and right shift (>>)
The bitwise operators work on operands that are expresses in binary
such as 00000010. or 2 (it decimal).
The & opearator will perform a logical bitwise AND on two operands
The | opearator will perform a logical bitwise OR on two operands
The ^ opearator will perform a logical bitwise EXOR (exclusive OR)
on two operands
The ~ opearator (unary/operates on a single operand) will perform a
logical bitwise inversion of the operand
For example. Consider two values 00000010 and 00000110 (2 and 3
in decimal respectively).
The & would yield 00000010
The | would yield 00000110
The ^ would yield 00000010
The ~ for both would yield 11111101 and 11111001 respectively.
The left shift operator (<<) will shift a pattern to the left by the number
of digits specified and the right shift operator (>>) will shift a pattern to
the right by the number of digits specified.
Statements, Arrays and Operators 127
For the left shift operator the syntax is number << p where number
is the number in bits and p is the number of positions to shift.
For example consider the bit value 00000011 or 3.
The left shift 3 << 2 means that shift the bits of the number 3 by 2
positions to the left.
So, applying this on the binary value, we move the bits to the left as
shown below:

Figure 138: Bitwise Operators.


For the right shift operator the syntax is number >> p where number
is the number in bits and p is the number of positions to shift.
For example consider the bit value 00000011 or 3.
The right shift 3 >> 2 means that shift the bits of the number 3 by 2
positions to the right.
Using the bit value 00000011, we get the value 00000000 which is
equivalent to 0 in decimal.

Figure 139: Bitwise Operators (1).


128 Object Oriented Programming with Java

Shorthand Operators
We have the following shorthand assignment operators in java:
+=, -=,*=, /=,%=
1 += : This operator is used as follows: a+= b;
This translates into a= a+b;
This is a way to reduce code complexity in java.
3. -=: This operator is used as follows: a*=b;
This statement is equivalent to a=a*b;
4. /=: This operator is used as follows: a/=b;
This statement is equivalent to a=a/b;
5. %=: This operator is used as follows: a%=b;
This statement is equivalent to a=a-b;
The following program named ShorthandOperators describes the use
of these operators.

Figure 140: Shorthand Operators.


Statements, Arrays and Operators 129
The output produced by the program ShorthandOperators is as
follows:

Figure 141: Shorthand Operators (1).

Conditional or Ternary Operator


The conditional or ternary operator(?:) operates on 3 operands. It main
functionality consists of evaluation of Boolean expressions and its aim
is to decide the final value that must be assigned to the given variable.
The syntax of the conditional operator is as follows:
x = (expression to evaluate) ? value to assign if expression evaluates
to true : value to assign if expression evaluates to false
The following class ConditionalOperator demonstrates the use of this
operator.

Figure 142: Ternary Operator.


130 Object Oriented Programming with Java

The output produced by the class ConditionOperator is as follows:

Figure 143: Ternary Operator (1).


CHAPTER

7
MISCELLANEOUS CLASSES

STRING CLASS IN JAVA


Generally strings are nothing but a sequence of characters. But in java they
are objects that represent these characters. All the string manipulations
are done via the String class in java. Any string declared in java is an
instance of this class.
Similar to arrays a string can be declared in 2 ways:
• new operator
String str = new String(“String 1 “);
• string literal
String str = “String 1”;
A simple example of string declaration is as follows.
132 Object Oriented Programming with Java

Figure 144: String Declarations.


The output of the class StringExample is as follows:

Figure 145: String Declarations (1).


An important note about the String class is that it is immutable.
Immutability means that once the objects are created, the objects cannot
be changed (Gosling, 2000). Immutability has been discussed in chapter
11.
Another important concept in terms of Strings is the String pool. This
is nothing but a pool of strings that is maintained that helps reusability of
strings that have been created so far. By use of this pool, Strings created
using literals can be reused. If a string literal has been used repeatedly in
the java code, only a single copy of it is created, which save space.
For example if a string is created as follows:
String string1 = “String1”;
The value ‘String1’ is added to the pool. Now, if we create another
string string2 as follows, then a new object isn’t created. The object
string2 points to the value ‘String1’ in the string pool. This is depicted in
figure 146:
Miscellaneous Classes 133

Figure 146: String Pool.


The pool cannot be used when a string is created using the new
operator because this forces a brand new String instance to be allocated.

String Operations in Java


The String class in Java provides us with a range of methods that help us
manipulate strings. We are now going to discuss a few of these methods
(Gosling, 2000).
a. Concatenate: The concatenate method is used to concatenate two
Strings. Its syntax is [Link](string2);
b. Length: The length method returns the length of a string. Syntac-
tically is written as [Link]();
c. Replace, replaceFirst and ReplaceAll: These methods are used to
replace certain parts of the string
d. toLowerCase and toUpperCase: These methods are used to con-
vert an uppercase string to lowercase and vice versa.
e. IndexOf: This method returns the index of the character.
134 Object Oriented Programming with Java

f. CompareTo and compareToIgnoreCase: This method compares


the values of 2 strings and returns 0 is they are equal, a value less
than zero if the string is smaller and a value greater than 0 if the
string is larger in size.
The use of the above methods has been demonstrated in the following
class StringExample:

Figure 147: String Operations.


Miscellaneous Classes 135
The output generated by the class StringExample is as follows:

Figure 148: String Operations (1).


The String class provides many other methods that facilitate string
manipulations. They can be accessed at javadocs (Java Platform SE 8,
2015).

StringBuffer CLASS
This class is used when we need to create strings that need to be modified
a lot of times. This class is exactly like the String class except that it not
immutable. The string object can be changed as often as required. An
advantage of this class is that it is synchronized or thread-safe.
A simple example using the method reverse() of this class to determine
if a String is a palindrome is shown below:

Figure 149: StringBuffer class.


136 Object Oriented Programming with Java

The output generated by the above class is as follows:

Figure 150: StringBuffer class (1).

StringBuilder CLASS
This class was introduced in Java 5 (jdk 1.5). This class is also used when
we need to create and manipulate mutable string Strings. It is exactly
similar to the StringBuffer class except for the fact that it is not thread-
safe.
A simple example of the use of these classes is shown below using
the StringExample class:

Figure 151: StringBuffer class (2).


The results generated by the above program are:
Miscellaneous Classes 137

Figure 152: StringBuffer class (3).

THE OBJECT CLASS


The Object class is the superclass of all the classes in Java. Every
java class is descendant (directly or indirectly) of this class. This class
provides some useful methods that are inherited by every class. As a
programmer, you are not obligated to use these methods, but if you do
wish to incorporate them in your programs, you have to override them as
per your specifications.
Some of the methods provided by this class are as follows:
Table 5: Methods of the objects class

Method Description
Protected Object clone() throws This methods creates a copy/clone of the object
CloneNotSupportedException that invokes it and returns the copy
public boolean equals(Object obj) This method compares two objects and returns
true if the objects are equal

public final Class getClass() This method returns the runtime class of an
object

public int hashCode() This method returns the hashcode value for the
object invoking it
public String toString() This method returns the object in the form of a
string
protected void finalize() throws Throw- This method is called by the garbage collector
able on an object when the object is not referenced
anymore

These methods have been explained below.

a. The toString Method()


The method toString() in java is used to represent an object as a string
(Wu, 1996). This method is a method of the object class. On overriding
138 Object Oriented Programming with Java

this method, an object can be represented in a customized way. This is


shown as below:

Figure 153: toString() method.


As shown by the program ToStringExample above, the object can be
printed directly in the [Link] statement similar to other variables.
The output generated by this program is shown in figure 22:

Figure 154: toString() method (1).


If we do not override the toString() method the output is as follows:
Miscellaneous Classes 139

Figure 155: toString() method (2).


As seen by the output, the toString() method of the object class is
invoked and a hashcode is printed. If we want to print the actual values
of the objects, the toString() method needs to be overridden.

b. clone()
This method creates a copy and returns a copy of the object that invokes
it. It throws a CloneNotSupported Exception if the invoking class doesn’t
support the Cloneable interface.
140 Object Oriented Programming with Java

Figure 156: clone() method.


The output is as follows:

Figure 157: clone() method (1).


c. finalize(): This is a method that may or may not be invoked/called
on an object when the object is no longer in use (Goetz and Peierls, 2006).
This method may or may not be called by the garbage collector. We can
use this method in our java class to send a request to the jvm to clean up/
free memory, but there is no sure guarantee that it will be called/invoked.
This method can be invoked using a simple [Link]() method
call.
As there is no guarantee that this method will be called, it is advised
to close up all the resources that we use in our program before exiting.
This is valid for file description and input streams which will be discussed
Miscellaneous Classes 141
in Chapter 9.
d. getClass(): This method returns an instance object of the java type/
class Class. The object of type Class has several methods that can be
used to obtain information about the invoking class itself such as the
methods of the class, the members, variables and so on.

The output is as follows:

e. equals(): This method returns true if the invoking object and the ob-
ject passed as a parameter are the same. It uses the equals operator (==)
to compare two objects and determine their equality. This works well in
case of primitive data types. But in case of objects, this is not correct. The
‘===’ operator checks if the references of the two objects under consid-
eration are equal, which isn’t correct. The desired behaviour is that the
method should return true if the two objects contain the same informa-
tion. Hence, in case of Objects, if you want to check the equivalence of
two objects this method should be overridden.
142 Object Oriented Programming with Java

A simple java program demonstrating the use of the equals() method


is shown below:

In the example, we use the equals() method to compare Integers and


objects.
In case of integers, it returns true; but in case of the objects it returns
false as the equals() method has not been overridden in the class.
The output is:
Miscellaneous Classes 143
To correctly check if the objects are equal, we override the method
as shown below:

Now that the method has been properly overridden, we get the desired
output as follows:
144 Object Oriented Programming with Java

Another important point to note is that if your class overrides the


equals method, then it should override the hashcode() method as well.
The hashCode() method is described next.
f. hashcode(): This method returns the hash code value of the object
invoking it which is the memory address of the object in hexadecimal.
According to the Java definitions and documentation, if two objects are
equal, so is their hashcode (Gosling, 2000).
Hence, if you override the method equals(), then you change the way
the objects are compared for equality and hence the default hashcode()
method and its implementation is no longer valid for your class. As a
result of this behaviour, the hashcode() methd must be overridden if you
override the equals() method in your class.
An example demonstrating the use of the hascode() method along
with the equals() method is shown below:

The output generated is as follows:


Miscellaneous Classes 145

The hashcode() method can be overridden in any way that you want.
Generally, the use of prime numbers along with recursive calls to the
hashcode method by the members of the class is suggested.
An important point is that if two objects have the same hashcode they
may or may not be equal, but if two objects are equal they must have the
same hashcode.
Another simple way to override the equals() and the hashcode()
method is by using the Eclipse IDE. Eclipse offers this functionality. This
can be obtained in the menu obtained when you right-click on the page.
This is shown below:

A dialog pops up and you can click on Ok. The equals() and hashcode()
method are generated as follows:
146 Object Oriented Programming with Java
Miscellaneous Classes 147

DATE CLASS IN JAVA


This class is present in the [Link] package and represents a real time
date. This utility class in Java provides us with methods and constructors
that help us manipulate Date and time constructs in java. This class
implements the Serializable, Cloneable and Comparable interface.
Some important methods and constructors of this class are as follows:
Table 6: Methods of the Date class

Method/Constructor Description

Date() Creates a date object with current date and time

Date(long milliseconds) Creates a date object with an argument. This argu-


ment is the time elapsed in milliseconds after Janu-
ary 1 1970 at midnight.

long getTime() Returns the time that has elapsed since January 1,
1970.

setTime(long time) Updates the current date and time to specified time

boolean after(Date date) Checks if the current date comes after the specified
date and returns true if it does

boolean before(Date date) Checks if the current date comes after the specified
date and returns true if it does

int compareTo(Date date) Compares two dates.


Returns :
-0 if dates are equal
-Positive value if the first Date is after the specified
date
-Negative value if the first Date is before the speci-
fied Date

We shall now take a look at some examples demonstrating the use of


the Date class.
Example 1: Create a Date object
148 Object Oriented Programming with Java

The output is as follows:

Example 2: Manipulate date objects


Miscellaneous Classes 149

The output is as follows:


150 Object Oriented Programming with Java

SimpleDateFormat Class
This class is present in the [Link] package and is composed of methods
that help in parsing and formatting date and time in Java.
As evident from the examples of the Date class, the date is represented
in th format: “dd mm yy hh:mm:ss timezone” such as
Thu Jan 15 07:56:07 CET 1970
But, if want the date to be displayed in another format, we can make
use of the SimpleDateFormat class.
A use case demonstrating the use of this class is shown below:

The output generated is as follows:

Calendar Class in Java


This class is a special abstract class in Java that helps manipulate dates.
Using this class, a date can be expressed as calendar terms/fields such as
Miscellaneous Classes 151
months, days, years etc. For example, using this class, we can find out
which day of the week it is, or which day of the month it is and so on.
This class implements the Comparable interface. This class represents a
simple date in the Gregorian calendar format that is used worldwide.
The Calendar class has a concrete subclass called as the
GergorianCalendar class that represents the date in the Gergorian
calendar format.
Some useful methods from the Calendar class are as follows:
Table 7: Methods of the Calendar class

Method Description
Date getTime() This method returns a Date object that represents
the time value of the Calendar class
void setTime(Date date) This method sets the time of the Calendar to the
specified Date
static Calendar getInstance() This method is used to get an instance of the Cal-
endar class based on the current time, the default
locale zone in the current time zone
void setFirstDayOfWeek(int value) This method sets the first day of the week
int getFirstDayOfWeek() This method gets the first day the week
int getWeekYear() This method returns the week year of the calendar
instance
void add(int field, int amount) This method adds or subtracts a value from the
given instance
void set(int year, int month, int date) This method sets the values for the year, month
and date of a calendar instance
int getWeeksInWeekYear() This method returns the number of weeks in a
particular year that are present in the calendar
instance
int get(int field) This method returns the value of a particular calen-
der field (day/month/year)
abstract int getMaximum(int field) This method returns the maximum value of a given
field (day/month/year) of the Calendar instance
abstract int getMinimum(int field) This method returns the minimum value of a given
field (day/month/year) of the Calendar instance
boolean before(Object object) This method is similar to the before() method of
the Date class
boolean after(Object object) This method is similar to the after() method of the
Date class
152 Object Oriented Programming with Java

The before() and after() methods are analogous to the compareTo()


method only when the object is an instance of the calendar class.
Let us now take a look at some examples demonstrating the use of
the Calendar class.
Example 1: Displaying current date and time

The output is:

Example 2: The get() method


Miscellaneous Classes 153

The output is as follows:


154 Object Oriented Programming with Java

Example 3: Convert a Calendar instance to Date and vice versa

The output generated is:

Example 4: The add()


Miscellaneous Classes 155
The output generated is:
CHAPTER

8
EXCEPTIONS IN JAVA

An exception is defined as an event that occurs during the execution of a


program which disrupts the usual execution of the program’s instructions
(Horstmann and Cornell, 2002).
When an exception occurs the program is interrupted and it terminates
abruptly, which is not desirable. Hence, it is advisable to handle the
exceptions if possible.
Certain examples of exceptions are: invalid input given by the user,
divide by zero, etc
In java when an error occurs in a program method the following steps
take place:
• The method containing the error generates an object, called an
exception object and gives it to the runtime system.
• This object holds data regarding the error, its type and the
program’s state when the said exception occurs. This process
is referred to as “throwing an exception”.
• After this, an attempt is made to look for a method/something
that can handle the exception. The list of possible things that
158 Object Oriented Programming with Java

can handle the exception is the list of methods called before


the method that threw the exception; also called as the method
call stack.
• The java runtime looks for a method that handles the exception
in the reverse order of the call stack. This means that this
method contains a piece of code that knows how to deal with
the exception. This is called an exception handler.
• When a method that handles the exception is found, the runtime
passes the control to this method/handler. This means that the
method ‘catches’ an exception.
• In case the java runtime is unable to find a method that ‘handles’
the exception, the program terminates abruptly.

Figure 158: Call Stack (Exceptions, 1995).


Exception handling is a mechanism to control/administer runtime and
compile time exceptions that a java program can possibly throw. This is
extremely useful when we want to maintain the flow of the programs we
write. Suppose we have code of 5 statements. If an exception occurs at
the very first statement of the code, statements 2-5 are not executed. But
if the exception is handled, then all the following statements are executed
and a meaningful message is given to the end user stating that something
has gone wrong.
There exist 3 categories of exceptions:
a. Checked Exceptions: These occur at compile time and need to
be handled at compile time; else a compile time exception will
be thrown.
Exceptions in Java 159
b. Unchecked Exceptions: These exceptions are checked at exec-
tion/runtime and not at compile time.
c. Errors: These events are not exceptions but issues that come up
during program execution, which cannot be controlled by the
programmer or end user. They are nothing but abnormal events
that occur in case of major failures of the runtime environment.
For example, java out of memory exceptions.
The Exception classes all inherit from the Throwable class which is
the parent class. The hierarchy is as follows:

Figure 159: (Apps, 2017).


All runtime and compile exceptions descend from the class Exception.
The class Error is another subclass of class Throwable.
Certain examples of errors and exceptions are:
160 Object Oriented Programming with Java

Figure 160: ([Link], 2017).

HANDLING EXCEPTIONS
Java has provided us with certain keywords that are part of the exception
handling mechanism. They are: try, catch, throw, throws and finally.

The try-catch block


The bare minimum requirement of exception handling is a try-catch block.
The try block consists of the code that is likely to throw an exception and
the catch block handles this exception. In other words, the code likely to
thrown an exception is surrounded by this block.
The basic syntax is as follows:

try{
}
catch (Exception e){
}

A try block needs to be followed by a catch or a finally block. It cannot


exist on its own. It can be followed by one/more catch blocks but only
one finally block (Horstmann and Cornell, 2002).
Exceptions in Java 161
A simple program with the implementation of a try catch block is
shown below:

The above sample code tries to divide an integer by zero in method1.


This is an arithmetic exception in Java. The code handles this exception
and gives a meaning message to user without causing an abrupt
termination of the program.
The output of the above program ExceptionHandling is as follows:

A try block can be accompanied by one/more catch blocks. It can be


written syntactically as:
try{
}
162 Object Oriented Programming with Java

catch(Exception1 e1){
}
catch(Exception2 e2){
}
catch(Exception3 e3){
}
When an exception is thrown, if it isn’t caught by the first catch block,
it is passed on to the next until the appropriate block that handles that
exception is reached. If the exception is not caught by any of the catch
blocks, it is passed to the runtime and the program ends.
The next example demonstrates the use of multiple catch blocks.
Exceptions in Java 163
The output of the above code is as follows:

As the arithmetic exception has been thrown before the


ArrayIndexOutofBounds exception, it is the only one handled by the
code.
In case of multiple try blocks, it is paramount to know that they must
be ordered in a particular way; from the most specific exception to the
most general. Hence, arithmetic exception has been caught before the
general type ‘Exception’.

In java it is also possible to have one try block inside another. This is
called as nesting of try blocks or nested try blocks. This may be employed
164 Object Oriented Programming with Java

when a particular section of code is likely to throw an exception that is


completely unrelated to the exception thrown by the entire block.
The class ExceptionHandling demonstrates the use of nested
try catch blocks. We have a nested try catch block that handles an
ArrayIndexOutOfBounds Exception and the outer block that handles an
arithmeticException.
The generated output is the following:

As we can see, both the exceptions have been caught and the code
following the outer try block has been executed as well.

Keywords throw and throws


The keyword throw is used when a method wants to explicitly throw/
invoke an exception.
The use of the keyword throw has been demonstrated in the program
ExceptionHandler below:
Exceptions in Java 165
The output of the above program is as follows:

The throws keyword is generally used by a method when it doesn’t


want to manage an exception that is checked. By using this keyword, it
passes on the job of exception handling to the class further up in the call
stack.
The caller has to handle the exceptions thrown by that method.
The syntax for a method is as follows:
public void method1() throws ArrayIndexOutOfBoundsException,
NullPointerException {
}
Sometimes throws is used in combination with throw as follows:
166 Object Oriented Programming with Java

The output/result is the same as before; the class throws and arithmetic
exception like in the previous example.

The Finally Block


The finally block is a block that can be written after a try block. This
block is always executed even if an exception occurs.
When exceptions are thrown by methods in a program, the regular
flow of code is interrupted and the method may not execute completely.
Based on the manner in which the method has been coded, it is highly
possible that an exception may cause the method to terminate prematurely,
which could be an issue in case of certain methods. A simple example is
that if a method opens a file at its very beginning and closes it in the end,
if an exception occurs somewhere in the middle, then the code that closes
the file is bypassed. The finally keyword helps in this situation serving as
a contingency plan.
This is a block of code that is executed after a try or catch block even
if an exception doesn’t occur. So, if the method throws and exception,
this block is executed even if there are not surrounding catch clauses that
match the exception thrown. When a method is about to return the control
from within a try or catch block, or through an uncaught exception the
finally block is executed just before the return from the method.
This block can be useful for closing up resources that have been used/
allocated during the course of the program with the intention of freeing
them before the method ends. The block finally is not compulsory, but
if there are not catch clauses following a try block, the finally block is
obligatory. In simpler terms, a try block must be followed by a catch
block or a finally block. Further, a try block can be followed by any
number of catch blocks but only a single finally block.
Even in case no exceptions are thrown, the addition of cleanup code
to prevent leakage of resources in this block is considered to be a good
practice.
Some examples of the use of this block are shown by the class
FinallyExample below:
Example 1: Class implementing the try/catch/finally
Exceptions in Java 167

In this example, the method method1() throws an exception which is


caught by the catch clause after which the finally block is executed. The
output generated is as follows:

Example 2: Class implementing only the try/finally block:


168 Object Oriented Programming with Java

In the above example, the exception is not caught in a catch block,


but the finally block is still executed. Hence, the output is as follows:

Two important points to note about the finally blocks are:


• In rare situations, there is a chance that the JVM may exit
during the execution of the try/catch block. In such cases the
finally block is not executed.
• If a thread that is executing the try/catch block is killed/
interrupted, there is a chance that the finally block may not
execute, even though the rest of the application is still executing.
CHAPTER

9
INPUT OUTPUT

A program may need to communicate to the external world from time to


time via a network, file storage or even a simple keyboard input. Like
most programming languages, java supports input/output operations
via the file system and the byte streams, providing us with the [Link]
package.
This package consists of a number of classes and interfaces that help
in performing I/O operations. The main concept in case of I/O operations
is called a stream. A stream is nothing but a continuous sequence of
information/data. In java, a stream is made up bytes; each stream
consisting of an input and output or a source and destination. In java,
streams support several data types as follows: integer, characters and
other primitive data types, objects and so on.
A stream is further divided into an input and output stream. The
input stream reads the input from a source, whereas the output stream
writes the data to a particular destination (Gosling and McGilton, 1995).
Streams basically carry data to and from the source to the destination.
Data flowing into the program comes via the input stream whereas data
flowing from the program to another destination travels via an output
stream.
170 Object Oriented Programming with Java

Some possible sources and destination could as follows:

The Input output streams in java are classified as follows:

Classification of streams in Java

BYTE STREAMS
Byte Streams are used by Java programs to perform I/O operations on
bytes of 8 bits. All the classes that help in perfuming byte operations
descend from the Input Stream and Output Stream classes.
There exist several classes that support byte operations. We shall
focus on the classes FileInputStream and FileOutputStream classes.
The following class [Link] demonstrates the use of these
streams. The class shows how to read a file and copy the contents of the
file into another file.
Input Output 171

}
The file [Link] has the following content in it:
Hello! How are you doing?
Have a good day!!
On execution of the program, a new File called [Link] is
generated and the contents of the input file are copied to this file as shown
below:
172 Object Oriented Programming with Java

We now proceed to look at character streams and examples of their


use.

CHARACTER STREAMS
Character streams are used to handle Unicode inputs and output. This is
not supported by Byte Streams. Byte Streams do not support any encoding
stream. So, if we try to work on a character set that is not 8 bits (like
ASCII), the output would be not be correct as the byteStream just treates
the input bitwise. A simple example is a file that employs UNICODE
encoding system. This means that 2 bytes are used per character whereas
the Byte Streams only use 1 byte. The Byte Streams split the data while
reading into a single byte and this could result in bad data.
This is avoided by the use of character streams that automatically
adapts to the local character set, being able to read characters in a wide
variety of languages. It supports internationalization without added
development work for the programmer to accommodate new languages.
The classes belonging to the character stream support Unicode
characters (16-bit) and enable the user to perform operations on simple
characters, arrays of characters, strings and so on. As shown below, they
are further divided into a Reader and a Writer class. The reader reads 2
bytes at a time and the Writer writs 2 bytes at a time. All the character
classes descend from the Reader and Writer abstract classes.
The use of the character streams is demonstrated by the class
FileExample which copies the contents of a UNICODE file into another
file.
Input Output 173
174 Object Oriented Programming with Java

As we can see, this example is very similar to the previous example.


The only difference is that a FileReader and a FileWriter has been used.
The only difference in the 2 examples is that the variable byteChar holds
a character value in the last 16 bits in this example. In the previous
example, this variable holds the value in the last 8 bits. The output/results
generated are the same as that of the previous example.

BUFFERED STREAMS
The buffered streams make use of buffers to read/write data. Buffers are
helpful in increasing program speed and performance. Generally, in an
unbuffered stream, each read and write operation is handled by the OS
every time it is called, which means that multiple native method calls are
done. This can result in inefficiency of the program as each native call to
the OS requires time, access to the disk or file system and so on. To help
fix this issue, we make use of buffered streams. Programs feed the data to
a buffer and these streams read data from the buffer. The native methods
for the read operation are called only when the buffer is empty. In case
of the write operation, these streams write data to a buffer until it is full,
after which the native method call is executed to write the data. The
buffered streams are like wrapper classes that wrap the stream objects.
There are 4 buffered classes:
BufferedInputStream and BufferedOutputStream for byte streams
BufferedReader and Buffer for character streams
The following class BufferedStreamExample, using the concept of
buffered streams is shown below:
Input Output 175

As shown by the class BufferedStreamExample, Reader and Writer


objects have been wrapped inside the BufferedReader and writer objects.

JAVA STANDARD I/O STREAMS


Java provides us with the following standard i/o streams via the System
class that are attached to the console.
• Standard Input – This is the standard input stream. This gener-
ally refers to the keyboard input and is this input is consumed as
[Link].
• Standard Output – This is the output standard output stream that
displays the program output. The output is generally the monitor/
console of a computer. This output is well known and is depicted
as [Link].
• Standard Error – This stream is for the errors produced by the
program and is displayed using the [Link] statement.
176 Object Oriented Programming with Java

A simple program ConsoleExample demonstrates the use of the


standard streams. The class ConsoleExample reads input from the
keyboard and displays it on the console. The program will read the input
until the user inputs the letter ‘e’.

The output generated is as follows:

The input is shown in green and the same value is displayed on


console in black.
Input Output 177

I/O HIERARCHY
The hierarchy of the I/O classes with some I/O classes in Java is as shown
below:

We shall now take a look at some of these byte and character stream
classes using examples.

FilterInputStream and FilterOutputStream


The FilterInputSream class is a subclass of the InputStream class and
this class contains other input streams that inherit from it. This class
overrides the methods from its parent class and its subclasses further
override methods from this class. Similar to the FileInputStream, this
class has the standard read() method to help read inputs sent to the I/O
((Naughton and Schildt, 1996). Some implmenetations/subclasses of this
class are:
BufferedInputStream, CheckedInputStream, DataInputStream,
DigestInputStream, etc.
The FilterOutputStream class, like its counterpart FilterInputStream
descends from the OutputStream class. It too overrides the methods of its
parent class and its subclasses further override the methods of this class.
Similar to the traditional writer classes this class has the write() method
178 Object Oriented Programming with Java

that writes output to the desired destination.


Some implementations of this class are:
BufferedOutputStream, CheckedOutputStream, DataOutputStream,
DigestOutputStream, etc
The use of these two classes is shown below:

We use the FilterOutputStream to wrap a FileOutputStream object to


write to a file. The FilterInputStream is used to read the contents of the
file. This class wraps an object of the BufferedInputStream.
The output generated is:
Input Output 179
ByteArrayInputStream and ByteArrayOutputStream
The ByteArrayInputStream is a subclass of InputStream that accepts a
byte array as a source of input. It contains an internal buffer that is made
up of bytes that can be read from the stream (Friesen, 2015).
The ByteArrayOutputStream is a subclass of OutputStream that
writes data into an array of bytes (internal buffer). The size of the Buffer
grows as the data is written into it (Friesen, 2015).

The output is:

DataInputStream and DataOutputStream


These streams are used to read and write primitive data types (int, double,
float, etc) into an input and output stream respectively. A DataInputStream
180 Object Oriented Programming with Java

object wraps an InputStream object whereas a DataOutputStream object


wraps an OutputStream objects.

The output is as follows:

ObjectInputStream and ObjectOutputStream


An ObjectOutputStream extends from the InputSream class and
is used to write primitive data types and graphs of Java objects to an
OutputStream in binary format. These objects can further be read using its
counterpart Input Stream class ObjectInputStream. An ObjectInputStream
reads primitive data types and objects that have been written using an
ObjectOutputStream. The state of an object can be persisted by using a
Input Output 181
File object to store the data (Naughton and Schildt, 1996).
A few examples demonstrating the use of the ObjectOutputStream
and the ObjectInputStream have been provided below.
Example 1: Using File objects for persistence

The output is:

Example 2: Reading and Writing user-defined objects


182 Object Oriented Programming with Java

The output is:


Input Output 183
Note that in the above example the user defined class MyClass has to
be declared to implement the interface Serializable as we save its state.
The Serializable interface has been discussed in Chapter 11.

StringReader and StringWriter


The StringReader and the StringWriter classes take character streams.
The StringReader class extends the Reader class and the StringWriter
class extends the Writer class respectively.
The StringReader class takes in a String as an input and converts it
into a character stream.
The StringWriter class is a character stream that takes in input in the
form of a string buffer which is used to build a String (Naughton and
Schildt, 1996).
184 Object Oriented Programming with Java

As seen from the class StringReaderWriter we have not closed the


resouces stringReader and stringWriter. This is because when we use
these classes the system resources like files, sockets, etc are not used and
hence it is not necessary to close these resources.
The output is:

FilterReader and FilterWriter


The FilterReader class is an abstract class that helps read input from
different character streams.
The FilterWriter class, is the counterpart of the FilterReader class,
is another abstract class that is used to write data to different character
output streams.
The classes that subclass the FilterReader and FilterWriter class must
provide overridden implementations of their respective superclass.
A basic example that makes use of these classes is shown below. The
class below wraps a StringWriter object within a FilterReader object for
writing and into a FilterReader object for reading purposes.
Input Output 185

The output is:

These classes can also be used to create custom reader and writer
classes. A custom Reader and Writer class has been shown below.
186 Object Oriented Programming with Java

Custom Reader Example:

The output is:

Custom Writer Example:


Input Output 187

The output written to the file [Link] is:

CharArrayReader and CharArrayWriter


The CharArrayReader and the CharArrayWriter class are used to read
and write a character array respectively. Both these classes implement a
character buffer. The character array serves as a source of input for the
CharArrayReader class.
In case of the CharArrayWriter class, the buffer size grows
automatically when some data is written to the stream (Chan, Kramer
and Lee, 1999).
188 Object Oriented Programming with Java

A couple of examples demonstrating the use of these classes have


been provided.
Example 1: A simple program demonstrating the use of the
CharArrayReader and the CharArrayWriter classes.

The output is:


Input Output 189
Example 2: Writing data to multiple files using the CharArrayWriter
class
The CharArrayWriter class can also be used to write data to multiple
files which can save time if we want to replicate data across many files.
This is shown by the class CharArrayWriterExample.

The output generated is as follows:

The content of the 3 files generated by the above program is shown


below:
190 Object Oriented Programming with Java

As shown by the content written in the files, the same content has
been successfully written to 3 different files.

PipedInputStream and PipedOutputStream


These classes implement the input and output components of a traditional
Operating System pipe operation. A pipe is basically a way to pass
output from one process/program as an input to another program. A
PipedOutputStream must be connected to a PipedInputStream and vice
versa.
They both are connected to one other to create a communication pipe
(Friesen, 2015). These classes can further be used to perform read and
write operations at the same time as the streams are connected.
The data is sent via the PipedOutputStream (it serves as the sending end)
and is fed as an input to the PipepInputStream (it serves as the receiving
end).
Input Output 191

In the above class, the PipedInputStream and the PipedOutputstream


are connected to form a pipe. The output from the PipedOutputstream is
fed to the PipedInputStream which further reads and prints the data.
The output is as follows:
192 Object Oriented Programming with Java

These classes are also used in the context of multithreading and will
be discussed in Chapter 16.

PipedReader and PipedWriter


The PipedReader class is used to read piped character-input streams and
the PipedWriter class is used to write piped character-output streams.
Like the PipedInputStream and PipedOutputStream, these two classes
are connected to one another where the PipedWriter class is the sender
and the PipedInputStream is the receiver.
Output from the writer is sent as an input to the reader which reads
the data.

The output is:


Input Output 193

The PipedReader and the PipedWriter classes are also used in a


multithreaded context which will be discussed in Chapter 16.
Additional information about the I/O package is provided at the
following link:
[Link]
html
The scope of this book does not cover all the classes that are part of
the java I/O package.
CHAPTER

10
NEW I/O (NIO)

The java New I/O package is a library that was introduced starting
from java version 4. It is an alternative to the existing traditional I/O
package. This package NIO provides high-speed, block-oriented input
output operations in our regular Java code. This NIO package makes
use of low-level optimizations in a manner better than the traditional I/O
without using native machine code. This means that the I/O operations
are performed directly at the operating system level, which reduces the
time spent on time consuming I/O operations (Friesen, 2015).
The NIO package is based on the concepts of Buffer, Channels,
Selectors and Non-Blocking I/O.
We shall now discuss these concepts in brief.

CHANNELS AND BUFFERS


In traditional java I/O we make use of character and byte streams to
perform I/O operations such as read and write.
But, in NIO, Channels and Buffers are at the heart of the I/O
operations. In NIO, the data is written to a Buffer from a Channel and
read vice versa.
196 Object Oriented Programming with Java

A Channel is simply an object that permits you to read and write data
to it. Here a channel is analogous to a Stream. Using NIO channels, we
do not write data directly to the Channel but to Buffers, which provides
decoupling of the data and the connection stream.
Channels are slightly different from streams as they are bi-directional.
We can open a channel for reading, writing or both the operations.
A Buffer is an object in NIO that holds your data that can be read or
data that has to be written to a particular destination. A buffer is very
similar to an array in java. It is basically a simple array of bytes. But
it provides many more additional features than a simple array such as
structured access to the data, various methods to manipulate data, tracking
of the read and write operations performed on the data and so on.
A channel reads and reads data from and to a buffer respectively. This
is illustrated below:

The NIO package consists of a Buffer class that holds primitive data
types. This class has the following subclasses:
• IntBuffer : Buffer that operates on primitive type int
• ShortBuffer : Buffer that operates on primitive type short
• LongBuffer : Buffer that operates on primitive type long
• FloatBuffer : Buffer that operates on primitive type float
• DoubleBuffer : Buffer that operates on primitive type double
• CharBuffer : Buffer that operates on primitive type char
• ByteBuffer : Buffer that operates on primitive type byte
New I/O (NIO) 197
The Channels package consists of several types of channel classes
and interfaces. Some of them have been described below.
Channel Classes (Friesen, 2015):

Table 8: Channel Classes (Friesen, 2015)

Class Description
FileChannel This channel helps read, write, map and
manipulate files
DatagramChannel This channel is used for datagram related
sockets (selectable)
AsynchronousFileChannel This channel is an asynchronous file channel
SocketChannel This channel is used for connecting sockets
(selectable)
Pipe This channel consists of two unidirectional
channels that implement a pipe
Channel Interfaces (Friesen, 2015):

Table 9: Channel Interfaces (Friesen, 2015)

Interface Description
ByteChanel A class implementing this channel interface can
read/write bytes
AsynchronousByteChannel A class implementing this channel interface sup-
ports asynchronous I/O operations
AsynchronousChannel A class implementing this channel interface is an
asynchronous file channel
NetworkChannel A class implementing this channel interface im-
plements a network socket
MulticastChannel A class implementing this channel interface im-
plements and supports IP multicasting operation
ReadableByteChannel A class implementing this channel interface can
perform read operations on bytes
The classes DatagramChannel and SocketChannel are marked as
selectable classes which means that they can be selected by the Selector
interface. This will be discussed in Section 10.4
The next section covers some examples demonstrating the use of
Channels and Buffers
198 Object Oriented Programming with Java

Examples of Channels and Buffers


Example 1: ByteBuffer put() method

The output is:

Example 2: ByteBuffer get() method


New I/O (NIO) 199

The output is as follows:

Example 3: Read a file using Channels and Buffers.


The following example shows the use of Channels and Buffers.
The example reads the following file:
200 Object Oriented Programming with Java

The output is:

Example 4: Write to a File using Channels and Buffers


This example creates a new file named [Link] and writes data
to it.
New I/O (NIO) 201

The contents of the file myFile1 are as follows:

Example 5: Read and Write to a File using Channels and Buffers


This example writes data to a file and then reads the data written to
the file.
202 Object Oriented Programming with Java

The above example firsts writes data from a String to the file and then
reads the data that was written in the file. If the file doesn’t exist, a new
file is created. If the file exists and is not empty, then the contents of the
file are overwritten with the new contents.
The output generated by the above class is:

The contents of the file ‘myFile’ are as follows:


New I/O (NIO) 203

Example 6: TransferFrom() method


This example transfers the contents of a file ([Link]) to another
file ([Link]) using channels.
Initially, the contents of the two files are as follows:

The class is as follows:

After execution of the program, the contents of [Link] have been


updated as follows:
204 Object Oriented Programming with Java

Example 7: Transfer contents from one file to another using buffers


The contents of the two files ‘[Link]’ and ‘[Link]’ before
the copy operation are as follows:

The class NIOExample7 that performs the copy operation is shown


below:
New I/O (NIO) 205
After execution of the class, the contents of the file ‘outputFile’ are
updated as follows:

NIO PATH AND FILES CLASS


The NIO package in Java provides additional utility classes Path, Files
and Paths that help in handling of files.
Path: This is an object that can be used to locate a files situated on a
file system. It serves as an entrypoint for the [Link] class. Like its
name, ‘Path’ represents the actual path of a file on the file system such ‘C:
\[Link]’ for example. It represents a system dependant file path (docs.
[Link], 2017).
Files: This is a utility class that provides api that can be used to
perform operations on files and different file types or directories. This
class is composed of only static methods.
Paths: This class is another utility class that helps recover a Path
object. It is made up entirely static methods that return a Path object from
a string input or a URI.
The above classes are used in combination with one another. A Path
object is a real representation of the underlying operating system. A path
is dependent on the system; in Windows is shown as C:\mtfoler and a
path in Linux is /home/myfolder. Path from two different Operating
Systems cannot be compared.
A path object can be used to in many ways; by appending to it,
extracting parts of the path from it, compare different paths and so on.
Additionally, a Path object can be used in combination with the Files
class to check if a file exists at the given path and manipulate files by
performing different file operations such as file creation, opening,
deletion, changing the owner and its permissions and so on.
The classes Files, Paths and Path provide several methods that help
in file and directory manipulation.
206 Object Oriented Programming with Java

Some important methods from these classes are described below.

Paths Class Methods


Table 10: Path class methods ([Link], 2017)

Method Description
static Path get(String first, String This method takes the path as an
otherStrings…) input of multiple strings which when
joined gives the entire path String
and returns a Path object
static Path get(URI uri) This method takes the given URI
(uniform resource identifier) and
returns a Path objects

Files Class Methods


Table 11: Files class methods ([Link], 2017)

Method Description
static boolean deleteIfexists(Path This method deletes a file if it exists at the
path) given path and returns true if the file was
deleted.
static boolean exists(Path path, This method tests if a file exists and returns
LinkOption…options) true if it does.
static byte[] readAllBytes(Path This method reads all the bytes from a file
path) and returns a byte array containing the bytes
that were read
static List<String> This method reads all the lines from a file
readAllLines(Path path) and returns a list of Strings containing the
contents of the file
static Path setOwner(Path path, This method updates the owner of the file to
UserPrincipal owner) the owner specified as a parameter.
static long size(Path path) This method returns the size of a file in bytes
static Path write(Path path, byte[] This method writes bytes to a file
bytes, OpenOption..options)
static Path write(Path path, Iterable This method writes lines of text input to a
<? extends CharSequence, Ope- file.
nOption..options)
static Path createDirectory(Path dir, This method creates a new directory and
FileAttribute>?> attributes) returns its path
New I/O (NIO) 207

Static path createFile(Path path, This method creates a new empty file and
FileAttribute>?> attributes) returns its path. This method fails if the file
already exists.
Static BufferedReader new This methods opens a file at the specified
BufferedReader(Path path) path for reading and returns a BufferedRead-
er object to read the file text
Static BufferedWriter new This methods opens/creates a file at the
BufferedWriter(Path path, Ope- specified path for writing and returns a
nOption…options) BufferedReader object to write contents to
the file

Path Class Methods


Table 12: Path class methods ([Link], 2017)

Method Description
int compareTo(Path an- This method compares two paths
otherPath)
boolean endsWith(Path This method returns true if the invoking path ends
otherPath) with the specified path
boolean startsWith(Path This method returns true if the invoking path starts
otherPath) with the specified path
Path toAbsolutePath() This method returns a Path object with the absolute
path
File toFile() This method returns a File object that represents the
Path
Path subpath(int beginIn- This method returns a relative path that is a sequence
dex, int endIndex) of the names of the elements in the path
URI toUri() This methods returns a URI representing the path
Path normalize() This method eliminates redundant elements and re-
turns a path
boolean isAbsolute() This method returns true if the given path is absolute
Path getFileName() This method returns the name of the file or directory
held by the path
Path getName(int index) This method returns a name element as a Path object
Path getRoot() This method returns the root directory/element of the
path
Path getParent() This method returns the path of the parent or null if no
parent exists for the path
int getNameCount() This method returns the number of elements present in
the path
208 Object Oriented Programming with Java

Examples

Example 1: Simple File creation

The output is:

As seen from the output, as the file did not exist before creation,
the method returns false. A new file named [Link] is created at the
location specified by the path.
Example 2: Retrieve information about the path using static methods
of the Paths and Path class
New I/O (NIO) 209

The output is:

Example 3: equals(), startsWith() and endsWith() methods


210 Object Oriented Programming with Java

The output is:

Example 4: Iterate over the Name elements of a path


New I/O (NIO) 211
The output is as follows:

The Path class implements the Comparable interface which means


that two paths can be compared using the compareTo method (docs.
[Link], 2017).
Example 5: Read the contents of a file using the method readAllLines()

The output is:

Example 6: Write to a file using the write() method


212 Object Oriented Programming with Java

The above class writes to the file [Link]. The contents of this file
are:

Example 7: Reading the contents of a file using a BufferedReader


object
New I/O (NIO) 213
The output is as follows:

Example 8: Write to a file using a BufferedWriter object

On execution of the above code, the file [Link] is updated with the
contents specified. The contents of the file [Link] are:

Example 9: Write to a file by providing options


Various options for opening a file are defined by the class
StandardOpenOption. This class provides us with useful file operation
constants such APPEND, CREATE, CREATE_NEW, READ etc. In this
example, we make use of constants from this class to open the file in
append mode. Additionally, we write a List of Strings to the file.
The initial contents of the file are:
214 Object Oriented Programming with Java

The class is as follows:

The updated contents of the file [Link] are as follows:

Example 10: File createFile(), isRegularFile(), isReadable() ,


isWritable() methods
New I/O (NIO) 215
The output is:

On execution of the code, the highlighted files are deleted and a new
directory is created at the specified location.

Example 10: FileSystem API


216 Object Oriented Programming with Java

The output generated is as follows:


New I/O (NIO) 217

NIO SCATTER AND GATHER


The Java NIO package provides an interesting functionality called as
scatter and gather. This a very powerful technology provided by this
package that permits you to write bytes of data from multiple buffers
to a channel and read data into a channel from multiple buffers. This
functionality is inbuilt within the NIO package, which is generally used to
perform read() and write() operations on channels using multiple buffers.
Scattering Read: This operation reads data from a single channel into
many buffers (Horstmann and Cornell, 2002).
This is depicted below:

Programmatically the scattering read is done as follows:


ByteBuffer buffer1 = [Link](512);
ByteBuffer buffer2 = [Link](512);
ByteBuffer[] byteBufferArray = { buffer1, buffer2 };
//read data from multiple buffers
[Link](byteBufferArray);
Gathering Write: This operation writes data from many buffers into
a single channel ((Horstmann and Cornell, 2002). This is depicted below:
218 Object Oriented Programming with Java

Programmatically the gathering write is done as follows:


ByteBuffer buffer1 = [Link](512);
ByteBuffer buffer2 = [Link](512);
//write data into multiple buffers
ByteBuffer[] bufferArray = { buffer1, buffer2 };
[Link](bufferArray);

SELECTORS
In Java NIO a new concept called ‘Selectors’ has been introduced. This
functionality basically provides a way to handle many sources of data.
In java NIO, a Selector is basically a class that examines your channels
and checks which channel is available for communication i.e. read and
write operations.
This concept is very useful in a multithreaded context as by using
Selectors, we now have the possibility to make use of a single thread
to manipulate several data sources. This is efficient in terms of memory
as context switching between threads is expensive for the underlying
operating system. Additionally threads take up memory.
The abstract class Selector defined in the [Link] package
has been provided by NIO to provide this functionality. It is basically
a multiplexor that takes in selectable channels. Selectable channels are
those that can be used in non-blocking mode.
It is important to take note of the fact that in addition to providing read
New I/O (NIO) 219
and write functionalities, Selectors are capable of listening for incoming
connections and writing to several slow channels.
As the selector is capable of monitoring the streams of communication,
it need less threads to handle the channels, thereby improving the
efficiency.

NON-BLOCKING I/O
Java NIO permits us to perform Non-Blocking I/O operations.
For instance, imagine a thread asking a channel to read some data into
a buffer. During the time the channel reads the buffer, the thread can be
assigned to some other task. In this way, time is saved. Once the channel
reads the data from the buffer, the thread can resume its previous task.
The exact same process is applicable in case of write() operations.
CHAPTER

11
ADVANCED JAVA CONCEPTS

NESTED CLASSES
Similar to nested loops, in java we have the possibility of writing and
declaring nested classes in Java. These classes are called as inner classes.
The syntax of a nested class is as follows:
Class Outer {
Class Inner {
}
}
Nested classes are used as they help in logical grouping of classes
that are used in a single place. Further they promote encapsulation and
make the code more readable.
Nested class are of 2 types: Static/ Non-static or Inner classes

Static Nested classes


An inner class declared as static is called a static inner class. A static
inner class has access to the static members of the class enclosing it,
222 Object Oriented Programming with Java

except for private members. It does not have the right to access the non-
static members of the enclosing class. It can be declared as either public
or default.
The syntax of such a class is as follows:
public class OuterClass {
public static class InnerClass {

}
}
A simple example of a static InnerClass is shown below:

The output generated by the class OuterClass is as follows:


Advanced Java Concepts 223

An object of the inner class can be created using the syntax as shown
in the above class OuterClass.

Inner/ Non-Static Classes


A non-static nested class, as its name suggests is an inner class that is not
static. There are further divided into three types:
1. Basic Inner class: This is a class that is declared within another
class. A simple example is shown below:

As compared to the static inner class, we instantiate the non-static


inner class with the object of the outer class. Non-static inner classes
have access to all the members of the enclosing outer class, even their
private members as shown in the class above.
The output generated is as follows:
224 Object Oriented Programming with Java

[Link] Inner classes: These classes are nested classes that


are declared within a method body or any block of code such
methods, expressions and statements. We can declare these
classes in an if loop, in an assignment statement, in a method,
in a block of code and so on.
An example of a local class is as follows:

In the above example, the inner class cannot be accessed from the
main method of the outer class. Hence, its instance has been created and
used within the outer/enclosing class method. The output generated is as
shown below:
Advanced Java Concepts 225

A key critical point to note is that the local class cannot be declared
as public. It has to be declared as default.
3. Anonymous inner classes: These classes are nested classes
that are declared within a method body and they do not have
a name, which is why they are called as anonymous inner
classes.
These classes are similar to local classes except that they do not have
a name. They can be declared via two ways: class and interface. Both
have been explained below:

Using a Class
In this case, a class is sub-classed in another class. The example
AnaonymousClassDemo shows how to create and instantiate an
anonymous class.
226 Object Oriented Programming with Java

As seen from the example, the class Anonymous class is a simple


class like any other java class. The important part is in the class
AnonymousClassDemo, where an anonymous class instance of class
AnonymousClass has been created. As we can see, an object of class
Anonymous class with a method body has been created along with the
instantiation of the object. The body ends with a semicolon. This is
not a normal class as we generally do not see method definitions when
we instantiate a class. In reality, the above code is actually creating a
subclass/child class of the class AnonymousClass. The instance object
obj1 is an instance of the anonymous subclass declared within the class
AnonymousClassDemo. So, it is a subclass.
When we execute this program, the output is as below:

As noted from the output, the method1() of the anonymous class


declared in the class AnonymousClassDemo has been invoked. The
overridden method has been called. This class is called an anonymous
class because it literally has no name. Its entire structure has been created
within an instance object.

Using an Interface
In this case, an interface is instantiated and implemented at the same time
by a class. This is shown by the class AnonymousImplementation below:
Advanced Java Concepts 227

The figure above shows that this example is similar to the previous
one; the only difference being that in this example, an interface has
been instantiated and its method has been implemented by the class
AnonymousImplmentation on instantiation.
The output of this class is the same as from the previous example.

Why use these anonymous classes?


Anonymous inner classes help in overriding methods of a superclass. But
this can be done in a separate class as well. Then why should we make
use of an anonymous inner class? Well, this is helpful when you want to
override a small part/function of code without creating a whole new class
via inheritance and overriding. In short, the overhead of creating a new
class can be avoided using such classes. Additionally, if the particular
piece of code is going to be used only once, an anonymous class makes
more sense.
In general, nested classes serve readability of code and allow us to
view the classes conveniently package-wise. Additionally, local or non-
static nested classes are used when you need to create several instances
of the local class and get access to the members (both static and non-
228 Object Oriented Programming with Java

static), constructor and methods of the enclosing class. Static nested


classed should be used when you want to access only the static members
of the enclosing class.

WRAPPER CLASSES IN JAVA


As we have already seen, java has 8 primitive data types. Each one of
these classes has a class dedicated to it. These classes are called as wrapper
classes. They are named as such because they ‘wrap’ the primitive data
type and it value and convert it into an object of its wrapper class.
Wrapper classes are used so that primitive data types can perform
operations similar to that of objects. This is especially useful when using
members of the Collections framework which will be discussed in the
next chapter.
Additionally they provide the functionality to convert objects into
primitive types as well.
Since the java se version 5 this is done automatically. It is called as
autoboxing and unboxing where primitives are converted to objects and
vice versa (Gosling, 2000).
Below is a table that shows the primitive types along with their
respective wrapper classes:

Table 13: Wrapper classes

Primitive Data Type Wrapper Class


Int Integer
Long Long
Float Float
Double Double
Byte Byte
Short Short
Char Character
Boolean Boolean
A sample java program making use of wrapper classes is shown
below:
Advanced Java Concepts 229

The output is as follows:

The wrapper class can take in String arguments in their constructor


as well. The declaration
Integer i = “33”; is completely legal.
An important thing to know about wrapper classes is that their objects
are immutable and hence thread safe.
Wrapper classes can also be used for binary, octal, hexadecimal
conversions as well. A simple example is shown in the class
230 Object Oriented Programming with Java

WrapperExample.

The output generated by the class WrapperExample is:

IMMUTABLE CLASSES AND OBJECTS


An immutable object is an object/instance whose state cannot be altered
post creation. Once the object is initialized, no further changes in its
state can be performed. Such objects are used in applications that are
concurrent or multithreaded where there is a high possibility that the
object is accessed by multiple threads. As their state cannot be changed/
altered the possibility of data corruption is avoided.
Advanced Java Concepts 231
An example of an Immutable class is the String class.
In java immutable classes can be created in the following way:
1. Declare the class as final
2. Declare all the variables and methods as private and final
3. Do not provide getters and setters for private variables
4. All fields should be initialized via a constructor
5. Clone the objects so that they return a copy and not the actual
object
6. If the class uses Mutable objects make them final
An example of an immutable class is as shown below:

As seen from the class ImmutableClass, the fields have been


declared as private and final. Moreover, they have been initialized via the
constructor and a clone has been provided at all times.
The values are not changed which is visible in the output shown
below:
232 Object Oriented Programming with Java

SERIALIZATION AND DESERIALIZATION IN JAVA


In java, we have the possibility of saving the state of an object as a
stream of bytes. This is known as serialization. The reverse process is
called as deserialization.
Serialization is defined as the conversion of the state of an object
to a byte stream so that the byte stream can later be reverted back to a
working copy of the object (Eckel, 2003).
The serialized object contains the data stored in the object along with
metadata of the object. In java, if a class or any of its parent classes/
superclasses implement the Serializable interface, the class is Serializable,
which means that it can be stored in the form of bytes and recovered and
transformed back into an object. The process of Deserialization is the
reverse of Serialization. It converts the serialized java object back to its
original object copy.
The Serialization interface is a part of the [Link] package. As
discussed in chapter 9, the [Link] package provides us with several
streams that help us read and write objects. The same methods can be
used in the process of Serialization and Deserialization. An example
demonstrating the process of serialization is shown below:
Advanced Java Concepts 233

The above example makes use of the ObjectOutputStream that


contains the functionality to write objects. The above class creates a file
named [Link] in the workspace which stores the state of the object ‘fruit’
that we create in the program. The contents of this file are as follows:
234 Object Oriented Programming with Java

The process of deserialization is exactly the reverse. This is


demonstrated by the class Deserialization example that reads from the
file ‘[Link]’ and creates an object of the type Fruit.

The output generated is as follows:


Advanced Java Concepts 235
As seen from the output, the state of the object has been restored
correctly. An important and noteworthy advantage of this process is that
it is transversal, meaning that an object is serializable across platforms. It
is independent of the JVM and hence we have the possibility to serialize
an object on one platform and deserialize it on another platform.

Serialization and the Transient Keyword


In case you do not wish to serialize a class member variable, it can be
declared as transient. The use of this keyword has been described by the
same example as above, but the field ‘fruitType’ has been declared as
transient.
236 Object Oriented Programming with Java

As seen from the class SerializationExample, the rest of the code


remains unchanged. The only difference is the addition of the transient
keyword. But the output changes as now the variable is not serialized and
hence its state is not preserved as shown below:
CHAPTER

12
THE COLLECTIONS FRAMEWORK

The Java Collections Framework is an architecture that manipulates


a collection of objects independent of the implementation details
(Collins, 2011). This framework is nothing but a collection of classes
and interfaces that help manipulate objects. Additionally, many useful
classes that implement data structures are provided by this framework.
The principal advantage of this framework is that general operations such
as deletion, insertion etc. can be rapidly performed using the classes and
API’s provided by this framework.
238 Object Oriented Programming with Java

The Collections framework hierarchy is shown below:

The interfaces are shown in blue and the classes are shown in yellow.
Additionally, another interface called the Map interface is provided
by this framework. It ia not a part of the collection interface hierarchy. Its
separate hierarchy is shown as follows:

The Collection interface serves as the backbone of the framework. All


collections implement this interface and hence inherit and implement all
its methods. Each of the classes implementing their respective interfaces
of this framework will now be discussed briefly.

LIST INTERFACE AND ITS IMPLEMENTATIONS


A list like its names suggests is a list of items or a sequence of items.
Similar to an array, its index starts at 0 and any element in a list can be
The Collections Framework 239
accessed via its index. A list can contain duplicate elements and accepts
null values as well.
This interface has three implementations: ArrayList, LinkedList and
Vector
ArrayList: This is a resizable implementation of an array. The
ArrayList grows dynamically in size and can hold null values.

The ArrayList class overrides the toString() method and hence can be
printed as a string directly as shown above. The output is:

In java version 7 and above, a concept called generics has been


introduced. Many classes, called as generic classes have type parameters
in their declarations such as the letter E in ArrayList<E>. This is a random
generic type. So, when we create an instance/object of this class, we have
the possibility to provide the type of the input parameter. This helps in
stronger checks at compile time. The example shown above can be re-
written as follows:
240 Object Oriented Programming with Java

As we can see in the class above, the ArrayList has been declared to
contain only Integer values. Additionally, we now do not need to cast the
variable i to int. The output is the same as before. Generics have been
discussed in chapter 13.
LinkedList: LinkList is a doubly-linked linked list data structure
implementation. Apart from its constructors, it inherits all its methods
from its parent. It permits duplicate and null values.
A simple example demonstrating the use of a LinkedList is shown by
the class LinkedListExample.

The output generated is as follows:


The Collections Framework 241

Vector: This class is similar to the ArrayList class and implements


an array that grows and shrinks dynamically. It accepts null values and
duplicates. The elements of a vector can be obtained by their indexes. The
size expands and shrinks on a need-basis. This class is very much like the
ArrayList class, the only difference being that it is thread-safe making it
a suitable choice for multithreaded applications. But, if your application
does not work in a concurrent context that requires synchronization,
then ArrayList should be preferred over vector as it is faster and hence
performs better.
A simple example of the Vector class is shown below:

The output is:

Stack: This class is a subclass of the Vector class and it implements a


standard LIFO (last in first out) stack. This class contains all the methods
of the vector class and implements some standard stack data structure
242 Object Oriented Programming with Java

methods if its own such as pop() to remove and return the top element or
the head, peek() to return the top, push() to add a new element, empty()
to check if the stack is empty or not and search() that returns the position
of the element that is searched.
An illustration demonstrating the use of this class is shown below:

The output generated by the class StackExample is as follows:


The Collections Framework 243

QUEUE INTERFACE AND ITS IMPLEMENTATIONS


A queue is a list of elements that are ordered, similar to the list interface.
But, the intended use if somewhat different in case of queues. Here a
simple First-In-First-Out algorithm has been implemented where the
elements that are inserted first and removed first (Collins, 2011). This
interface is implemented by the class PriorityQueue and the Deque
Interface.
PriorityQueue: This class implements the queue interface and
extends the AbstractQueue class and hence is composed of a combination
of implemented methods from the interface Queue and inherited methods
from the AbstractQueue class. This class does not permit null values and
is implemented as a priority heap. The elements are ordered as per natural
ordering or by a comparator at construction time of objects. Similar
to a queue in data structures, this class provides default queue-related
methods such as add(), remove(), poll() and peek().
A simple example of a PriorityQueue is shown below:
244 Object Oriented Programming with Java

The output generated is:

Dequeue Interface: This interface implements the queue interface is


called as the double ended queue and pronounced as deck. It is a simple
double ended queue that allows insertion and removal of objects at both
ends (Collins, 2011). Similar to the PriorityQueue standard methods
for insertion, deletion and retrieval of elements have been provided.
Two classes implement the deque interface, namely LinkedList and
ArrayDeque. The class LinkedList has already been discussed in the
previous section. We shall now discuss the ArrayDeque class.
ArrayDeque: This class provides yet another array implementation
that can be resized dynamically. They do not permit null values as elements
and are not restricted in terms of capacity. It is faster as compared to
LinkedList and Stack implementations.
The Collections Framework 245
A simple example demonstrating the use of this class is shown below:

The output generated is as follows:


246 Object Oriented Programming with Java

SET INTERFACE AND ITS IMPLEMENTATIONS


This interface implements only the Collection Interface and does not
permit duplicate elements. This Set is analogous to its mathematical
equivalent Set and they do not maintain order of the elements. This
interface has the following implementations: HashSet, LinkedHashSet
and SortedSet interface. The SortedMap interface is further implemented
by the TreeSet class.
HashSet: This is an implementation class that stores the elements
in a hashtable, doesn’t allow duplicate values but permits null elements.
The order of the elements is not maintained and objects of this type are
not synchronized. General methods to manipulate objects have been
provided such as add(), remove(), etc.
A simple example describing a hashset is as follows:

The output is:

As shown by the output, the elements are oredered in ascending


order/natural order.
The Collections Framework 247
LinkedHashSet: This implementation of the Set interface implements
a hashtable with a LinkedList that runs overs all its elements. Elements
belonging to this class are maintained in the order of insertion (insertion
order) and null values are permitted.
The following class LinkedHashSetExample demonstrates the use of
this class:

The output is:

As shown by the output, the order of insertion of the elements has


been maintained and duplicate values are not permitted.
SortedSet Inerface: This interface implements the Set interface and
provides a complete ordering of elements. Ordering is done on the basis
of natural ordering or with the help of the Comparable Interface. All
elements inserted into a class implementing this set must implement the
comparable interface as well. The class implementing this interface is the
TreeSet class.
• TreeSet: The elements in a TreeSet are stored in a red black
tree and are ordered based on their respective values. Null
248 Object Oriented Programming with Java

values are allowed. It is quite similar in its structure to the


HashSet. The only variation is that the elements are ordered in
an ascending manner.
A simple class implementing the TreeSet is shown below:

The output is:

As shown by the output, the order of insertion of the elements has in


the TreeSet been maintained and duplicate values are not permitted.

MAP INTERFACE AND ITS IMPLEMENTATIONS


A map is an object that holds key-value pairs. Each key maps exactly one
value and it generally doesn’t permit null values for keys. This interface
doesn’t inherit from the Collection interface but has properties similar to
that of the collection objects.
The Collections Framework 249
This interface has three implementations: HashMap, LinkedHashMap
and TreeMap
• HashMap: This is a collection class based on the Map
interface and it stores key-value pairs. HashMap is similar to
the HashTable class of the Set Interface and does not maintain
the elements in order. It is basically a hashTable based
implementation of the Map Interface. It is not synchronized
and also permits null values for keys and values.
A simple example of the use of HaspMap is shown below:

The output is:

• LinkedHashMap: Similar to the LinkedHashSet, the


LinkedHashSet class implements a hashtable with a linked
list that runs over all of its elements. The linked HashMap
maintains the order of insertion like the LinkedHashSet and
permits null values.
A simple example of this class is shown below:
250 Object Oriented Programming with Java

The output is as follows:

• TreeMap: This class extends the NavigableMap interface and


implements a Red-Black tree. The treeMap class maintains
the natural order, the elements being sorted in the ascending
order. This class is similar to the HashMap class except that
it is ordered and the hashmap isn’t. Additionally treeMap
is not synchronized and hence should be avoided in case of
multithreaded applications. The treeMap permits null values
for a corresponding key but does not permit duplicate keys.
If the same key is added again with a new value, its value is
updated.
A simple example demonstrating the use of this class is shown below:
The Collections Framework 251

The output is:

ITERATOR
An iterator helps you go through each element in a collection. All the
classes in the collections framework implement the Iterator Interface.
The Iterator helps you navigate your collection, retrieve elements, delete
elements and perform operations on all the elements of the collection.
Each class in the collections framework has an Iterator() method that
returns an iterator object, with the help of which we can iterate over the
elements of the collection. The iterator has the following methods that
help in iteration:
next(): returns the succeeding element in the collection
hasNext(): this returns true if the collection has another element
252 Object Oriented Programming with Java

set(): this assigns the value of the object to the element.


previous(): returns the previous element in the collection
hasPrevious(): this returns true if at the current point, the collec-
tion has a previous element
Additionally, it has common methods such as add() and remove() that
are used to add and remove objects from the collection object.
An example depicting the use of the iterator is shown below:

Although the above example uses an ArrayList and iterates over it


using an iterator, this is applicable to all the classes in the collections
framework that implement the interface Iterator.
The output generated the class IteratorExample is as follows:
The Collections Framework 253

ListIterator
This is just like the iterator interface but it can iterate over the elements
of a collection in both directions: forward and backward.
A simple example using a ListIterator is shown below:
254 Object Oriented Programming with Java

In addition to the iterator, the Map interface has some methods that
help to iterate over each key-value set. This iteration is done with the
help of the entrySet() method as shown in the example below:

As we can see, each complete entry comprising of key and value pairs
can be retrieved together. The entrySet() returns a set which contains the
key and value pair.
The output is as follows:
The Collections Framework 255
The entry set can also be used in combination with the Iterator. This
is shown below:

The output generated is the same as the output from the previous
example.

LEGACY COLLECTION CLASSES


Before the collections framework was introduced in Java version 2,
there existed some classes and interfaces that provided support of storing
objects similar to those defined in the framework now. They had behavior
similar to those of the new collection classes. When the collections
framework was introduced, these existing classes were reengineered so
that they support the new framework. Hence, these classes are named
or called as legacy classes. For these legacy classes, before the Iterator
interface came into place, the Enumeration interface was provided to list
through the elements of these classes.
The legacy classes are as follows:
• Vector
• Properties
256 Object Oriented Programming with Java

• Stack
• Dictionary
• HashTable
Some of these classes such as Vector, Stack and HashTable have
already been discussed. The Properties and Dictionary class will not be
discussed in the scope of this book.
Enumeration: This is another interface that helps iterate over
collection objects. Similar to the hasNext() method of the iterator, it has
a hasMoreElements() method that checks if elements are present in the
collection. This is used by Legacy classes such as Vector and Properties
class.
A simple example using enumeration for iteration is shown below:

The output obtained is as follows:


The Collections Framework 257

COLLECTIONS CLASS
This class of consists exclusively static methods that operate on or return
collections (Collins, 2011). Some useful methods of this class are as
follows:
Table 14: Methods of the Collections class

Method Description
emptyList() Returns an empty list that is unmodifiable
emptyMap() Returns an empty Map that is unmodifiable
emptySet() Returns an empty Set that is unmodifiable
synchronizedList() Returns a synchronized/thread-safe List
synchronizedMap() Returns a synchronized/thread-safe Map
synchronizedSet() Returns a synchronized/thread-safe Set
Sort(List<T> l) Sorts the list in ascending order of its ele-
ments
synchronizedSortedList() Returns a synchronized/thread-safe and
sorted List
synchronizedSortedMap() Returns a synchronized/thread-safe and
sorted Map
synchronizedSortedSet() Returns a synchronized/thread-safe and
sorted Set
replaceAll(List<T> T oldVal, T Replaces all occurrences of a value in one list
newVal) by another
T max(Collection<T> c) Returns the maximum element of a collection
based on natural ordering
T min(Collection<T> c) Returns the minimum element of a collection
based on natural ordering
T binarySearch(List<T> l, T Performs a binary search on a list for the
key) given key
shuffle(List<T> l) Shuffles the elements of the list in a random
order
fill(List<T> l, T obj) Fills the list with specified objects
258 Object Oriented Programming with Java

The uses of some of these methods have been demonstrated by the


following class:

The above class shows the use of the max(),min(), sort() and
unmodifableList() methods.
The output is:

As seen clearly from the above output, when we try to insert an


element into the newly returned unmodifiable list, we get an exception.
The Collections Framework 259
Another example that makes use of some the methods of this class
are as follows:

The output of the program CollectionsExample2 is as follows:

COMPARABLE INTERFACE
This is an interface provided by java in the [Link] package and is used
to order/sort the objects of a class defined by the user. It is made up of a
260 Object Oriented Programming with Java

single method namely compareTo(Object obj) that is used to compare the


object invoking this method (current object) and the object provided as a
parameter to the method.
The objects can be sorted based on a single element only. This means
that if a class has three properties such as Age, Id and phoneNumber,
only one of these three attributes can be used to sort the objects.
This method can be used to order elements of the following types:
Strings, Wrapper Classes and objects of User-Defined classes.
The String class and the Wrapper classes that exist for primitive data
types implement the comparable interface by default.
The Collections Framework 261
In case of user defined classes, this interface needs to be implemented.
To implement the compareTo() method, it is necessary that the class
implements the comparable interface and overrides the compareTo()
method.
In addition to these classes, some classes in the CollectionsFramework
such as List, TreeMap etc implement this interface by default. Hence, if the
sort() method is called on them, the default compareTo() implementation
method of this interface is called. In natural conditions, this method sort
the elements in their natural order.
A simple example demonstrating the use of the comparable interface
is shown below:
The output generated is as follows:

COMPARATOR INTERFACE
This is another interface found in the [Link] package that helps order
data of objects of user-defined classes. It is made up of a single method
called as int compare(Object obj1, Object obj2).
It compares and orderes the objects provided as method arguments
on the basis of 1 or more attributes/properties of the class. This means
that different comparators based on different attributes of the object can
be used to sort the collection.
This method returns a negative/less than zero value if the value of the
first parameter is less than the second, 0 if they are equal and a positive
integer/greater than zero value if the value of the first parameter is greater
than the value of the second parameter.
262 Object Oriented Programming with Java

To implement the compare() method, the class must implement the


Comparator interface and provide an implementation for the compare
method.
A simple example explaining the use of the compare() method is
shown below:

As we can see, this class implements the comparator as an anonymous


class and compares the objects on the basis of age.
The output generated is as follows:
The Collections Framework 263

The output clearly shows that the list has been sorted on the basis of
age. A comparator can defined in another class separately. Additionally
the logic of the compare method can be varied which is shown in the
example below.
264 Object Oriented Programming with Java

As shown in the above example, a new class that implements the


comparator interface has been added to the class. This class implements
the compare method in a slightly different way than the previous example.
But the base logic is the same. If the objects under consideration are equal
return 0, if the first is greater than the second, return a positive value and
if the second is greater than the first return a negative value. The output
generated is as follows:

As we can notice from the above output, the list of objects has been
sorted on the basis of the parameter ‘Id’.
Another way to implement the comparator method is by calling the
compareTo() method on the parameter to be compared. This can be done
only on objects of the Wrapper classes and Strings.
The same class with the changed method is shown below:
The Collections Framework 265

This returns the same output as shown in previously.


CHAPTER

13
GENERICS IN JAVA

In java, generics are a way to generalize classes, interfaces and methods.


For example, when we write a method to add two numbers, we need to
specify the type such as integer, double, float etc. But, what if we can
write a generic method that works on all data types? This functionality
simplifies the programming efforts significantly.

DEFINING GENERIC TYPES


A particular type can be made generic with the use of delimiters ‘<>’
with an enclosing parameter.
Consider the following simple class:
public class Addition {
}
This class can be converted into a generic class as follows:
public class Addition<T> {
}
268 Object Oriented Programming with Java

As seen from the class Addition, all occurrences of any ‘type’ have
been replaced by the parameter ‘T’. It is called a Type variable and it can
hold any non-primitive object type such as String, Integer, Array types,
interfaces, classes and so on.
As per the conventions of the java programming language, the type
variable is usually an uppercase letter. Some frequently used parameter
types are as follows:

Table 15: Parameter Types in generics

Parameter Name Description


T Type
K Key
N Number
V Value
E Element
The type <E> is largely used by the Collections framework that was
discussed in Chapter 12.
The above generic class Addition can be instantiated as follows:

Generic Methods: Like generic classes, we can have generic


methods as well. The method parameters take one of the parameters as
their input. This is shown by the class below:
Generics in Java 269

The class Addition has been modified to include a field, a setter and
a getter that are generic.
As this class is generic, it can be instantiated in several ways with
different types as shown by the class Addition.
The output generated is as follows:

If you want to display elements of a group of objects, you can simply


write a generic method that can display the elements of all classes. An
example using the parameter E for elements is shown blow:
270 Object Oriented Programming with Java

The output is as follows:

Generic methods can be used on objects from the collections


framework as well. To display elements a collection, a method similar to
the displayElements() method can be used. An example that demonstrates
the use of generics for displaying the elements of a class belonging to the
collections framework is shown below:
Generics in Java 271

The output generated is as follows:


272 Object Oriented Programming with Java

BOUNDED TYPE PARAMETERS


As a programmer, you may face situations where you would want to have
restrictions on the types that can be used as parameters. For instance, you
may want to limit the type to a descendant of the class Number. All the
wrapper classes descend from this class.
Bounded parameters are specified by the use of ‘extends’ keyword
within the <> delimiters as shown below:
public class Addition<T extends Number> {
}
The declaration ‘T extends number’ specifies that this class can
accept types that descend from the Number class. This is called as the
upper bound of the parameter.
Similarly, a method can be declared to have bounded parameters as
follows:

The output generated is as follows:


Generics in Java 273
In the above class, if we try to pass a type that is not a descendant of
the Number class, we get a compile time error as shown below:

Another thing to note is that a type parameter can have multiple


bounds. The syntax is as follows:
T extends A & B
A simple example is:
class A{}
interface B{}
public class GenericsExample4<T extends A & B> {
}
Note that the 2nd parameter always has to be an interface as a class
cannot extend more than one class.
If one the parameter is a class then it should be mentioned first.
The following declaration is not valid and will give a compile time
error.
public class GenericsExample4<T extends B & A> {
}
274 Object Oriented Programming with Java

WILDCARDS
In case of generics, we use the symbol ‘?’ (question mark) which stands
for a wildcard element. It is used to represent a type that is unknown.
This can be used in many scenarios such as in case of fields, variables
etc.
There exist 3 types of wildcards in Java: Upper, Lower and Unbounded
wildcards

Upper Bounded Wildcards


Wildcards with an upper bound can be used to add restrictions to your
variables. Such wildcards are analogous to the bounded type parameters
as explained in the previous section.
Upper Bounded Wildcards are declared as follows:
Class className <? extends UpperBound>
So, if we want to declare a method or a class that accepts all
descendants of the Number class, we would declare an upper bounded
wildcard as follows:
class MyClass <? Extends Number> {}
or
public void method1(List<? Extends Number> list1) {}
It is crucial to note that there is a difference between List<Number>
and List<? Extends Number>.
The former matches only a list of type Number whereas the latter
matches a list of Numbers or any of its child classes.
A simple example demonstrating the use of upper bounded wildcards
is shown below:
Generics in Java 275

The output is as follows:


276 Object Oriented Programming with Java

Lower Bounder Wildcards


A lower bounded wildcard is the exact opposite of an upper bounded
wildcard. A wildcard is said to be lower bounded if we restrict the lower
bound of the type parameter to a specific type or a super class/super type
of that type.
The syntax is as follows:
Class className <? Super lowerBound> or
To declare a class that accepts Integer values and all values that
belong to the superclass of Integer we add a lower bounded parameter as
follows:

class MyClass <? super Number> {}


or
public void method1(List<? super Number> list1) {}
A simple example demonstrating the use of lower bounded wildcards
is as follows:
Generics in Java 277
The output generated is as follows:

A key point to note is that we can specify either an upper bounded


wildcard or a lower bounded wildcard but not both.

Unbounded Wildcards
This wildcard is specified just by the question mark (?) within the
delimiter <>. It specifies that the type of the parameter is unknown. An
example is List<?>. This wildcard is used when the method implementing
an unbounded wildcard can be implemented by using the functions
provided by the object class. Secondly, this unbounded wildcard is used
when the class/method doesn’t depend on the the type Parameter T. A
wildcard should never be used as a type argument for a generic class
or as an argument passed during instantiation of a generic class. This
is because if any object is allowed to pass, there may arise many issues
related to the implementation.
Consider a method that displays a list of objects:
public static void displayList(List<object> list) {
for (Object object : list)
[Link](object);
}
What if we want to display a list of Strings or a list of Doubles or a
list of Integers using the same method? The above method doesn’t allow
this as these classes aren’t sub types of the object class.
Unbounded Wildcards can be used in this case. The above method
can be re-written as follows:
278 Object Oriented Programming with Java

public static void displayList(List<?> list) {


for (Object object : list)
[Link](object);
}
A simple example demonstrating the use of unbounded wildcards is
shown below:

The output is as follows:


Generics in Java 279

Another significant point to remember is that one shouldn’t get


confused between generic declarations such as List<Number> and List<?
extends Number>
When we consider a method such as void method1(MyClass<Number>
list) {} , we can see that it accepts a list of MyClass objects with an
argument Number. This means that we can pass a Number value as
follows:
MyClass<Number>
But we are not allowed to pass the following parameters:
MyClass<Double>
MyClass<Float>
MyClass<Integer>
Why, one may ask. This is because a list of MyClass<Double>,
MyClass<Float> is not a subtype of Number.
The relationship is shown as follows:

The integer class is a subclass of the type Number and so it the class
Double.
280 Object Oriented Programming with Java

But, MyClass<Integer>, a list of MyClass objects that accept an


Integer is not a subclass of MyClass<Number> which is a list of MyClass
objects that accept a Number parameter.
This because if we have two concrete classes A and B, and B extends
A; this has no relation to the following declarations MyClass<A> and
MyClass<B>.
So, if we want to have a relationship between the declarations
MyClass<A> and MyClass<B> we make use of the wildcard with an
upper or lower bound.
CHAPTER

14
REGULAR EXPRESSIONS

Regular expressions or Regex is a sequence of characters that depict or


represent a string/pattern to be searched within some text. In java, there
is an api called regex api that provides the pattern matching functionality
for search and enables easy manipulation of strings. This is provided by
the [Link] package.
It is made up of the following 3 classes:
1. Matcher class
2. Pattern class
3. PatternSyntaxException class
It additionally defines a MatchResult interface that is implemented
by the Matcher class.
Objects of the Pattern class represent a regular expression. This is the
pattern that we look for in a string. This class does not provide constructors
and hence to create and use a pattern one of its static methods needs to
invoked. These methods return a Pattern object. This will become clear
once we see a few examples.
282 Object Oriented Programming with Java

Some methods of the Pattern class are as follows:


• static Pattern compile(String regex): This method takes a pattern
as an input, compiles it and returns a pattern object.
• Matcher matcher(CharSequence input): This method takes a se-
quence of charcters as input and matches the input against a pat-
tern.
• static boolean matches(String regex, CharSequence input): This
method takes the regex pattern and the string to test it against
as inputs. It serves 2 purposes: compilation of the pattern and
matching the input against the pattern.
• String[] split(CharSequence input): This method is similar to
split method of Object class. This method splits the input string
into string arrays.
• String pattern(): this method returns the pattern
Objects of the matcher class perform the matching operations on
strings. It is an engine that interprets the pattern object and matches it
against the given string. Similar to the pattern class, no public constructors
have been provided. The class Matcher implements a matcher() method
(MatchResult Interface) that takes a string as input (the string against
which the pattern is matched) and this method must be invoked by a
pattern object.
Some important methods of the Matcher class are as follows:
• boolean matches(): This method checks whether the given input
matches the pattern
• Boolean find(): this method looks for successive expression/part
of the string that matches the pattern
• boolean find(int start): This method looks for the successive ex-
pression in the string that matches the pattern from the given start
index number
• String group(): This method returns the matched subsequence
based on the mattern
Regular Expressions 283
• int start(): This method returns the start index/first index of the
subsequence that matches
• int end(): This method returns the start last index of the subse-
quence that matches
• int groupCount(): This method returns the count of total number
of substrings matched against the pattern
This class has some replacement methods that manipulate strings
and help in replacement operations that will be discussed further in this
chapter.
A PatternSyntaxException is the exception thrown when there is
some syntax error in the pattern provided. It is an unchecked exception
and is thrown in such cases.
Some methods of this class are as follows:
• String getPattern(): This method returns the pattern that throws
the exception
• String getMessage(): This message gives the description of the
syntax error and its index, the pattern which caused the error and
a visual indicator of the index where the error is present
• int getIndex(): returns the index of the error
• String getDescription(): returns the description of the syntax error

EXAMPLES OF REGULAR EXPRESSIONS IN JAVA


Example1: This example shows a very simple pattern matching.
284 Object Oriented Programming with Java

In the above class we check if the input string contains the letters ab
with 1 character preceding and 0 or more characters succeeding them.
The dot (.) operator here represents one character.
The output is as follows:

Example 2: This example shows different ways to use the Pattern and
Matcher classes.
Regular Expressions 285

This example checks if the input string contains the substring ‘ab’
that has one character before the letters ‘ab’ and ends with ab. The output
is as follows:

Example 3: Dot operator


286 Object Oriented Programming with Java

The output is as follows:

CHARACTER CLASSES IN PATTERN CLASS


The pattern class consists of several regular expression constructs that
can be used. The following table represents some of these patterns. The
first column represents the construct and the second column describes
under which conditions it will match the input.

Table 16: Character classes ([Link], 2017)

Construct Description
[abc] a, b, or c (simple class)
Regular Expressions 287

[^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)
[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)
The above constructs can be better understood with the following
example shown in RegexExample4.
288 Object Oriented Programming with Java

The output is as follows:

JAVA REGEX QUANTIFIERS


In java, the regex package allows you to provide quantifiers that specify
the number of occurrences of a character that you want to match against.
The following table describes the quantifiers and their meaning:
The quantifiers state the number of occurrences of a character.

Table 17: Quantifiers

Quantifier Description
X? X must occur once or not at all
X+ X must occur once or more times
X* X must occur 0 or more times
X{n} X must occur exactly n times
X{n,} X must occur n or more times
X{y,z} X must occur at least y times but less than
z times
The following class RegexExample5 demonstrates the use of these
quantifiers.
Regular Expressions 289

The output is as follows:


290 Object Oriented Programming with Java

PREDEFINED CHARACTER CLASSES


Similar to the character class, the java regex package provides us with
some predefined character classes that offer small codes for expressions
that are used on a regular basis such as words, digits etc.
These constructs are defined in the following Table:

Table 18: Predefined character classes ([Link], 2017)

Character Description
Construct
\d Matches a range of digits [0-9]
\D Doesn’t match any digits [^0-9]
\s Matches whitespace character [\t\n\x0B\f\r]
\S Doesn’t match any whitespace characters [^\s]
\w Matches any word [a-zA-Z_0-9]
\W Doesn’t match any word character [^\w]
. Matches Any character (may/may not match line terminators)
These constructs have been explained by the class RegexExample6
as shown below:
Regular Expressions 291

The output generated by the program is as follows:


292 Object Oriented Programming with Java

REGEX BOUNDARY MATCHERS


The java regex package provides us with boundary matchers that help
determine where exactly the match occurred in the given input string.
These matches help in making the matching operation extremely precise
as the precise location of the match can be determined by use of boundary
matchers.
The regex package is composed of the following boundary matchers:
Table 19: Boundary Constructs ([Link], 2017)

Boundary Con- Description


struct
^ Matches a word the beginning of the input line
$ Matches a word at the end of the input line
\b Matches a word boundary
\B Matches a non-word boundary
\A Matches the beginning of the input line
\G Matches after the end of the previous match
\z Matches the end of the input
Regular Expressions 293

\Z Matches the end of the input line except for the final terminator
(if any present)

The boundary constructs have been explained by the following


examples.
Example1: ^and $

The output generated by the class JavaRegexExample7 is as follows:

Example 2: \b
294 Object Oriented Programming with Java

The output of the class JavaRegexExample8 generates is as follows:

Example3: \B or non-word boundary


This construct helps you match a non-word boundary as well. For
instance, if you want to find the word ‘you’ in longer words such as
‘yourself’ this construct can be used. In this case the constructs \Byou or
the construct you\B is is used separated by an or as the word ’you’ can
occur in the start or the end of another word.
Regular Expressions 295

The output generated is as follows:

Example 4: \G
This construct matches the pattern only if found at the end of the previous
match.
296 Object Oriented Programming with Java

The output generates is:

As we can clearly see from the output, only the first two occurrences
are matched since they follow one another.

Example 5: \A
This construct is used to match the beginning of a line.

The output generated is as follows:

This construct is similar to the ^ construct we studied earlier. It serves


as an alternative.
Example 6: \z or \Z
This construct is used to match the end of the line. It can be used to
match a pattern at the end of the line as well.
Regular Expressions 297

As we see in the output shown below, the pattern is found at the end.

This construct is similar to the $ construct that we studied earlier.

GROUPS IN REGEX
In java, using the regex package, we have the possibility to group multiple
characters together and check for matches against a group of characters
as well. The group construct is used to group characters together. As a
result of using groups a collection of characters can be treated as a single
unit (Gosling, 2000).

Defining Groups
As simple example is the following pattern: (ab).
Every group that we provide in the pattern has a group number.
The numbering of the groups starts at 1. The group starts from 1 as the
group 0 refers to complete regular expression and is not counted as an
occurrence. An important method: the groupCount() method in the class
298 Object Oriented Programming with Java

Matcher returns the count (number of groups matching the pattern).


For example, if we want to match a group of digits or a set of characters
in a particular order we can write them with the help of groups.
A simple example is shown below:

In the above class, we match only digits as shown in the output below:

If we want to match a particular group of digits followed by digits we


use multiple groups.
This is shown in the following example:
Regular Expressions 299

The output is as follows:

As we can see from the output above, the group (1) matches the first
pattern and gives us 123.
The group(2) matches the second pattern and gives us whitespace.
The group(3) matches the 3rd pattern and gives us 1234.
Another complex example with characters and digits is shown in the
class RegexExample15.
300 Object Oriented Programming with Java

The output is:

As we can notice from the output, the example makes use of 3 groups,
1 of which is a nested group.

Backreferences in Groups
While using regex, an important concept that is used is backreferencing.
A backreference can be specified using a backslash. Its main purpose is
to avoid repeating expressions or patterns. A part of the group is saved in
memory and can be recalled with the help of backreferencing. A backslash
followed by the number/index of the group is used. For instance consider
the expression (\d\d) which defines two digits that match. Now, if we
want to match a string with the same group of digits repeating again, we
Regular Expressions 301
can write the regex pattern as (\d\d)\1. This means that match a group of
2 digits that has been repeated once.
This is shown by the following class:

The output generated by the class JavaRegaxExample is as follows:

For groups that are nested, the concept of backreferencing works in


the exact same way as shown above.

Regex Replacement Methods


The pattern class has some useful replacement methods, similar to the
String class as follows:
String replaceAll (String s) – replaces all occurrences of a string
similar to the replacaAll method of String class
String replaceFirst (String s) – replaces first occurrence of a string
similar to the replaceFirst() method of String class
302 Object Oriented Programming with Java

StringBuffer appendTail (StringBuffer sb) – appends the tail of the


input at the end of the input string after the occurrences have been found.
String appendReplcement (StringBuffer sb, String replacement) –
Replaces the string with a replacement string like replaceAll() method
A simple example using replaceFirst and replaceAll methods is
shown below:

The output is as shown below:

The same example with the help of the appendTail and


appendReplcement method is shown below:
Regular Expressions 303

As we can see from the output in the above figure which is the
same one we got before, the appendReplacement method replaces all
occurrences of the pattern and the appendTail method appends the rest of
the input string to the StringBuffer.
CHAPTER

15
GRAPHICAL USER INTERFACE (GUI)

Java provides us with a platform for developing applications with a rich


graphical User Interface (GUI) called as AWT which stands for Abstract
Window Tooklit (Chan and Lee, 1998). AWT is an api that provides us
with various components to create applications with a User interface.
The components provided the AWT api are platform dependent which
means that the look and feel of the various components vary based on
the view provided by the underlying OS. Hence, these components are
called as heavyweight components as they make use of resources of the
operating system.
AWT provides us with several ui components such as Window, Button,
Label etc. that are native to the OS, layout and managers to manage the
layout of the ui, graphics tools and event handling mechanisms. These
components are provided by the [Link] package.
The hierarchy of the AWT package is as shown below:
306 Object Oriented Programming with Java

COMPONENTS OF AWT
Each one of the components in the AWT hierarchy has been described
below.
Component: This is the superclass of all the awt components
which is abstract. All the gui controls and components inherit from this
component. All the ui controls are built on top of this base class.
Container: This is a component that is capable of holding other
components such as button, labels and so on. Other types of containers
that are capable of holding other components are: Window, Dialog, Panel
and Frame. As visible in the hierarchy diagram, Window extends from
the Container class, Frame and dialog inherit from the Window class
whereas Panel inherits directly from the Container class.
We shall now see these containers.
Graphical User Interface (GUI) 307
Window: Window is a component that has no borders and menu
bars. This component must be used with a Frame or a dialog class which
are its subclasses or another window to create and display a window.
Frame: This component has a title and menu bar and other components
can be added to it. It is made up of a maximize and minimize button.
Panel: Panel is a component like the frame but it doesn’t have a title
and menu bar. It is used for holding other components such as buttons,
label, text fields and areas and so on.
Applet: It is a high level container for a component called as applet
itself. It is a type of program that runs a java program within a browser.
Dialog: This component is a top level window that is made up of a
border and title, inheriting from the window class. It is mainly used to
take an input from the user.
The commonly used components are described in the following table:
Table 20: AWT components

Component Description
Button Class that creates a button with a label
Label Class that helps place a text label
Checkbox Class that helps add a component with two states : true/false
List Class that helps create a scrollable list
TextField Class that allows editing a single line text
TextArea Class that allows editing a text of multiple lines
ScrollBar Class that permits adding a scrollbar to scroll through a range of
inputs/values
Choice Class that provides a drop down menu with choices

Some important methods of the component class that are used very
frequently are the following:
public void setSize(int width, int height): set/fix size of the container
component
public void add(Component c): Add a component on the component
invoking this method
public void setBackground(Color c): Set the given color as the background
of the component
public void setVisible(boolean status) : Set the visibility of the
308 Object Oriented Programming with Java

component. The visibility is false by default.


public void setLayout(LayoutManager m): Set the layout for the
component using the Layout Manager

LAYOUT MANAGER
In AWT, it is an object that is in charge of controlling the position of the
components within a container and the size of the container. The various
components inside a window or a frame can be arranged in a particular
way with the help of a layout. For example, a simple Frame may consist
of several buttons and labels. A layout Manager helps in better organizing
these components by determining where they will be placed within the
frame.
The AWT package in Java has the following layouts:
FlowLayout: This layout is used to arrange the component in a single
row and if one row is not enough a new row is started.

BorderLayout: This layout has 5 regions namely north, south,


center, east and west. Each region can have only one component. So this
layout must be used if you have limited number of components.
Visually, the border layout looks as shown below:
Graphical User Interface (GUI) 309

GridLayout: This layout is used to arrange the components in the


form of a grid of rows and columns. All the components have equal size.

GridBagLayout: This layout is an advanced and flexible version


of the GridLayout. It places the components in a grid of cells like
GridLayout, but allows a component to occupy several cells. The height
and/or width of a rows and/or column can be adjusted.
310 Object Oriented Programming with Java

CardLayout: This layout makes use of a container in such a way


that only one sub-component is visible at a time. Each component is
treated as a card and based on the selected option; different components
are shown to the user.

EXAMPLES
In java, the graphical UI can be created using awt via the Frame class.
The basic necessity for creation of a graphical component is a frame. One
approach is to inherit from the Frame class (using the extends keyword)
and the second approach is to create an instance of the Frame class
directly in your class. Both these approaches have been shown below:
Example 1: This example shows a simple frame with a button, label,
text field, checkbox, title and a list.
Graphical User Interface (GUI) 311

The output is as follows:


312 Object Oriented Programming with Java

As seen from the output in figure, the gui has been created with a title,
label, button, list, checkboxes and a text field.
Example 2: The second way of creating a frame is to create an
instance of the Frame class. This is done as follows:
Graphical User Interface (GUI) 313
The output is as follows:

Example 3: Applets
Applets are a type of java programs that can be run in the browser. A
simple Java applet is shown below:

Applets do not posess a main method, but to execute an applet we


need to override the paint method from the Graphics class. As an applet
is a type of a program, it needs to be executed as an applet. This option
is available when you right click anywhere on the source file as follows:

The output generated on execution is the following:


314 Object Oriented Programming with Java

The above applet can be run in a browser as follows:


1. Create an html file with the applet code in the same directory
as the class file [Link]. This is shown below:

2. Make sure the java is enabled on your browser and load the
html file on the browser. For example, if the path of the file
is C:/workspace/[Link] then the url to be typed in the
browser should be:
[Link]
The browser loads the applet and displays the same output as shown
previously, but inside a browser.

EVENT HANDLING IN AWT


An event in awt is described as the change in the state of an object. When
a user interacts with the user interface, events are generated based on
the user actions. A simple example is the clicking of a button. We may
want something to happen on the click of a button such as present the
Graphical User Interface (GUI) 315
user with a YES/NO dialog, or simply give an alert to the user or update
the value of another field such as a text field and so on. There are a lot
of possibilities. Such events are handled by the AWT framework with
the help of Event Listeners. Each event has two components namely a
source and listener. The source is the object that invoked the event and
the listener is the component that provides a response for the generated
event. AWT package has a wide range of event classes that help handling
of events such as WindowEvent, ContainerEvent, MouseEvent and do
on. The scope of this book does not describe all the AWT events. But a
few simple examples demonstrating event handling are provided below:
316 Object Oriented Programming with Java

As seen from the class AWTExample2, an event is registered on the


button which changes the message displayed in the text field. This is
shown from the output. On execution of the program, the frame with the
button and text field is displayed as follows:

When we click on the button, the text inside the text field is updated
as shown:

The next example shows the use of Event Listeners along with the
use of a dialog.
Similar to the previous example, in this example we use a button
performs an action when it is clicked. In class AWTExample3 shown
below, we create a simple frame along with a button and a text field. On
Graphical User Interface (GUI) 317
clicking the button, a new Dialog appears that takes input from the user.
This input is taken and the text field present is updated with this value.

The output generated is as follows:


318 Object Oriented Programming with Java

When we click on the button, a new dialog pops up.

We enter the data as follows:

On clicking the OK button, the previous screen is updated with the


value we entered as shown below:

JAVA SWING API


Java has provided us with an improved gui api called Swing. This was
developed to overcome the shortcomings of java AWT API and give more
advanced API’s to build GUI applications. This API is part of the Java
Foundation Classes (Oracle) and has the added functionality of providing
the ‘look and feel’ of the underlying OS. The swing components are built
on the AWT components and provide many additional components such
Graphical User Interface (GUI) 319
as panes, tables, trees and so on. Further, these components are lightweight
which serves as a great advantage in terms of large applications is and
they support the pluggable look and feel as well. This means that the
application using these components can have a look and feel that is
different from that of its underlying platform. Hence, this API is preferred
over the traditional AWT api.
The hierarchy of the components in swing is the same as that of AWT
as this api is built upon the existing AWT API. All the components are
derived from the AWT components. All the components are derived from
a parent class called as JComponent class which is built upon the existing
AWT containers and is a child class of the Component class. The only
difference is that instead of the abstract superclass Component, all the
components such as Button, List etc. extend the class JComponent. For
every AWT component there is an equivalent swing component which has
the prefix ‘J’. All the components are named with a label J before them
such as Button class is now JButton. Additionally many miscellaneous
components such as trees, color choosers, panes, sliders, toolbars, image
buttons, radio buttons, etc. have been provided.
The hierarchy is as shown below:
320 Object Oriented Programming with Java

Let us now look at a few examples using the Swing components.


Example 1: A simple user interface with a button and a text field
using swing components

The output generated is as follows:

Example 2: Menus and Submenus in swing


Graphical User Interface (GUI) 321

The above class creates a frame containing a menu and a submenu as


shown by the output below:
322 Object Oriented Programming with Java

Example 3: Event Handling in Swing


Graphical User Interface (GUI) 323
The output generated is as follows:

On clicking the buton, the text field is updated.

The class SwingExample4 gives us the same output as given by the


AWTExample2. This is because AWT and Swing both use the same
event handler.
Example 4: Event Handling in Swing using a yes/no dialog option
324 Object Oriented Programming with Java

On execution, the following window appears:

When the user clicks on it, a confirmation dialog is displayed.

Based on the choice of the user, the flow of the program can be
decided.
The AWT package is a large package and hence it has not been
covered in detail in this book. For detailed information about the AWT
API, consult the book YYYY. This book does not cover the Swing API
but the book x can be referred if you want to look into the details.
CHAPTER

16
MULTITHREADING

As explained in chapter 1, multithreading is supported by Java. In java, a


program can be logically divided in parts called as threads and each part
can be executed simultaneously.

THREADS
A thread is simply a light weight process that runs parallely with other
threads. They work independently of one another as each thread executes
a different part of the application, but share memory. If some error occurs
in one thread, the working of the other threads is not affected. All threads
that belong to a single process share the common memory. This process of
execution of many threads at the same time is defined as multithreading.
Multithreading is a simple solution to achieve multi-tasking the program
by executing parts of it simultaneously.
A very simple example of multithreading is the GUI that we discussed
in chapter 15. All the GUI packages make use of threads to handle and
manage various event generated by the application.
326 Object Oriented Programming with Java

This is a very interesting feature provided by Java that helps


applications run faster and save time. By making threads run or work
on different parts of the applications, the utilization of the CPU is done
to the maximum. In a typical program there exist some parts that are
independent of one another and hence can be executed with the help of
threads that share a common memory space. This helps reduce the idle
time of the CPU and use it more efficiently which is a boon for large
scale applications that are made up of multiple servers and processors. In
such case the processors’ complete capacity can be utilized by executing
applications with many threads.

THREAD LIFE CYCLE


A thread can be in different states or stages during its lifetime. A thread’s
life is controlled and managed by the JVM. The states of a thread are as
follows:
• New: A thread starts it life in this state. A thread in this has
been created but not started yet.
• Runnable: Once a thread is created it becomes a runnable
thread. This means that it is a thread that is executing/running.
• Waiting: A thread in this state is waiting for another thread to
complete its task. A thread can exit from this state only when
another thread signals this thread to start again.
• Timed_Waiting: A thread in this state waits for another thread
to complete its task for a specified period of time.
• Blocked: A thread in this state is blocked for the lock of the
monitor.
• Terminated: A thread in this state is dead and has exited.
At any point of time, a thread can have only 1 state. The lifecycle of
a thread is shown by the figure below:
Multithreading 327

Once the thread is created, it is in the New state. On invoking the


start() method on it, it moves to the runnable state. This new thread has
not yet been picked up by the system scheduler to start running. The
thread scheduler is a component of the JVM and it decides which thread
should be chosen. Once it is picked up it goes into the running state
and performs its task. This is done by the run() method. Once its task is
done, it dies a natural death and exits. But, if during its execution if the
sleep() or wait() is invoked on it, or if it is waiting for the I/O to be free.
In these cases it goes into the waiting state. Once it is in this state, it can
be revived again with the call of notify() that wakes up threads in sleep
mode or by the timed wait duration elapsing or by the I/O operation that
was blocking it being terminated. We shall see the working of threads in
the upcoming section.

THREAD CREATION
In java, the thread class is the class that creates and manages threads.
In java, we have two ways to create threads. The first way is to inherit/
extend the Thread class. The second way is to implement the runnable
interface. We shall now take a look at both the ways to create them.
• Extending the Thread class: By subclassing the Thread class,
we inherit its methods and hence its behavior. This is depicted
by the following example:
328 Object Oriented Programming with Java

The output generated is as follows:

Implementing the Runnable interface: Using this way, we implement


the method run() provided by the runnable interface. This is shown below:
Multithreading 329
As we notice from the class ThreadExample2, the runnable interface
has been implemented, the run() method has been overridden and the
instance object has been passed to the thread class object as a parameter
of its constructor. The output is as follows:

THE THREAD CLASS

Constructors
The thread class provides 8 constructors for creation of threads:

Table 21: Constructors of the Thread class

Constructor Description
Thread() creates a new thread object
Thread(String name) creates a new thread object with the given
name
Thread(Runnable r) creates a new thread object with a runnable
object (The class runnable/class that imple-
ments runnable)
Thread(Runnable r, String creates a new thread object with a runnable
name) object and gives it the specified name
Thread(ThreadGroup group, creates a new thread object belonging to the
Runnable r) specified thread group with a runnable object
Thread(ThreadGroup group, creates a new thread object belonging to the
String name) specified thread group and gives it the speci-
fied name
Thread(ThreadGroup group, creates a new thread object belonging to the
Runnable r, String name) specified thread group, with the specified
name and a runnable object
Thread(ThreadGroup group, creates a new thread object belonging to the
Runnable target, String name, specified thread group, with the specified
long stackSize) name and a runnable object and with the
specified stack size
330 Object Oriented Programming with Java

Methods of the Thread Class


The thread class provides many useful methods that help manipulate
threads. Some of them are as follows:

Table 22: Methods of the Thread class

Method Description
String getName() This method returns the name of the current thread
void setName(String name) This method sets the name of the Thread to the speci-
fied name
void run() This is the starting point of entry for a thread, called by
the start() method and executes the thread
void start() This method causes the thread to begin execution by
invoking the run() method
void sleep(long milliseconds) This method causes the thread to stop running for the
specified time
void getPriority() This method obtain the priority level of the thread
int setPriority(int priority) This method sets the priority of the thread to the speci-
fied priority
void join() This method waits for a thread to end its execution
boolean isAlive() This method returns true if the thread is still running
[Link] getState() This method returns the current state of the thread
boolean isDaemon() This method returns true if the current thread is a
daemon thread
void setDaemon(boolean b) This method sets the current thread to be a daemon
thread
void interrupt() interrupts the thread.
boolean isInterrupted() tests if the thread has been interrupted

EXAMPLES
Example 1: A simple example showing the use of some of the thread
methods and constructors
Multithreading 331

As we can see, three different constructors of the Thread class are used.
Methods of the thread class such getName(), getId(), getThreadGroup()
and getPriority() are used. The output generated is as follows:

Example 2: sleep() method


332 Object Oriented Programming with Java

The output generated is:

Example 3: Thread Priorities


In java, threads are assigned priorities which are represented by
a number between 1 and 10. The scheduler schedules the threads as
per their priority but this behaviour is dependent on the Jvm and the
scheduling mechanism it uses. By default, threads are given a priority
of 5. A total of 3 priorities are present which are constants of the thread
class. They are as follows:
- static int MIN_PRIORITY: this value is 1
Multithreading 333
• static int NORM_PRIORITY : this value is 5
• static int MAX_PRIORITY: this value is 10
The priorities of the threads are set to NORM_PRIORITY or 5 by
default if no priority has been assigned to it. But using the setPriority()
method, the priority of a thread can be changed. The use of thread
priorities has been explained in the class ThreadExample5.

As seen from the above example, three threads with three different
priorities have been created. If no priority has been set for a thread, it is
set to 5 by default as shown by the output below:
334 Object Oriented Programming with Java

An important/key point to note is that the start() method can be


invoked only once on a thread. If we invoke it more than once, the thread
reaches an illegal state and an IllegalStateException is thrown.
Example 4: Working of Threads using PipedReader and PipedWiter
Multithreading 335
The output is:

It should be noted that both ends (reader and writer) should not be
handled by a single thread else deadlock may occur. If any of the threads
stop working, the connection between the reader and writer or the pipe is
said to be broken.
Example 5: Working of Threads using PipedInputStream and
PipedOutputStream
336 Object Oriented Programming with Java

The output generated is as follows:

SYNCHRONISATION
By the use of threads, a type of asynchronicity is added to our programs.
When we use multiple threads there is a high chance that two threads
may be reading/writing the same data. This may cause the data to be in
inconsistent state and unusable. When many threads need to access the
same resource which they share, there should exist a way in which we can
assure/ensure that the resource is being accessed by just a single thread at
a particular point of time. This is done with the help of synchronisation
in Java.
We are familiar with the term ‘monitor’ in case of Operating Systems.
It is an importance concept in terms of synchronisation in operating
systems. In concurrent programming it is a functionality that allows
threads to be mutually exclusive with the ability to block/wait until some
condition is rendered true. Java supports the same concept to implement
synchronisation. In java, each object is bound to a monitor. To achieve
a lock on some data or an object in java, we make use of synchronized
blocks or synchronized methods.
When a thread enters such a block/method, no other thread can
access the data/object that has been synchronized. Any thread that wants
to obtain access to the synchronized block must wait until the previous
thread has exited the block.
When we want to synchronize an entire method we simply need to
put the keyword ‘synchronized’ in its declaration as follows:
public synchronized void method1() {
}
But, when we want to use objects of a class that was initially
designed without multithreading in mind, in a multithreaded context
we can do this using a synchronized block. For example, if we need a
Multithreading 337
particular operation to be synchronous, we can just add that statement in
a synchronous block. The syntax is as follows:
synchronized(object)
{
// statement/statements to be synchronized
}
To enable synchronized communication among threads, the thread
class is made up of methods wait(), notify() and notifyAll(). As explained
earlier, the wait() method causes the current thread to go into waiting
state. The thread is forced to release the lock on the monitor. The notify()
method on the other hand wakes up a single thread that is waiting on
the monitor. The choice of which thread to be woken up is random.
The notifyAll() method wakes up all the threads that are waiting for the
monitor.
These methods must be invoked within a synchronized context, i.e.
in a synchronized statement or synchronized method. This is because if a
method/statement doesn’t need to be synchronous/mutually exclusive to
thread access, there should be no need to communicate between different
threads and hence no need to use wait()/notify()/notifyAll(). This in turn
means that the method can be access by multiple threads simultaneously.
This use of synchronization is explained by the following example:
Consider a bank where a customer deposits and withdraws money. If his
balance is negative, he shouldn’t be allowed to withdraw money. In such
a scenario, the wait() method can be called. This method will restrict the
withdraw operation until the balance is positive. The notify() method can
be called when the balance is positive to let the user know that he can
now withdraw money.
338 Object Oriented Programming with Java

As seen from the class Bank, the methods withdraw() and deposit()
are synchronized and use wait() and notify() to manage thread
communication. The output is as follows:

Initially, when we try to withdraw an amount higher than what is


present, the thread is blocked until funds are deposited. Once, the funds
are deposited, the thread is now able perform its task.

Static and Synchronized


The ‘synchronized’ keyword can be applied in a static context too. This
can be done by using the synchronized keyword on the static method
(Gosling, 2000). The syntax is as follows:
public static synchronized method1() {}
Multithreading 339
When we use the ‘synchronized’ keyword on a static method, the
class is locked and not the object as in case of non-static synchronized
blocks/methods. Hence, static synchronization must be used carefully
as it could cause problems when mixed with non-static synchronization
blocks. This is because, if a static synchronized method is called by a
thread a class level lock is obtained. But, if another thread calls a non-
static method and tries to access another object, it will be unable to access
the object, as the entire class’s lock has been obtained by the previous
thread that invoke the static method.
So, the following declaration public static synchronized method1(){}
of a class named Test is equivalent to the following:
synchronized([Link]) {}
A simple method showing the use of static synchronization is shown
below:
340 Object Oriented Programming with Java

The output generated is:

As we can see from the output, the threads have been executed in a
mutually exclusive manner and hence the output is correct.

Static synchronization at class level


As mentioned above, the ‘synchronized’ keyword can be used at a
class level as well. The Counter class used in the above example can be
synchronized at class level as follows:

Note that the wait() method is used without any parameters. But,
a specific duration could be specified using the method void wait(long
milliseconds).

The join() method


As explained in table 22, this method waits for the current thread to
terminate. In other words, it stops all the executing threads until the
thread that invokes the join method completes its execution. The use of
the join() method is shown below:
Multithreading 341

The output generated is as follows:

As seen from the output, the first thread, thread-0 is executed first and
the rest of them are blocked until its execution is complete.
342 Object Oriented Programming with Java

Similar to the wait() method, the Thread class provides us with


another version of the join() method where we can invoke it on a thread
for a specified period of time. It is as follows:
public void join(long milliseconds)
The previous example can be modified to use this method as follows:

The rest of program remains the same. However, the output changes
slightly as thread1 executes for half a second and then the other threads
take over as shown below.

The methods wait() and join() throw the InterruptedException. This


exception is thrown when the thread is either waiting, sleeping or busy
being blocked and it is interrupted during this state. If we want to know if
a thread has been interrupted, the thread class provides us with a method
interrupted() to check this. This method can be used to examine if a
particular thread has been interrupted, and if it is the case, we can handle
this exception as follows:
Multithreading 343
if ([Link]())
throw new InterruptedException();
In java, the process of thread interruption works with the use of a
flag called as the interrupt status. If a thread is interrupted, this flag is set
Once the static interrupted() method is called, this flag is cleared.

DEADLOCK
Deadlock is a scenario where two or more threads are blocked endlessly,
waiting for one another (Goetz and Peierls, 2006). This happens when
many threads acquire locks on two or more objects in a different order.
This deadlock situation arises due to synchronization as it blocks the
current thread as it waits for the lock. But due to this behavior it may wait
forever. This is explained by the following example:
344 Object Oriented Programming with Java

As seen from the program DeadlockExample, thread1 locks the


object1 first while thread2 locks object2 first. After each thread acquires
one lock; on object1 and object2 respectively by thread1 and thread2,
they both wait indefinitely for the lock on the other object which results
in a deadlock.
The output is as follows:

One way to resolve a deadlock is to manage the order in which the


locks on different objects are obtained. If we change the order of the locks
in the above example, the deadlock is resolved. This is shown below:
Multithreading 345
The order of calling the locks on the objects has been changed. Now
thread2 is blocked until thread1 completes its task which is shown by the
output below:

As shown in the output, thread1 and thread2 both execute successfully


and complete their respective tasks.
In addition to deadlocks, multithreaded environments give rise to
another two less common issues namely starvation and livelock.
Starvation, as its name suggests is when a thread literally starves for
resources. This situation arises when a thread monopolizes a particular
resource for longer periods of time, resulting in other threads waiting on
the resource forever and ultimately being unable to move forward and
complete its task.
Livelock is a peculiar issue in case of multithreaded environments.
This issue occurs when two threads are responding to each other. This
means that each thread knows that it is blocking the other and hence
decides to take action and stops its work. But the other thread at the
same time, decides to take action and stop its work. So, neither thread
advances. Their states just keep changing constantly based on the other
thread.
A simple real world example is when 2 people meet in a tiny cramped
hallway, each person, being polite, moves to the side to let the other
one pass. But, they move to same side at the same time. Then they keep
moving from side to side without moving forward as they continuously
move to the same side at the same time which results them in being
indefinitely stuck.
346 Object Oriented Programming with Java

THREAD POOLS
Java 5 introduces the [Link] packages that include advanced
level concurrency features that are useful in case of multithreaded
applications. We shall take a look at two special features provided by this
package. They are as follows:

1. Executors
The basic multithreaded applications that we have seen so far create and
use threads within the program on a small scale. But, if we imagine a
large scale application that has over hundreds of threads, it seems more
practical to separate the management of threads from the rest of the
application logic. The [Link] package provides us with the
executor interfaces that helps manage threads. Executors are capable of
creating pools of threads so we do not need to create threads manually.
Three executor interfaces are provided as follows:

The Executor interface is the main interface and it has a sub-


interface named ExecutorService and a sub- sub interface named
ScheduledExecutorService.
The executor interface provides a method execute() to launch threads.
This method takes a runnable object as a parameter.
Multithreading 347
The ExecutorService interface is the advanced version of the Executor
interface offering many api’s and services.
The ScheduledExecutorService is also an advanced interface based
on the executor. It had additional methods that help schedule tasks
repeatedly at fixed intervals of time.
Detailed discussion of the Executor interfaces is beyond the scope
of this book. However, the book xyz by abc can be referred for further
reading.
Asimple example using the executor interface with the ExecutorService
is shown below:

The output of the above program is as follows:


348 Object Oriented Programming with Java

2. Atomic Variable
Although synchronization works well for multiple threads, in case of
very large scale applications with millions of threads competing for the
same resource, many threads are blocked and suspended to be resumed
later. In addition to the overhead of synchronization, the threads that
are waiting on the lock cannot do any other task until they finish their
previous task. To avoid these issues, the concurrent package in java 5 has
a functionality of Atomic variables. These variables have the property of
atomicity. An atomic action is when an event happens completely or not
at all.
The concurrent package support atomic actions on variables. It is like
a small yet powerful toolkit that supports thread safe operations without
use of locks and synchronized blocks/methods.
Some of the classes present in this toolkit are:
AtomicBoolean, AtomicInteger, AtomicLong, AtomicLongArray
etc.
All the classes in this toolkit have a get() and a set() method. The
reads and writes on objects of these classes are similar to the read/write
operations on volatile variables. This means that any write/set operation
always happens before a read/get operation. This is said to be ‘happens-
before’.
Consider a class with a variable i that we increment as follows:
Multithreading 349

A simple way to make the variable thread safe is synchronization. If


we make the method synchronized, it becomes thread safe.
As this is a simple class, synchronization works to make it thread
safe. But, for a complex class, we may be faced with the liveness issues
such as starvation, deadlock or livelock.
So to simplify things, we can use an AtomicInteger in place of an
Integer variable with having the need for synchronization. Hence, the
above class now changes as follows:
350 Object Oriented Programming with Java

CONCURENT COLLECTIONS
The [Link] packages made a few changes to the Collections
Framework as well. Some new classes and interfaces that support
concurrent access and are thread safe have been added to the Collections
Framework.
They are as follows:
1. Blocking Queue: This class inherits from the Queue Interface
defines a FIFO queue data structure that blocks the thread if you try to
add an element to an already full queue or if you try to pop an element
from an empty queue (Collins, 2011).
Some of its implementations: ArrayBlockingQueue, DelayQueue,
LinkedBlockingQueue, LinkedBlockingDeque , etc.
2. ConcurrentMap: This interface inherits from the Map interface
and provides atomic operations. In a concurrentMap implementation, the
remove or replace operations proceed only if a key is present and add a
key/value pair only if the new key to be added is not present in the Map.
Multithreading 351
This interface has 2 implementations: the class ConcurrentHashMap
and the interface ConcurrentNavigableMap
The ConcurrentHashMap is the concurrent/thread safe version of the
HashMap. It has the same properties, functionality and behavior as that
of a HashMap. The difference is that concurrent access is supported by
the ConcurrentHashMap.
ConcurrentNavigableMap is an interface that inherits from the
ConcurrentMap interface. This interface supports navigable Map
operations such as returning the closest match for a given search target.
A number of methods for locating elements have been provided by this
interface.
The implementation class of the ConcurrentNavigableMap is the
ConcurrentSkipListMap class. This class is a similar to a TreeMap. It
could be said that it is a concurrent version of a TreeMap. It supports
scalability, and sorts elements based on their natural order. Additionally,
it implements a SkipList that is concurrent/thread-safe.
A SkipList is a data structure similar to a search algorithm, that
performs very rapid search operations where a hierarchy of elements/
sequences are maintained and each subsequence of elements skips a few
elements. More information about skiplists can be found here.
CHAPTER

17
GARBAGE COLLECTION IN JAVA

In java, memory management is done with the help of an entity/module


called as the garbage collector. Unlike similar OOP programming
languages such as C or C++, the collector in java is automatic. The
garbage collection process includes periodical checking of the heap
memory, scanning them and checking which of the objects are in use and
which of them aren’t in use and then deleting the objects that are not used,
thus freeing up memory space. In order to check if an object is still in
use, the concept of referencing is used. If an object is in use it means that
some part of the program still maintains a reference to the object. This
means that the program still is making use of it and has a pointer linked
to it, which in turn means that memory is still allocated to the object. An
unreferenced object is one that is not used by any part of the program and
hence is unreferenced and thus its memory space must be freed as it is no
longer in use. Its memory in the heap can be reclaimed and assigned/re-
allocated to new objects that will be created by the program. This unused
object takes up space in the memory which can be reused in a better
way. This is done by the garbage collector automatically, unlike other
354 Object Oriented Programming with Java

programming languages, where the allocation-de-allocation-reallocation


process is manual and it is up to the user to manage memory. Leaving the
responsibility to the user makes the program vulnerable to memory leaks
and dangling pointers. All these issues have been eliminated in Java by
its automatic Garbage collector.

WORKING OF THE GARBAGE COLLECTOR


The working of the GC is a simple three-step process that is described as
follows:

Step 1: Marking
The very first and crucial step in the process of collection of unused
objects is called as marking. This step involves identifying which parts
of memory are in use and which of them are not being used anymore.
The garbage collector scans the memory and marks all the objects that
are referenced and unreferenced. As we can see in the figure below, all
objects are scanned and then marked based on their usage. As shown
below, the used objects are marked in red and the unused objects are
marked in green. This marking process can take a lot of time as all objects
need to be scanned.
Garbage collection in Java 355
Step 2: Normal Deletion
The second step is simple deletion of the objects that are no longer in
use. This action frees up space and now new objects can be allocated this
freed up space.

Step 3: Compacting the Memory fragments


In addition to deletion of unused and unreferenced objects, the java
garbage collector further makes use of algorithms/collectors that help
defragment or compact the memory to form contiguous blocks of used/
referenced objects. In this step, the objects that remain or the objects that
are still in use are compacted together. This makes it easier and faster to
allocate memory blocks.
This is shown in as follows.

THE CONCEPT OF GENERATIONS


In java, one of the advantages is that the developer is not exposed to
complexities of the memory allocation and release processes. The GC in
java is a tool that helps free up memory space. But, in doing so, it makes
certain assumptions with respect to the use of objects by the various
java applications. This is reflected in certain fine tuning parameters of
356 Object Oriented Programming with Java

the GC that are adjusted to achieve better performance. While marking


an object for garbage collection, the GC marks it if it isn’t referenced
anymore. The simplest way to mark any object is to iterate over all the
possible objects and find every object. But, this approach is a little time
consuming, especially in case of very large scale applications which is
made up of many objects. This slows down the marking process because
as more objects get allocated, the list keeps growing which results in the
increase in time taken to iterate over all the objects.
In order to remedy this problem, the JVM has a number of object
collection/memory recovery algorithms that are executed along with
the collection on the basis of ‘Generations’. Generational collection is
based on the hypothesis that most objects in a program live for a short
period of time. This conclusion was reached after empirical analysis of
allocation data over several java programs. This analysis was done to
find out ways and properties that help in minimizing the effort required
to reclaim unused or unreferenced objects. Hence, in java the unused
objects are classified into different generations based on the amount of
time that they exist.
A simple example of data that is short lived is shown below. The
following graph shows the distribution of objects’ lifetime. It displays the
amount of bytes allocated on the X axis against the lifetime of the bytes.
As we can see, the lifetime of the objects is generally short.

Figure 161: Distribution of an objects’ lifetime: ([Link], 2017)


Garbage collection in Java 357
In general it was found that most of the objects have a short life-span
and this is clearly depicted by the help of the graph above. It shows a
higher concentration on the left side which means that many objects don’t
survive for longer periods of time. Hence, the JVM divides the heap into
small parts, namely generations. Based on the generations, objects are
classified and marked accordingly by the collection algorithms.
The heap is divided into the following generations: Young, old/
tenured and Permanent.
The young generation comprises of all the newly created and
allocated objects. When this part fills up with objects completely, a minor
garbage collection event occurs. This event consists of collection of all
unreferenced/unused objects in this generation. The assumption made
here is that not many objects survive and thus can be collected quickly.
For the objects that do survive, they age and are moved eventually to the
old generation. This minor garbage collection event is a stop-the-world
event, which means that all applications are stopped until the minor
garbage collection terminates. Conventionally, an age threshold is set for
this generation. If an object reaches that age, it is moved to the older
generation.
The next generation is the Old/Tenured Generation which stores
objects that survive for a longer period of time. This section comprises
of objects that have survived the young generation. Eventually, after a
period of time these objects need to be collected as well. This collection
is a major collection and is yet another stop-the-world event. This
process is a lot slower as compared to a minor collection and hence is not
done often. The duration of the major collection is dependent on several
parameters such as the time of GC and the collection algorithm used.
The next generation is the Permanent generation which consists of
all the non-heap data. This pool of objects consists of the JVM data
itself, such as classes and methods. Basically, the metadata of the classes
and methods used in the application are stored by this generation. This
heap space is filled up during runtime based upon the classes used by
the program. When the jvm no longer references or uses these non-heap
objects, they may get collected by the garbage collector. Whenever a
complete garbage collection occurs, this generation is always included.
358 Object Oriented Programming with Java

The generations are depicted below:

Figure 162: Generations ([Link], 2017)


Now that we know of generations, we further take a look into how
the objects age in the JVM and see how generational garbage collection
works.
Initially the objects are newly created and allocated to young
generation in the eden space. This space stores newly allocated objects.
The survivor spaces, shown by the green sections in the figure below are
initially empty.

Once, the eden space is full, a minor garbage collection event is


triggered by the jvm.
The objects that are currently in use are moved to the survivor space
[Link] objects that are not used are deleted and the objects that do survive
are moved to survivor space 0.
Garbage collection in Java 359

When the next minor collection event occurs after the eden space
is full, this process is repeated. Objects in use from the eden space are
moved to survivor space 0 and unused objects are deleted. But, this time,
objects from the survivor space 0 that survive are moved and aged from
the survivor space 0 are moved in Survivor space 1.

Once all the objects that survive move to the survivor space 1, the
eden space and the survivor space 0 are cleared. Now a collection of
differently aged objects are present in the young generation.
Notice we now have differently aged object in the survivor space.
When another minor GC event occurs, the same process occurs: the
objects that survive are aged, unused objects are deleted and after the age
threshold is reached, the objects are moved into the succeeding survivor
spaces.
As the jvm keeps triggering minor collection events, the objects will
be further aged and promoted to the older generation. As this goes on,
eventually the JVM triggers a major collection event that clears up space
from the older generation and defragments the heap.
360 Object Oriented Programming with Java

Further, several types of garbage collectors are available such as the


parallel collector, the Mark and sweep collector. Additional information
related to these collectors can be found at the Java Documentation (docs.
[Link], 2017).
CHAPTER

18
REFLECTION IN JAVA

Java is a powerful language that is capable of examining and modifying


the properties of an object at runtime. Java allows a developer to inspect,
analyse and modify objects and their types, fields and classes etc which
is called as reflection. The JVM makes use of the [Link] class
and the [Link] package that has methods that one can use to
examine the properties of an object at runtime. This class serves as the
base class or point of entry for the reflection api. This class provides
several methods that helps us retrieve metadata bout classes such as
fields, methods and so on. Furthermore, using the reflection Api, the
behaviour of a class can be modified as well.

REFLECTION API
This API is mainly in the following context:
• Reflection is used in Integrated Development Environments
(IDE’s) such as Eclipse, Netbeans etc. where a developer may
need to list the members and fields of a class. This may help a
developer write better and cleaner code.
362 Object Oriented Programming with Java

• Another important area of application of reflection is in


debuggers and testing tools as they need to inspect the private
members of a class. This further helps in developing better test
cases that ensure better code coverage.
Some useful methods of the reflection API are as follows:
Method[] getDeclaredMethods(): returns a list/collection of Method
objects containing the declared methods of the current class.
Constructor[] getDeclaredConstructors(): returns the list of
constructors of the class
Field[] getDeclaredFields(): returns a list of Field object with the
fields of the class
Class<T> getSuperClass(): returns a reference of the super class of
the current class
T newInstance(): creates a new instance of the class type
String getName(): returns the name of the class as a string
Class<T> getEnclosingClass(): returns an instance object of the
class enclosing the current class. This is useful in case of nested classes
(Collins, 2011).
Package getPackage(): returns the package the class is declared in
boolean isInterface(): returns true if the object is an interface
boolean isAnonymousClass(): returns true if the class is an anonymous
class
int getModifiers(): returns the modifiers for the class encoded as an
integer
boolean isArray(): returns true if the object is an array
T newInstance(): creates a new instance of the class
static class forName(String className): returns an instance of the class
name it takes as an argument and loads it dynamically

EXAMPLES OF REFLECTION
The following examples demonstrate the use of the reflection API.
Reflection in Java 363
Example 1: Basic Java reflection API to obtain class information.
364 Object Oriented Programming with Java

The output generated is as follows:

Example 2: The newInstance() api


The newinstance() method creates an object of the class as it would
have been created using the ‘new’ keyword with a default constructor.
The object/class that is returned is always initialized. This method throws
two Exceptions: InstantiationException and IllegalAccessException.
Reflection in Java 365
As shown by the output, a new instance of the class is obtained using
two ways; using the new operator and the newInstance() method(). Both
the ways generate the same result as shown by the output below.

Example 3: [Link]
This method returns an instance of the type Class and loads the
instance dynamically. This method takes the fully qualified class name as
a parameter and cannot be used for primitive data types such as int, float
etc. (Shams and Edwards, 2013). This api is similar to the [Link]
API which returns an instance of the class as well.

The output generated is as follows:

Example 4: getMethods() and getDeclaredMethods()


366 Object Oriented Programming with Java

A notable point is that there is a difference between the


getDeclaredXXX() and the getXXX() api’s as shown in the above
example. The getDeclareMethods() method returns all the methods
declared in the current class. The getMethods() method returns all the
methods declared in the current class and the methods the current class
inherits from its superclass which is the Object class in this case. The
output is as shown below:
Reflection in Java 367
Example 5: isInterface(), getModifiers() and isArray()

The output generated by the above class is:


368 Object Oriented Programming with Java

Example 5: Use reflection api on existing java classes such as Integer.

The output generated is as follows:


Reflection in Java 369
REFERENCES

1. [Link]. (2017). What is Object-Oriented Programming?


Webopedia Definition. [online] Available at: [Link]
com/TERM/O/object_oriented_programming_OOP.html [Accessed
22 Jul. 2017].
2. development, J. (2017). Java language basics. [online] [Link].
Available at: [Link]
j-introtojava1/[Link]/ [Accessed 22 Jul. 2017].
3. Rolling Stone. (2017). Steve Jobs in 1994: The Rolling Stone
Interview. [online] Available at: [Link]
com/culture/news/steve-jobs-in-1994-the-rolling-stone-
interview-20110117 [Accessed 22 Jul. 2017].
4. Horstmann, C. S., & Cornell, G. (2002). Core Java 2: Volume I,
Fundamentals. Pearson Education.
5. Wu, C. T. (2006). An introduction to Object-oriented programming
with Java. Tata McGraw-Hill Publishing Company Limited.
372 Object Oriented Programming with Java

6. Gosling, J., & McGilton, H. (1995). The Java language environment.


Sun Microsystems Computer Company, 2550.
7. Curtin, M. (1998). Write once, run anywhere: Why it matters.
Technical Article. [Link] sun. com/features/1998/01/wo.
8. Eckel, B. (2003). Thinking in JAVA. Prentice Hall Professional.
9. Gong, L., & Ellison, G. (2003). Inside Java (TM) 2 Platform
Security: Architecture, API Design, and Implementation. Pearson
Education.
10. Shavor, S., D’Anjou, J., Fairbrother, S., Kehn, D., Kellerman, J.,
& McCarthy, P. (2003). The Java developer’s guide to Eclipse.
Addison-Wesley Longman Publishing Co., Inc..
11. Naughton, P., & Schildt, H. (1996). Java: the complete reference.
Osborne/McGraw-Hill.
12. Tempero, E., & Biddle, R. (2000). Simulating multiple inheritance
in Java. Journal of Systems and Software, 55(1), 87-100.
13. Liskov, B., & Guttag, J. (2000). Program development in JAVA:
abstraction, specification, and object-oriented design. Pearson
Education.
14. Johnson, R. E., & Foote, B. (1988). Designing reusable classes.
Journal of object-oriented programming, 1(2), 22-35.
15. Gosling, J. (2000). The Java language specification. Addison-
Wesley Professional.
16. Goetz, B., & Peierls, T. (2006). Java concurrency in practice.
Pearson Education.
17. Collins, W. (2011). Data structures and the Java collections
framework. Wiley Publishing.
18. Chan, P., & Lee, R. (1998). The Java Class Libraries, Volume 2:
java. applet, java. awt, java. beans. The Java Series.
19. Shams, Z., & Edwards, S. H. (2013). Reflection support: Java
reflection made easy. The Open Software Engineering Journal, 7(1).
20. Serializable (Java Platform SE 8 ). (n.d.). Retrieved from https://
[Link]/javase/8/docs/api/java/io/[Link]
21. javatpoint (2017). Features of Java - Javatpoint. [online] Available
at: [Link] [Accessed 22 Jul.
2017].
Object Oriented Programming 373
22. Applets Java: A Framework for Programming and Problem Solving”,
Kenneth A. Lambert and Martin Osborne, PWS Publishing, 1999,
pp. 443-455.
23. How to explain multiple inheritance in Java - Stack Overflow. (2013).
Retrieved from [Link]
how-to-explain-multiple-inheritance-in-java
24. Exceptions (1995). Retrieved from [Link]
tutorial/essential/exceptions/[Link]
25. Apps, S. (2017). Checked and Unchecked Exceptions in Java.
[online] HackTrix. Available at: [Link]
and-unchecked-exceptions-in-java [Accessed 22 Jul. 2017].
26. [Link]. (2017). Exception handling, exception
hierarchy in java. [online] Available at: [Link]
com/2015/05/[Link]
[Accessed 22 Jul. 2017].
27. [Link]. (2017). Java Garbage Collection Basics. [online]
Available at: [Link]
tutorials/obe/java/gc01/[Link] [Accessed 22 Jul. 2017].
28. [Link]. (2017). Tuning Java Garbage Collection
for Performance. [online] Available at: [Link]
com/collection/278/ [Accessed 22 Jul. 2017].
29. [Link]. (2017). Java Language Keywords (The Java™
Tutorials > Learning the Java Language > Language Basics).
[online] Available at: [Link]
nutsandbolts/_keywords.html [Accessed 22 Jul. 2017].
30. “The Complete Reference Part 2 by Herbert Schildt”.
31. The Path Class (The Java™ Tutorials > Essential Classes > Basic
I/O). (2017). [Link]. Retrieved 10 July 2017, from https://
[Link]/javase/tutorial/essential/io/[Link]
32. Chan, P., Kramer, D., & Lee, R. (1999). The Java Class Libraries:
Supplement for the Java 2 Platform Standard Edition (Vol. 1).
Addison-Wesley Professional.
33. Friesen, J. (2015). Java I/O, NIO and NIO. 2. Apress.
INDEX

A Dynamic behaviour 12

Abrupt termination 161 E


Anonymous class 225, 226, 227
Argument Number 279 Encoding system 172
Assignment operator 121 Enumeration 256
Assignment statement 224 Enumeration interface 255
Asynchronicity 336 Event handling 305, 315
Atomic action 348 Exception handling 158
Automatic garbage collector 10 Exception handling mechanism 160
Automatic Garbage collector 354
F
B File system 169, 174
Binary value 127
Bounded wildcard 274, 276, 277
G
Garbage collector 137, 140
C Generational garbage collection 358
Character array 187 Generic class 267, 268, 277
Character class 290 Generic method 267, 269
Collection interface 238, 248 Graphical User Interface (GUI) 305
Compile time 239
Contingency plan 166
H
High level container 307
D
Data structure 1
I
Deserialization 232, 234 Immutability 132
Development process 26 Immutable class 231
Diamond inheritance 83, 91 Immutable object 230
Double ended queue 244 Input Stream class 180
376 Object Oriented Programming with Java
Instance object 141 Operating system 195, 205, 218, 305
Integrated Development Environments Output stream 169, 175, 179
(IDE’s) 361
Iterator Interface 251 P
Iterator object 251
Primitive data type 228
J Programming language 7, 8, 9

Java bytecode 14 Q
Java compiler 15, 33
Queue interface 243, 244
Java Runtime Environment (JRE) 14
Java Software environment 15 R
Java virtual machine (JVM) 15
Java Virtual Machine (JVM) 14 Random generic type 239
Just in time (JIT) 11 Regex package 281, 288, 290, 292, 297
Runtime environment 159
L
S
Looping statement 110
Lower bounded parameter 276 Scheduling mechanism 332
Serializable interface 96
M Serialization mechanism 96
Static polymorphism 98
Memory management mechanism 9
String instance 133
Multidimensional array 119, 120
Superclass constructor 76, 77, 79
Multithreading 325, 336
Superclass method 75
N Superclass variable 73, 74
Survivor space 358, 359
Natural ordering 243, 247, 257 Synchronized statement 337
Nested class 221, 223
Non-static synchronization 339 T
O Tagging interface 96

Object-oriented programming (OOP) 1 U


Unbuffered stream 174
Unreferenced object 353

You might also like