0% found this document useful (0 votes)
78 views137 pages

Object Oriented Programming

This document provides an introduction to different programming paradigms including unstructured programming, procedural programming, modular programming, logic programming, and object-oriented programming. It discusses the advantages and disadvantages of each paradigm. Specifically, it notes that unstructured programming can lead to spaghetti code that is difficult to maintain, while procedural programming introduces parameters and procedures to structure programs in a more modular way. Object-oriented programming further improves on this by encapsulating code and data within objects that interact by sending messages.

Uploaded by

assefag92
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
78 views137 pages

Object Oriented Programming

This document provides an introduction to different programming paradigms including unstructured programming, procedural programming, modular programming, logic programming, and object-oriented programming. It discusses the advantages and disadvantages of each paradigm. Specifically, it notes that unstructured programming can lead to spaghetti code that is difficult to maintain, while procedural programming introduces parameters and procedures to structure programs in a more modular way. Object-oriented programming further improves on this by encapsulating code and data within objects that interact by sending messages.

Uploaded by

assefag92
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 137

Woldia University

Institute of Technology
School of Electrical and Computer engineering
For 3st year
Object Oriented Programming (ECEg-3091)

Module name: Java

Prepared by: Tesfamariam G.

Preparation date: 05/04/15


Learning module for Java 2015 E.C

Chapter One
Introduction
Programming Paradigms
A programming paradigm is a model of programming based on distinct concepts that shapes the
way programmers design, organize and write programs. A programming paradigm is a style or
way of programming. Features of various programming languages determine which programming
paradigms they belong to; as a result, some languages fall into only one paradigm, while others
fall into multiple paradigms. Some paradigms are concerned primarily with the way that code is
organized, such as grouping code into units along with the state that is modified by the code. Yet
others are concerned primarily with the style of syntax and grammar.

Why does a programming paradigm matter? Program size keeps growing quickly leading to more
complexity. The following table shows some software with their lines of code.
Software Size in lines of code Year
Windows 2000 29 million 2000
Windows XP 45 million 2001
Windows 7 40 million 2009
Android 12 million
Debian 5.0 324 million 2009
Debian 7.0 419 million 2012
Google Chrome 5 million
Firefox 10 million
Choosing a good paradigm that helps manage the complexity of programs is very important.

There are many programming techniques. This includes:


• Unstructured programming
• Procedural programming
• Modular programming
• Object-Oriented programming
• Logic programming

1. Unstructured Programming
Usually, people start learning programming by writing small and simple programs consisting only
of one main program. Here main program stands for a sequence of commands or statements which
modify data which is global throughout the whole program.

2
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

A program in a unstructured language usually consists of sequentially ordered commands, or


statements, usually one in each line. The lines are usually numbered or may have labels and this
allows the flow of execution to jump to any line in the program. Unstructured programming
introduces basic control flow concepts such as loops, branches and jumps. There is no concept of
procedures in the non-structured paradigm.

Structured programming is a programming paradigm aimed at improving the clarity, quality, and
development time of a computer program by making extensive use of subroutines, block structures,
for and while loops. This is in contrast to unstructured which uses simple tests and jumps such as
the goto statement which could lead to "spaghetti code" causing difficulty to both follow and
maintain.

Unstructured programming technique provides tremendous disadvantages once the program gets
sufficiently large. For example, if the same statement sequence is needed at different locations
within the program, the sequence must be copied. This increases the code size and becomes
unmanageable if the program is big. This has led to the idea to extract these sequences, name them
and offering a technique to call and return from these procedures. Making the data global also has
the adverse effect of getting unwanted changes inadvertently.

Fig spaghetti code created by using goto statements


The other disadvantage of unstructured programming is spaghetti code created due to use the
infamous goto statements. spaghetti code is difficulty to both follow and maintain the code.

3
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

2. Procedural Programming
In procedural programming, the program is built from one or more procedures (also called
subroutines or functions). With procedural programming you are able to combine returning
sequences of statements into one single place. A procedure call is used to invoke the procedure.
After the sequence is processed, flow of control proceeds right after the position where the call
was made.

With introducing parameters as well as procedures, programs can now be written more structured
and error free. For example, if a procedure is correct, every time it is used it produces correct
results. Consequently, in case of errors you can narrow your search to those places which are not
proven to be correct.

Now a program can be viewed as a sequence of procedure calls. The main program is responsible
to pass data to the individual calls, the data is processed by the procedures and once the program
has finished, the resulting data is presented. Thus, the flow of data can be illustrated as a
hierarchical graph, a tree, as shown in the figure.

Generally, we have a single program which is divided into small pieces called procedures. To
enable usage of general procedures or groups of procedures also in other programs, they must be

4
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

separately available. For that reason, modular programming allows grouping of procedures into
modules.

Languages such as C are procedural programming languages, so programming tends to be action-


oriented. In C, the unit of programming is the function.

Procedural programming offers many benefits over simple sequential programming since
procedural code is:
• easier to read and more maintainable
• allows reuse of procedures
• more flexible
• facilitates the practice of good program design

3. Modular Programming
With modular programming procedures of a common functionality are grouped together into
separate modules. A program therefore no longer consists of only one single part. It is now divided
into several smaller parts which interact through procedure calls and which form the whole
program.

Main program coordinates calls to procedures in separate modules and hands over appropriate
data as parameters.

Each module can have its own data. This allows each module to manage an internal state which is
modified by calls to procedures of this module. However, there is only one state per module and
each module exists at most once in the whole program.

5
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

4. Logic Programming
Logic programming is a programming paradigm based on formal logic. A program written in a
logic programming language is a set of sentences in logical form, expressing facts and rules about
the problem domain. Major logic programming language families include Prolog, Answer set
programming (ASP) and Datalog.

In this case, a logic program consists of:


• axioms — defining facts about objects
• rules — defining ways for inferencing new facts
• a goal statement — defining a theorem, potentially provable by given axioms and rules.

The rules of inference are applied for deriving the goal statement from the axioms and the
execution of a logic program corresponds to the construction of a proof of the goal statement from
the axioms.

5. Object Oriented Programming


Object-oriented programming solves some of the problems just mentioned. In contrast to the other
techniques, we now have a web of interacting objects, each house-keeping its own state.

Objects of the program interact by sending messages to each other.

OOP Concepts
1. Encapsulation
Encapsulation is the mechanism that binds together code and the data it manipulates, and keeps
both safe from outside interference and misuse. One way to think about encapsulation is as a
protective wrapper that prevents the code and data from being arbitrarily accessed by other code

6
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

defined outside the wrapper. Access to the code and data inside the wrapper is tightly controlled
through a well-defined interface.

Encapsulation is the principle of data hiding. It is the process of hiding the data structures of the
class and allowing changes in the data through a public interface where the incoming values are
checked for validity, and so not only it permits the hiding of data in an object but also of behavior.
This prevents clients of an interface from depending on those parts of the implementation that are
likely to change in future, thereby allowing those changes to be made more easily, that is, without
changes to clients.

The power of encapsulated code is that everyone knows how to access it and thus can use it
regardless of the implementation details—and without fear of unexpected side effects.

In Java/C++ the basis of encapsulation is the class. A class defines the structure and behavior (data
and code) that will be shared by a set of objects. Each object of a given class contains the structure
and behavior defined by the class, as if it were stamped out by a mold in the shape of the class.
For this reason, objects are sometimes referred to as instances of a class. Thus, a class is a logical
construct; an object has physical reality.

When you create a class, you will specify the code and data that constitute that class. Collectively,
these elements are called members of the class. Specifically, the data defined by the class are
referred to as member variables or instance variables. The code that operates on that data is
referred to as member methods or just methods. In properly written Java programs, the methods
define how the member variables can be used. This means that the behavior and interface of a class
are defined by the methods that operate on its instance data.

2. Data Hiding
It just provides a way to protect your data from the outside world. What it means is, let’s say if I
made my instance variable public, then anyone can change its state. But if we make our instance
variable private/protected then actually we are restricting outside entities from making changes to
it.

3. Abstraction
An abstraction separates interface from implementation. Abstraction hides implementation details
from the outside world. Through the process of abstraction, a programmer hides all but the relevant
data about an object in order to reduce complexity and increase efficiency.

4. Inheritance
Inheritance is the process by which one object acquires the properties of another object. This is
important because it supports the concept of hierarchical classification. For example, a Golden

7
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Retriever is part of the classification dog, which in turn is part of the mammal class, which is under
the larger class animal. Without the use of hierarchies, each object would need to define all of its
characteristics explicitly.

However, by use of inheritance, an object need only define those qualities that make it unique
within its class. It can inherit its general attributes from its parent. Thus, it is the inheritance
mechanism that makes it possible for one object to be a specific instance of a more general case.

Inheritance describes a relationship between two or more types of objects in which one inherits
features of the parent, allowing for shared functionality. This lets programmers re-use or reduce
code and simplifies the development and maintenance of software.

Inheritance is a form of software reusability in which new classes are created from existing classes
by absorbing their attributes and behaviors and adding new capabilities the new classes require.
Software reusability saves time in program development. It encourages reuse of proven and
debugged high-quality software, thus reducing problems after a system becomes operational.
These are exciting possibilities.

Most people naturally view the world as made up of objects that are related to each other in a
hierarchical way, such as animals, mammals, and dogs. If you wanted to describe animals in an
abstract way, you would say they have some attributes, such as size, intelligence, and type of
skeletal system. Animals also have certain behavioral aspects; they eat, breathe, and sleep. This
description of attributes and behavior is the class definition for animals.

If you wanted to describe a more specific class of animals, such as mammals, they would have
more specific attributes, such as type of teeth, and mammary glands. This is known as a subclass
of animals, where animals are referred to as mammals’ superclass. Since mammals are simply
more precisely specified animals, they inherit all of the attributes from animals. A deeply inherited
subclass inherits all of the attributes from each of its ancestors in the class hierarchy.

8
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Fig inheritance

Inheritance interacts with encapsulation as well. If a given class encapsulates some attributes, then
any subclass will have the same attributes plus any that it adds as part of its specialization. This is
a key concept which lets object-oriented programs grow in complexity linearly rather than
geometrically. A new subclass inherits all of the attributes of all of its ancestors. It does not have
unpredictable interactions with the majority of the rest of the code in the system.

5. Polymorphism
Polymorphism (from Greek, poly “many” and morph “form”, combined together “many forms”)
is a feature that allows one interface to be used for a set of actions.

The specific action is determined by the exact nature of the situation. Consider a stack (which is a
last-in, first-out list). You might have a program that requires three types of stacks. One stack is
used for integer values, one for floating-point values, and one for characters. The algorithm that
implements each stack is the same, even though the data being stored differs. In a non–object-
oriented language, you would be required to create three different sets of stack routines, with each
set using different names. However, because of polymorphism, in Java you can specify a general
set of stack routines that all share the same names.

More generally, the concept of polymorphism is often expressed by the phrase “one interface,
multiple methods.” This means that it is possible to design a generic interface to a group of related
activities. This helps reduce complexity by allowing the same interface to be used to specify a

9
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

general class of action. It is the compiler’s job to select the specific action (that is, method) as it
applies to each situation. You, the programmer, do not need to make this selection manually. You
need only remember and utilize the general interface.

There are several fundamentally different kinds of polymorphism:


• Ad hoc polymorphism: if a function denotes different and potentially heterogeneous
implementations depending on a limited range of individually specified types and
combinations, it is called ad hoc polymorphism. Ad hoc polymorphism is supported in
many languages using function overloading.
• Parametric polymorphism: if the code is written without mention of any specific data type
and thus can be used transparently with any number of new types, it is called parametric
polymorphism. In the object-oriented programming community, this is often known
as generics or generic programming. In the functional programming community, this is
often simply called polymorphism.
• Subtyping (also called subtype polymorphism or inclusion polymorphism): when a name
denotes instances of many different classes related by some common superclass. In the
object-oriented programming community, this is often simply referred to as polymorphism.

Example: subtype polymorphism


abstract class Animal {
abstract String talk();
}
class Cat extends Animal {
String talk() {
return "Meow!";
}
}
class Dog extends Animal {
String talk() {
return "Woof!";
}
}
class TestClass {
void letsHear(Animal a) {
println(a.talk());
}
void main() {
letsHear(new Cat());
letsHear(new Dog());
}
}

10
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Polymorphism, Encapsulation, and Inheritance Work Together


When properly applied, polymorphism, encapsulation, and inheritance combine to produce a
programming environment that supports the development of far more robust and scalable programs
than does the process-oriented model. A well-designed hierarchy of classes is the basis for reusing
the code in which you have invested time and effort developing and testing. Encapsulation allows
you to migrate your implementations over time without breaking the code that depends on the
public interface of your classes. Polymorphism allows you to create clean, sensible, readable, and
resilient code.

The Java Programming Language


Java is related to C++, which is a direct descendent of C. Much of the character of Java is inherited
from these two languages. From C, Java derives its syntax. Many of Java’s object-oriented features
were influenced by C++. In fact, several of Java’s defining characteristics come from—or are
responses to—its predecessors.

In the Java programming language, all source code is first written in plain text files ending with
the .java extension. Those source files are then compiled into .class files by the javac compiler.
A .class file does not contain code that is native to your processor; it instead contains bytecodes —
the machine language of the Java Virtual Machine (Java VM). The java launcher tool then runs
your application with an instance of the Java Virtual Machine.

Figure overview of Java software development process.

Because the Java VM is available on many different operating systems, the same .class files are
capable of running on Microsoft Windows, the Solaris Operating System (Solaris OS), Linux, or
Mac OS. Some virtual machines, such as the Java HotSpot virtual machine, perform additional
steps at runtime to give your application a performance boost. This includes various tasks such as
finding performance bottlenecks and recompiling (to native code) frequently used sections of code.

11
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Through JVM, the same application is capable of running on multiple platforms.

Characteristics of Java
The Java programming language is a high-level language that can be characterized by all of the
following buzzwords:
• Object oriented
• Distributed
• Multithreaded
• Dynamic
• Architecture neutral/portable
• High performance
• Robust
• Secure

Architecture-Neutral/Portable
A central issue for the Java designers was that of code longevity and portability. One of the main
problems facing programmers is that no guarantee exists that if you write a program today, it will
run tomorrow—even on the same machine. Operating system upgrades, processor upgrades, and
changes in core system resources can all combine to make a program malfunction. The Java
designers made several hard decisions in the Java language and the Java Virtual Machine in an
attempt to alter this situation. Their goal was “write once; run anywhere, anytime, forever”. This
is called WORA(Write Once, Run anywhere).To a great extent, this goal was accomplished.

12
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Object-Oriented
Object-oriented programming is at the core of Java. In fact, all Java programs are object-oriented—
this isn’t an option the way that it is in C++, for example. OOP is so integral to Java that you must
understand its basic principles before you can write even simple Java programs.

Interpreted and High Performance


Java enables the creation of cross-platform programs by compiling into an intermediate
representation called Java bytecode. This code can be interpreted on any system that provides a
Java Virtual Machine. Most previous attempts at crossplatform solutions have done so at the
expense of performance. Other interpreted systems, such as BASIC, Tcl, and PERL, suffer from
high performance deficits. Java, however, was designed to perform well on very low-power CPUs.

As explained earlier, while it is true that Java was engineered for interpretation, the Java bytecode
was carefully designed so that it would be easy to translate directly into native machine code for
very high performance by using a just-in-time compiler. Java run-time systems that provide this
feature lose none of the benefits of the platform-independent code. “High-performance cross-
platform” is achieved in Java.

Distributed
Java is designed for the distributed environment of the Internet, because it handles TCP/IP
protocols. In fact, accessing a resource using a URL is not much different from accessing a file.
The original version of Java included features for intra-address-space messaging. This allowed
objects on two different computers to execute procedures remotely. Java revived these interfaces
in a package called Remote Method Invocation (RMI). This feature brings an unparalleled level of
abstraction to client/server programming.

Multithreaded
Java supports multithreaded programming, which allows you to write programs that do many
things simultaneously. The Java run-time system comes with an elegant yet sophisticated solution
for multiprocess synchronization that enables you to construct smoothly running interactive
systems. Java’s easy-to-use approach to multithreading allows you to think about the specific
behavior of your program, not the multitasking subsystem.

Dynamic
Java programs carry with them substantial amounts of run-time type information that is used to
verify and resolve accesses to objects at run time. This makes it possible to dynamically link code
in a safe and expedient manner. This is crucial to the robustness of the applet environment, in
which small fragments of bytecode may be dynamically updated on a running system.

13
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Dynamic programming languages are languages which, at runtime, execute many common
programming behaviors that static programming languages perform during compilation. These
behaviors could include extension of the program, by adding new code, by extending objects and
definitions, or by modifying the type system.

The Java Platform

A platform is the hardware or software environment in which a program runs. Some of the most
popular platforms are Microsoft Windows, Linux, Solaris OS, and Mac OS. Most platforms can
be described as a combination of the operating system and underlying hardware. The Java platform
differs from most other platforms in that it's a software-only platform that runs on top of other
hardware-based platforms.

The Java platform has two components:


• The Java Virtual Machine
• The Java Application Programming Interface (API)

Java Virtual Machine is the base for the Java platform and is ported onto various hardware-based
platforms. The JVM executes Java bytecode. When you compile Java code, you produce bytecode
which is an intermediate representation. Bytecode is not directly executable because it is not
machine code. It is possible to compile code written in other languages into Java bytecode.

The Java Application Program Interface (Java API) is a large collection of ready-made software
components that provide many useful capabilities. It is grouped into libraries of related classes and
interfaces; these libraries are known as packages.

The Java Class Library (JCL) is a set of dynamically loadable libraries that Java applications
can call at run time. Because the Java Platform is not dependent on a specific operating system,
applications cannot rely on any of the platform-native libraries. Instead, the Java Platform provides
a comprehensive set of standard class libraries, containing the functions common to modern
operating systems.

Java the platform contains around 4,000 classes/interfaces used for:


➢ Data Structures
➢ Networking
➢ File access
➢ Graphical User Interfaces (GUI)
➢ Security and Encryption
➢ Image Processing
➢ Multimedia use, etc

14
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The API and Java Virtual Machine insulate the program from the underlying hardware.

As a platform-independent environment, the Java platform can be a bit slower than native code.
However, advances in compiler and virtual machine technologies are bringing performance close
to that of native code without threatening portability.

The key that allows Java to solve both the security and the portability problems is that the output
of a Java compiler is not executable code, rather, it is bytecode. Bytecode is a highly optimized set
of instructions designed to be executed by the Java run-time system Java Virtual Machine (JVM).
That is, in its standard form, the JVM is an interpreter for bytecode. Most modern languages are
designed to be compiled, not interpreted—mostly because of performance concerns. However, the
fact that a Java program is executed by the JVM helps solve the major problems associated with
downloading programs over the Internet.

Translating a Java program into bytecode helps makes it much easier to run a program in a wide
variety of environments. The reason is straightforward: only the JVM needs to be implemented for
each platform. Once the run-time package exists for a given system, any Java program can run on
it. If a Java program were compiled to native code, then different versions of the same program
would have to exist for each type of CPU available. This is, of course, not a feasible solution. Thus,
the interpretation of bytecode is the easiest way to create truly portable programs.

The fact that a Java program is interpreted also helps to make it secure. Because the execution of
every Java program is under the control of the JVM, the JVM can contain the program and prevent
it from generating side effects outside of the system. As you will see, safety is also enhanced by
certain restrictions that exist in the Java language.

When a program is interpreted, it generally runs substantially slower than it would run if compiled
to executable code. However, with Java, the differential between the two is not so great. The use
of bytecode enables the Java run-time system to execute programs much faster than you might
expect.

Although Java was designed for interpretation, there is technically nothing about Java that prevents
on-the-fly compilation of bytecode into native code. Along these lines, Sun supplied its Just In

15
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Time (JIT) compiler for bytecode, which is included in the Java 2 release and later. When the JIT
compiler is part of the JVM, it compiles bytecode into executable code in real time, on a piece-by-
piece, demand basis. It is important to understand that it is not possible to compile an entire Java
program into executable code all at once, because Java performs various run-time checks that can
be done only at run time. Instead, the JIT compiles code as it is needed, during execution. However,
the just-in-time approach still yields a significant performance boost. Even when dynamic
compilation is applied to bytecode, the portability and safety features still apply, because the run-
time system (which performs the compilation) still is in charge of the execution environment.
Whether your Java program is actually interpreted in the traditional way or compiled on-the-fly,
its functionality is the same.

Java Virtual Machine


Java Virtual Machine (JVM) is an execution environment for Java applications. In the general
sense, the JVM is an abstract computing machine defined by a specification, which is designed to
interpret bytecode that is compiled from Java source code.

The Oracle Corporation, which owns the Java trademark, distributes the Java Virtual Machine
implementation HotSpot together with an implementation of the Java Class Library under the
name Java Runtime Environment (JRE).

There are three levels of Java platforms:


• J2SE – Java Standard Edition (Java SE) is a widely used platform for development and
deployment of portable code for desktop and server environments.
• J2EE – Java Enterprise Edition (Java EE) is a widely used computing platform for
enterprise software. It is aimed for developing and running enterprise software, including
network and web services, and other large-scale, multi-tiered, scalable, reliable, and secure
network applications. Java EE extends the Java SE providing an API for object-relational
mapping, distributed and multi-tier architectures, and web services.
• J2ME - Java Micro Edition (Java ME) is a Java platform designed for embedded systems
(such as mobile devices, for example). It is for the development of software for small,
resource-constrained devices such as cell phones, PDAs and set-top boxes. Target devices
range from industrial controls to mobile phones (especially feature phones) and set-top
boxes.

16
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The JVM specification defines the subsystems and their external behavior. The JVM has the
following major subsystems:
• Class Loader: responsible for reading Java source code and loading classes into the data
areas.
• Execution Engine: responsible for executing instructions from the data areas.

The data areas occupy memory that is allocated by the JVM from the underlying OS.

17
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Fig JVM components

Class Loader
The JVM uses different class loaders organized into the following hierarchy:
• The bootstrap class loader is the parent for other class loaders. It loads the core Java
libraries and is the only one written in native code. The bootstrap class loader loads the
core Java libraries located in the <JAVA_HOME>/jre/lib directory.
• The extension class loader is a child of the bootstrap class loader. It loads the extension
libraries. The extensions class loader loads the code in the extensions directories
<JAVA_HOME>/jre/lib/ext.
• The system class loader is a child of the extension class loader. It loads the application
class files that are found in the classpath.
• A user-defined class loader is a child of the system class loader or another user-defined
class loader.

When a class loader receives a request to load a class, it checks the cache to see if the class has
already been loaded, then delegates the request to the parent. If the parent fails to load the class,
then the child attempts to load the class itself. A child class loader can check the cache of the parent
class loader, but the parent cannot see classes loaded by the child. The design is such because a
child class loader should not be allowed to load classes that are already loaded by its parent.

18
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Execution Engine
The execution engine executes commands from the bytecode loaded into the data areas one by
one. To make the bytecode commands readable to the machine, the execution engine uses two
methods.
• Interpretation - the execution engine changes each command to machine language as it is
encountered.
• Just-in-time (JIT) compilation - if a method is used frequently, the execution engine
compiles it to native code and stores it in the cache. After that, all commands associated
with this method are executed directly without interpretation.

Although JIT compilation takes more time than interpretation, it is done only once for a method
that might get called thousands of times. Running such method as native code saves a lot of
execution time compared to interpreting each command one by one every time it is encountered.

JIT compilation is not a requirement of the JVM specification, and it is not the only technique that
is used to improve JVM performance. The specification defines only which bytecode commands
relate to which native code; it is up to the implementation to define how the execution engine
actually performs this conversion.

Besides interpreting Java bytecode, most software implementations of the JVM include a just-in-
time (JIT) compiler that generates machine code for frequently used methods. Machine code is the
native language of the CPU and can be executed much faster than interpreting bytecode.

Java Version History


The Java language has undergone several changes since JDK 1.0 as well as numerous additions
of classes and packages to the standard library. In addition to the language changes, much more
dramatic changes have been made to the Java Class Library over the years, which have grown
from a few hundred classes in JDK 1.0 to over three thousand in J2SE 5. Entire new APIs, such
as Swing and Java2D, have been introduced, and many of the original JDK 1.0 classes and
methods have been deprecated.

Major release versions of Java are:


• JDK Alpha and Beta (1995)
• JDK 1.0 (January 21, 1996)
• JDK 1.1 (February 19, 1997)
• J2SE 1.2 (December 8, 1998)
• J2SE 1.3 (May 8, 2000)
• J2SE 1.4 (February 6, 2002)
• J2SE 5.0 (September 30, 2004)
• Java SE 6 (December 11, 2006)

19
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

• Java SE 7 (July 28, 2011)


• Java SE 8 (March 18, 2014)

Types of Java Programs


Java is a programming language that can be used to build programs that can work on the local
machine and on the internet as well. There are various categories of programs that can be
developed in Java.

I. STAND-ALONE APPLICATIONS
Console Applications
Like in many other programming languages, Java application can either be GUI based or console
based. Console based applications are Java programs that run from a command prompt and do not
display any GUI based screen. Such programs have console based outputs.

Fig console application that adds two numbers


GUI based applications are the Java programs that accept user input through a GUI based screen.

Fig GUI application that adds two numbers

20
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

II. WEB APPLICATIONS


These are the applications which are web-based in nature and run in web environment. The Web
applications makes use of a Server to store the data, and every time a user requests to execute that
application, the request is passed on to the server for suitable reply.
Applets
Applets are Java programs that are created specially to work on the internet. They run through a
Java embedded browser such as Firefox, Chrome, Internet Explorer, and many more. An applet
can be created using any Java development kit or tool. To work it out through the internet, it must
be contained or embedded within a web page or HTML file.
Servlets
Java is suitable for web based application development. The server side Java Application
Programming Interfaces (APIs) takes care of the program process and the response of the client’s
request. These server side APIs extend capabilities of standard Java APIs and are known as Java
servlets. HTML form processing is one of the simplest uses of servlets. These servlets can also
process databases and perform server side transactions. Servlets make use of web servers for their
execution.

Definition of Java Application, Java Applets


Applications are Java programs that run directly on your machine. Java Applications must have a
main() method. Any Java application runs stand-alone, with the support of a Java Virtual Machine.

A Java applet is a special kind of Java program that a browser enabled with Java technology can
download from the internet and run. An applet is typically embedded inside a web page and runs
in the context of a browser. An applet must be a subclass of the java.applet.Applet class. The
Applet class provides the standard interface between the applet and the browser environment.

A Java applet is a small application which delivered to users in the form of that bytecode. The user
launches the Java applet from a web page, and the applet is then executed within a Java Virtual
Machine (JVM) in a process separate from the web browser itself. A Java applet can appear in a
frame of the web page, a new application window, Sun's AppletViewer, or a stand-alone tool for
testing applets. Java applets were introduced in the first version of the Java language, which was
released in 1995.

21
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 2

Basic Language Constructs

2.1 Input and Output

Input is any information that is needed by your program to complete its execution. Input to
programs takes different forms. Some programs use graphical components like a popup dialog
box to accept and return the character string that is typed by the user. You are certainly familiar
with programs that are controlled simply by clicking the mouse in a specific area of the
screen. Still other programs, like word processing programs, get some of their input from a file
that is stored on the computer's floppy or hard disk drive. Some programs, like web browsers, get
their data from a network connection, while others get data from devices like scanners, digital
cameras and microphones. The possibilities are limited only by computer scientists' imagination.

Output is any information that the program must convey to the user. The information you see on
your computer screen is being output by one or more programs that are currently running on your
computer. When you decide to print a document, a program is told to send some output to the
printer. Any sound that your computer makes is because some program sent output to the speakers
on your computer. The possibilities for program output are also limited only by our imaginations.

There are several potential error conditions that may occur when a program needs to get input from
the user. If a user enters letters when a program is expecting numbers, an exception (error) will
occur if the program assumes incorrectly that it has a valid integer to use in calculations. Programs
must be written to survive bad input by the user. One way to do this is to ensure that only valid
input is accepted.

22
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Standard Java classes do not ensure that only valid input is accepted. They are designed to be very
flexible to support the wide variety of input and output options available now and in the
future. This flexibility comes at the cost of increased complexity.

Java applications can accept input from console or GUI input fields. The console window is the
window that is automatically launched when you run a Java program. Console input is any input
that is entered in the console window instead of typing it into a field or dialog box that pops up in
a window.

Java applications are designed to work in a terminal (console) I/O environment. Every Java
application has at its disposal three I/O streams that are designed for terminal-based input and
output, which simply sends or receives data one character at a time. The three streams are:

• Standard input (stdin): A stream designed to receive input data. This stream is usually
connected to the keyboard at the computer where the program is run. That way, the user
can type characters directly into the standard input stream. You can connect this input
stream to a class called Scanner that makes it easy to read primitive data types from the
standard input stream.
• Standard output (stdout): A stream designed to display text output on-screen. When you
run a Java program under Windows, a special console window is opened, and the standard
output stream is connected to it. Then, any text you send to standard output is displayed in
that window.
• Standard error (stderr): Another stream designed for output. This stream is also
connected to the console window. As a result, text written to the standard output stream is
often intermixed with text written to the error stream. Windows and other operating
systems allow you to redirect standard output to some other destination — typically a file.

23
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

When you do that, only the standard output data is redirected. Text written to standard error
is still displayed in the console window.
All three standard streams are available to all Java program via the fields of the System class.
Field Description
System.in Standard input
System.out Standard output
System.err Standard error

Output
System.out is known as the standard output object. System.out allows Java applications to display
strings and other types of information in the console window from which the Java application
executes.

System.out defines the print() and println() methods which are used to write data to the console.
You can use both methods with either a String argument or an argument of any primitive data type.

The method System.out.println() displays a line of text in the command window. When
System.out.println() completes its task, it automatically positions the output cursor to the beginning
of the next line in the command window. This move of the cursor is similar to you pressing the
Enter key when typing in a text editor.

Syntax:
System.out.print(message);
System.out.println(message);

The only difference between the print() and the println() methods is that the println() method adds
a line-feed character to the end of the output, so the output from the next call to print() or println()
begins on a new line. Because it doesn’t start a new line, the print() method is useful when you
want to print two or more items on the same line. For example:
System.out.print("Hello world...\n");
System.out.println("Hello world...");
System.out.print( "The answer is: ");
System.out.print( 3.14 );

System.out also implements the low-level method write( ). Thus, write( ) can be used to write to
the console. The simplest form of write( ) defined by PrintStream is shown here:
void write(int byteval)
This method writes to the stream the byte specified by byteval. Although byteval is declared as an
integer, only the low-order eight bits are written. Here is a short example that uses write( ) to output
the character “A” followed by a newline to the screen:

24
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

class WriteDemo {
public static void main(String args[]) {
int b = 'A';
System.out.write(b);
}
}
You will not often use write( ) to perform console output (although doing so might be useful in
some situations), because print( ) and println( ) are substantially easier to use.

Escape Sequence
The backslash (\) is called an escape character. It indicates that a “special character” is to be
output. When a backslash appears in a string of characters, Java combines the next character with
the backslash to form an escape sequence. The escape sequence \n is the newline character. When
a newline character appears in a string being output with System.out, the newline character causes
the screen’s output cursor to move to the beginning of the next line in the command window.

Some other common escape sequences are listed below.


Sequence Description
\n Newline. Position the screen cursor to the beginning of the next line.
\t Horizontal tab. Move the screen cursor to the next tab stop.
Carriage return. Position the screen cursor to the beginning of the current
\r line; do not advance to the next line. Any characters output after the carriage
return overwrite the characters previously output on that line.
\\ Backslash. Used to print a backslash character.
\" Double quote. Used to print a double-quote character. For example,

Input
In Java, console input is accomplished by reading from System.in. System.in refers to standard
input, which is the keyboard by default. System.in is an object of type InputStream.

System.in is a byte oriented input accepting mechanism which allows to accept byte by byte.
System.in has a method called read() which returns an integer whose value can be in the range of
0-255. This value is represents a byte of data read from console.

Example:
int a;
System.out.print("Enter a character: ");
a = System.in.read();
System.out.println("Accepted value: “ + a);

25
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Accepting input using System.in directly is very inflexible because it deals with bytes instead of
characters. As a result, it is not used commonly. Instead other input accepting mechanisms are
used of which one is the Scanner class.

Scanner Class
Until recently, getting text input from the user in a console-based Java program wasn’t easy. But
with Java 1.5, a new class called Scanner has been introduced to simplify the task of getting input
from the user.

Before you can use the Scanner class in a program, you must import it. To do that, we have to use
an import statement at the beginning of the program, before the class declaration as shown below:
import java.util.Scanner;

Before you can use the Scanner class to read input from the console, you must declare a Scanner
variable and create an instance of the Scanner class. I recommend you create the Scanner variable
as a class variable, and create the Scanner object in the class variable initializer, as shown below:
static Scanner sc = new Scanner(System.in);

That way, you can use the sc variable in any method in the class. To create a Scanner object, you
use the new keyword followed by a call to the Scanner class constructor. Note that the Scanner
class requires a parameter that indicates the input stream that the input comes from. You can use
System.in here to specify standard keyboard console input.

To read an input value from the user, you can use one of the methods of the Scanner class. As you
can see, the primitive data type has a separate method.
Method Explanation
boolean nextBoolean() Reads a boolean value from the user
byte nextByte() Reads a byte value from the user
double nextDouble() Reads a double value from the user
float nextFloat() Reads a float value from the user
int nextInt() Reads an int value from the user
String nextLine() Reads a String value from the user
long nextLong() Reads a long value from the user
short nextShort() Reads a short value from the user
Table Scanner Class Methods that get input values

26
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example:
import java.util.Scanner;
public class ScannerApp {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter an integer: ");
int x = sc.nextInt();
System.out.println("You entered " + x);
}
}

If the user enters a value that can’t be converted to the correct type, the program crashes, which
means that it abruptly terminates. As the program crashes, it displays a cryptic error message that
indicates what caused the failure. For example, if you enter three instead of an actual number, the
console window looks something like this:
Enter an integer: three
Exception in thread “main” java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at ScannerApp.main(ScannerApp.java:11)
This message indicates that an exception called InputMismatch Exception has occurred, which
means that the program was expecting to see an integer, but got something else instead.

Subtle bugs are introduced into your program when you connect more than one Scanner object to
the single System.in. So, create only one instance of the Scanner connected to System.in for use
throughout their entire program. All keyboard operations will use that single
shared Scanner object. The code below is placed with other class data members and is not inside
any method.
//Create a single shared Scanner object for keyboard input
private static Scanner scr = new Scanner( System.in );

27
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Error
System.err (the standard error stream object) normally enables a program to output error messages
to the screen. Standard error is typically used by programs to output error messages or diagnostics.
It is a stream independent of standard output and can be redirected separately.
Example:
try {
static Scanner sc = new Scanner(System.in);
String s = br.nextLine();
double number = Double.parseDouble(s);
System.out.println("Number is:" + number);
} catch (Exception e) {
System.err.println("Error invalid number");
}

2.2 Variables and Data Types

The variable is the basic unit of storage in a Java program. A variable is defined by the combination
of an identifier, a type, and an optional initializer. In addition, all variables have a scope, which
defines their visibility, and a lifetime.

Declaring a Variable
In Java, all variables must be declared before they can be used. The basic form of a variable
declaration is shown here:
type identifier [ = value][, identifier [= value] ...] ;
The type is one of Java’s primitive types, or the name of a class or interface. The identifier is the
name of the variable. You can initialize the variable by specifying an equal sign and a value. Keep
in mind that the initialization expression must result in a value of the same (or compatible) type as
that specified for the variable. To declare more than one variable of the specified type, use a
comma-separated list.

Variable Names
The rules and conventions for naming variables can be summarized as follows:
• Variable names are case-sensitive. Variable names age and Age are different variables.
• A variable's name can be any legal identifier — an unlimited-length sequence of Unicode
letters and digits, beginning with a letter, the dollar sign ($), or the underscore (_). The
convention, however, is to always begin your variable names with a letter, not $ or _.
Additionally, the dollar sign character, by convention, is never used at all. While it is
technically legal to begin your variable's name with "_" or "$", this practice is discouraged.
White space is not permitted as part of variable name.
• Subsequent characters may be letters, digits, dollar signs, or underscore characters. As a
convention, when choosing a name for your variables, use full words instead of cryptic

28
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

abbreviations. Doing so will make your code easier to read and understand. In many cases
it will also make your code self-documenting; fields named cadence, speed, and gear, for
example, are much more intuitive than abbreviated versions, such as s, c, and g. Also keep
in mind that the name you choose must not be a keyword or reserved word.
• If the name you choose consists of only one word, spell that word in all lowercase letters.
If it consists of more than one word, capitalize the first letter of each subsequent word. The
names gearRatio and currentGear are prime examples of this convention. If your variable
stores a constant value, such as static final int NUM_GEARS = 6, the convention changes
slightly, capitalizing every letter and separating subsequent words with the underscore
character. By convention, the underscore character is never used elsewhere.

Data Types
Java defines eight simple or primitive types of data: byte, short, int, long, char, float, double,
and boolean. These can be put in four groups:
• Integers - this group includes byte, short, int, and long, which are for wholevalued signed
numbers.
• Floating-point numbers - this group includes float and double, which represent numbers
with fractional precision.
• Characters - this group includes char, which represents symbols in a character set, like
letters and numbers.
• Boolean - this group includes boolean, which is a special type for representing true/false
values.

Integers
Java defines four integer types: byte, short, int, and long. All of these are signed, positive and
negative values. Java does not support unsigned, positive-only integers. All of them are
represented as signed two's complement integer.

Name Width(bits) Range

byte 8 –128 to 127


short 16 –32,768 to 32,767
int 32 –2,147,483,648 to 2,147,483,647
long 64 –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

byte
The smallest integer type is byte. This is a signed 8-bit type that has a range from –128 to 127.
Variables of type byte are especially useful when you’re working with a stream of data from a
network or file. They are also useful when you’re working with raw binary data that may not be
directly compatible with Java’s other built-in types.

29
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Byte variables are declared by use of the byte keyword. For example, the following declares two
byte variables called b and c:
byte b, c;

short
The short data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768
and a maximum value of 32,767. You can use a short to save memory in large arrays, in situations
where the memory savings actually matters.

Here are some examples of short variable declarations:


short s;
short t = 3217;

int
The int data type is a 32-bit signed two's complement integer. It has a minimum value of -
2,147,483,648 and a maximum value of 2,147,483,647. For integral values, this data type is
generally the default choice unless there is a reason to choose something else. This data type will
most likely be large enough for the numbers your program will use, but if you need a wider range
of values, use long instead.

In addition to other uses, variables of type int are commonly employed to control loops and to
index arrays. Any time you have an integer expression involving bytes, shorts, ints, and literal
numbers, the entire expression is promoted to int before the calculation is done.

long
long is a signed 64-bit type and is useful for those occasions where an int type is not large enough
to hold the desired value. The range of a long is quite large. This makes it useful when big, whole
numbers are needed.

For example, here is a program that computes the number of kilometers that light will travel in a
specified number of days.
// approximate speed of light in meters per second
int lightspeed = 299792458;
long days, seconds, distance;
days = 1000; // specify number of days here
seconds = days * 24 * 60 * 60; // convert to seconds
distance = lightspeed * seconds; // compute distance
System.out.print("In " + days);
System.out.print(" days light will travel about ");
System.out.println((distance/1000) + " kilometers.");

30
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Floating-Point Types
Floating-point numbers, also known as real numbers, are used when evaluating expressions that
require fractional precision. For example, calculations such as square root, or trigonometry such
as sine and cosine, result in a value whose precision requires a floating-point type. Java implements
the standard (IEEE–754) set of floating-point types and operators. There are two kinds of floating-
point types, float and double, which represent single- and double-precision numbers, respectively.
Name Width Range
(bits)
double 64 4.9e–324 to 1.8e+308
float 32 1.4e−045 to 3.4e+038

Floating-point numbers can be expressed in either standard or scientific notation. Standard


notation consists of a whole number component followed by a decimal point followed by a
fractional component. For example, 2.0, 3.14159, and 0.6667 represent valid standard-notation
floating-point numbers. Scientific notation uses a standard-notation, floating-point number plus a
suffix that specifies a power of 10 by which the number is to be multiplied. The exponent is
indicated by an E or e followed by a decimal number, which can be positive or negative. Examples
include 6.022E23, 314159E–05, and 2e+100.

Floating-point literals in Java default to double precision. To specify a float literal, you must
append an F or f to the constant. You can also explicitly specify a double literal by appending a D
or d. Doing so is, of course, redundant.

float
The type float specifies a single-precision value that uses 32 bits of storage. Single precision is
faster on some processors and takes half as much space as double precision, but will become
imprecise when the values are either very large or very small. Variables of type float are useful
when you need a fractional component, but don’t require a large degree of precision.

Example:
float x = 2.5345;
float y = 34.23f;
float z = 6.022E+23;

This data type should never be used for precise values, such as currency. For that, you will need
to use the java.math.BigDecimal class instead.

31
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

double
Double precision uses 64 bits to store a value. For decimal values, this data type is generally the
default choice. Double precision is actually faster than single precision on some modern
processors that have been optimized for high-speed mathematical calculations. All transcendental
math functions, such as sin( ), cos( ), and sqrt( ), return double values. When you need to maintain
accuracy over many iterative calculations, or are manipulating large-valued numbers, double is
the best choice.

Example: compute the area of a circle.


class Area {
public static void main(String args[]) {
double pi, r, a;
r = 10.8; // radius of circle
pi = 3.1416; // pi, approximately
a = pi * r * r; // compute area
System.out.println("Area of circle is " + a);
}
}

char
In Java, the data type used to store characters is char. Java uses Unicode to represent characters.
Unicode defines a fully international character set that can represent all of the characters found in
all human languages. It is a unification of dozens of character sets, such as Latin, Greek, Arabic,
Cyrillic, Hebrew, Katakana, Hangul, and many more. For this purpose, it requires 16 bits. Thus,
in Java char is a 16-bit type. The range of a char is 0 to 65,536.

The standard set of characters known as ASCII still ranges from 0 to 127 as always, and the
extended 8-bit character set, ISO-Latin-1, ranges from 0 to 255. Since Java is designed to allow
applets to be written for worldwide use, it makes sense that it would use Unicode to represent
characters of all languages. Of course, the use of Unicode is somewhat inefficient for languages
such as English, German, Spanish, or French, whose characters can easily be contained within 8
bits. But such is the price that must be paid for global portability.

Character literals should be enclosed in single quotes (‘’), but not double quotes. Numbers can be
assigned to char variables. These numbers are treated as character code of the character desired.
Hence, you can use unary operators on characters just like on numbers.

Example:
char ch1, ch2;
ch1 = 88; // code for X

32
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

ch2 = 'Y';
System.out.print("ch1 and ch2: " + ch1 + " " + ch2); //output: ch1 and ch2: X Y
ch2++; //increment character code by 1
System.out.print("ch2: " + ch2); //output: ch2: Z

Unicode characters are represented using \uxxxx format where xxxx is the Unicode code of the
character and \u is indication of that this is Unicode representation. The number xxxx is given in
hexadecimal. It has a minimum value of '\u0000' and a maximum value of '\uffff'.

Example: a program that uses Unicode code to display Greek characters


char c, d;
c = '\u042F';
d = '\u0418';
System.out.print(c + "" + d);
Output: ЯИ

Booleans
Java has a simple type, called boolean, for logical values. It can have only one of two possible
values: true or false. This is the type returned by all relational operators, such as a < b. boolean
is also the type required by the conditional expressions that govern the control statements such as
if and for.

Example:
boolean b = false;
System.out.println("b is " + b);
b = 3 < 4;
System.out.println("b is " + b);

String Handling In Java


A string is a sequence of text characters. Java doesn’t define strings as a primitive type. Instead,
strings are defined by the Java as String class. The Java language does have some built-in features
for working with strings. In some cases, these features make strings appear to be primitive types
rather than reference types.

Strings are declared and initialized much like primitive types. In fact, the only difference is that
the word String is capitalized, unlike the keywords for the primitive types. The following
statements define and initialize a string variable:
String s;
s = "Hello, World!";

33
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Notice that string literals are enclosed in quotation marks, not apostrophes. Apostrophes are used
for character literals, which are different than string literals.

You can combine two strings by using + which is a concatenation operator. For example, the
following statement combines the value of two string variables to create a third string:
String he = "Jimma University, ";
String wo = "Jimma";
String greeting = he + wo;
The final value of the greeting variable is "Jimma University, Jimma!".

You can also mix variables and string literals. For example:
String hello = "Hello";
String world = "World! ";
String greeting = hello + ", " + world;

Java is Strongly Typed


It is important to know that Java is a strongly typed language. Indeed, part of Java’s safety and
robustness comes from this fact. First, every variable has a data type, every expression has a data
type, and every data type is strictly defined. Second, all assignments, whether explicit or via
parameter passing in method calls, are checked for data type compatibility. There are no automatic
conversions of conflicting types as in some languages. The Java compiler checks all expressions
and parameters to ensure that the types are compatible. Any type mismatches are errors that must
be corrected before the compiler will finish compiling the class.

Example: expressions have data types


float x;
x = 5/2;
System.out.println(x); //2
The result is 2 because both operands are integers and Java is taking the expression as integer
division which results in integer value. If you want real number division, the numbers should be
followed by f indication that it is float or d indicating that it is double.

Example: double division


double x,y;
x = 5.0d/2;
System.out.println(x); //2.5

Note: If you come from a C or C++ background, keep in mind that Java is more strictly typed than
either language. For example, in C/C++ you can assign a floating-point value to an integer. In Java,

34
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

you cannot. Also, in C there is not necessarily strong type-checking between a parameter and an
argument. In Java, there is.

Type Conversion and Casting


Sometimes, you need to convert numeric data of one type to another. For example, you might need
to convert a double value to an integer, or vice versa. Some conversions can be done automatically.
Others are done explicitly using a technique called casting.

In Java, type casting is classified into two types:


• Widening conversion - when you are converting data from small sized data type to big
sized data type. There is no possibility of data loss during conversion.
• Narrowing conversion - when you are converting data from big sized data type to small
sized data type. There is possibility of data loss during conversion.

Fig widening (top) and narrowing (bottom) conversions

Casting could be either:


• Implicit casting – casting done by compiler/interpreter itself during compilation or run.
Widening conversions can be implicit.
• Explicit casting – should be clearly stated in the code. Narrowing conversions have to be
done explicitly using code.

When one type of data is assigned to another type of variable, an automatic type conversion
(implicit casting) will take place if the following two conditions are met:
• The two types are compatible.
• The destination type is larger than the source type.
When these two conditions are met, a widening conversion takes place. For example, the int type
is always large enough to hold all valid byte values, so no explicit cast statement is required. For
widening conversions, the numeric types, including integer and floating-point types, are
compatible with each other.

35
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Fig possible automatic conversion


Example: implicit casting
int a = 100;
long b = a; // Implicit cast, an int value always fits in a long

Type Casting
To create a conversion between two incompatible types, you must use a cast. A cast is simply an
explicit type conversion. Casting is similar to conversion, but isn’t done automatically.

When you use casting, you run the risk of losing information. For example, a double can hold
larger numbers than an int. But, an int can’t hold the fractional part of a double. As a result, if you
cast a double to an int, you run the risk of losing data or accuracy. For example, 3.1415 becomes
3.

To cast a primitive value from one type to another, you use a cast operator, which is simply the
name of a primitive type in parentheses placed before the value you want to cast. The general
syntax is:
variable = (data-type) value
Here, data-type specifies the desired type to convert the specified value to.

For example, the following fragment casts an int to a byte. If the integer’s value is larger than the
range of a byte, only bits that can fit into byte is taken and other bits discarded.
int a = 100;
byte b = (byte) a;

36
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

A different type of conversion will occur when a floating-point value is assigned to an integer type:
truncation. Thus, when a floating-point value is assigned to an integer type, the fractional
component is lost. Of course, if the size of the whole number component is too large to fit into the
target integer type, then that value will be reduced to the bits that fit into the target type.

Example:
public static void main(String args[]) {
byte b;
int i = 257;
double d = 323.142;
System.out.println("\nConversion of int to byte.");
b = (byte) i;
System.out.println("i and b " + i + " " + b);
System.out.println("\nConversion of double to int.");
i = (int) d;
System.out.println("d and i " + d + " " + i);
System.out.println("\nConversion of double to byte.");
b = (byte) d;
System.out.println("d and b " + d + " " + b);
}

Output:
Conversion of int to byte.
i and b 257 1
Conversion of double to int.
d and i 323.142 323
Conversion of double to byte.
d and b 323.142 67

A boolean value cannot be assigned to any other data type. Except boolean, all the other data types
can be assigned to one another either implicitly or explicitly; but boolean cannot. This means,
boolean is incompatible for conversion.

String to Number
Converting a primitive value to a string value is pretty easy. But converting a string value to a
primitive is a little more complex, because it doesn’t always work. For example, if a string contains
the value 10, you can easily convert it to an integer. But if the string contains “thirty-two”, you
can’t.

37
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

To convert a string to a primitive type, you use a parse method of the appropriate wrapper class
(see table below).
Wrapper class Parse Method Example
Integer parseInt(String) int x = Integer.parseInt(“100”);
Short parseShort(String) short x = Short.parseShort(“100”);
Long parseLong(String) long x = Long.parseLong(“100”);
Byte parseByte(String) byte x = Byte.parseByte(“100”);
Float parseFloat(String) float x = Float.parseFloat (“19.95”);
Double parseDouble(String) double x = Double.parseDouble(“19.95”);
Boolean parseBoolean(String) boolean x = Boolean.parseBoolean(“true”);

For example, to convert a string value to an integer, you use statements like this:
String s = “10”;
int x = Integer.parseInt(s);

Constant
A constant, also called final variable, is a variable whose value you can’t change once it has been
initialized. To declare a final variable, you add the final keyword to the variable declaration, like
this:
final double PI = 5;

Although it isn’t required, using all capital letters for final variable names is common. You can
easily spot the use of final variables in your programs.

Constants are useful for values that are used in several places throughout a program and that don’t
change during the course of the program.

2.3 Operators
An operator is a special symbol or keyword that is used to designate a mathematical operation or
some other type of operation that can be performed on one or more values, called operands. In all,
Java has about 40 different operators.

The Unary Operators


The unary operators require only one operand; they perform various operations such as
incrementing/decrementing a value by one, negating an expression, or inverting the value of a
boolean.

38
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Operator Description
+ Unary plus operator; indicates positive value (numbers are positive
without this still)
- Unary minus operator; negates an expression
++ Increment operator; increments a value by 1
-- Decrement operator; decrements a value by 1
! Logical complement operator; inverts the value of a boolean

Example:
public static void main(String[] args) {
int result = +1; // result is now 1
result--; // result is now 0
result++; // result is now 1
result = -result; // result is now -1
boolean success = false;
boolean tt = !success; // true
}

Arithmetic Operators
These arithmetic operators perform basic arithmetic operations, such as addition, subtraction,
multiplication, and division.
Operator Description Example
+ Addition x = 3+4;
- Subtraction y = 5-3;
* Multiplication x = 5*5;
/ Division y = 50/2;
% Remainder y = 20%7;
++ Increment y++; ++x;
-- Decrement y--; --x;

Example:
short x = 6, y = 4;
float a = 12.5f, b = 7f;
System.out.println("x is " + x + ", y is " + y);
System.out.println("x + y = " + (x + y));
System.out.println("x - y = " + (x - y));
System.out.println("x / y = " + (x / y));
System.out.println("x % y = " + (x % y));

39
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

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

Example:
double x = 5.5, y = 2.0;
double m = x + y; // m is 7.5
double n = x - y; // n is 3.5
double o = x * y; // o is 11.0
double p = x / y; // p is 2.75
double q = x % y; // q is 1.5
x++; // x is now 6.5
y--; // y is now 1.0

Relational Operators
The relational operators determine the relationship that one operand has to the other. Specifically,
they determine equality and ordering i.e. which one is greater than or less than the other.
Operator Meaning Example
== Equal x == 3
!= Not equal x != 3
< Less than x<3
> Greater than x>3
<= Less than or equal to x <= 3
>= Greater than or equal to x >= 3

The outcome of these operations is a boolean value. The relational operators are most frequently
used in the expressions that control the if statement and the various loop statements.

Example:
int a = 4, b = 1;
boolean c = a < b; //false
if(a > 10)
System.out.println("Greater than ten");

Logical Operators
A logical operator (sometimes called a boolean operator) is an operator that returns a boolean result
that’s based on the boolean result of one or two other expressions. Expressions that use logical
operators are sometimes called compound expressions because the effect of the logical operators
is to let you combine two or more condition tests into a single expression.

Operator Name Description


! Not Returns true if the operand to the right evaluates to false.
Returns false If the operand to the right is true.
& And Returns true if both of the operands evaluate to true. Both
operands are evaluated before the & operator is applied.

40
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

| Or Returns true if at least one of the operands evaluates to


true. Both operands are evaluated before the | operator is
applied.
^ Xor Returns true if one and only one of the operands
evaluates to true. If both operands evaluate to true or if
both operands evaluate to false, returns false.
|| Conditional Or Same as |, but if the operand on the left returns true,
returns true without evaluating the operand on the right.
&& Conditional And Same as &, but if the operand on the left returns false,
returns false without evaluating the operand on the right.

Example: check if a number is between 80 and 100


int num = 50;
if(num>=80 && num<=100)
System.out.println("Yes");
else
System.out.println("No");

Compound Assignment Operator


A compound assignment operator is an operator that performs a calculation and an assignment at
the same time. All of Java’s binary arithmetic operators have equivalent compound assignment
operators.
Operator Description
= Assignment
+= Addition and assignment
-= Subtraction and assignment
*= Multiplication and assignment
/= Division and assignment
%= Remainder and assignment
&= AND & assignment
|= OR and assignment
^= XOR and assignment

Example:
boolean a = true, b = false;
boolean d = a & b;
boolean e = a ^ b;
boolean f = (!a & b) | (a & !b);
boolean g = !a;
System.out.println(" a = " + a + " b = " + b);
System.out.println(" a&b = " + d); //false

41
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println(" a^b = " + e); //true


System.out.println("!a&b|a&!b = " + f); //true
System.out.println(" !a = " + g); //false

The Conditional Operator


Java includes a special ternary operator that can replace certain types of if-then-else statements.
This operator is the ?, and it works in Java much like it does in C or C++. The ? has this general
form:
expression1 ? expression2 : expression3
Here, expression1 can be any expression that evaluates to a boolean value. If expression1 is true,
then expression2 is evaluated; otherwise, expression3 is evaluated. The result of the ? operation is
that of the expression evaluated. Both expression2 and expression3 are required to return the same
type, which can’t be void.

Example: a program that returns absolute value of a number


int i = 10, k;
k = i < 0 ? -i : i; // get absolute value of i
System.out.print("Absolute value of " + i + " is " + k);

Operator Precedence
Operator precedence determines the order in which operators are performed. This can clearly affect
the result of the operation.

Parentheses raise the precedence of the operations that are inside them. This is often necessary to
obtain the result you desire.

Operators Associativity Type


() [] . left to right highest
++ -- right to left unary postfix
++ -- + - ! (type) right to left Unary & prefix
* / % left to right multiplicative
+ - left to right additive
< <= > >= left to right relational
== != left to right equality
& left to right logical AND
^ left to right logical exclusive OR

42
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

| left to right logical inclusive OR


&& left to right logical AND
|| left to right logical OR
?: right to left conditional
= += -= *= /= %= right to left assignment

Example: Evaluate the following expressions


double x;
x = 3 + 2 * 3; //9
x = (3 + 2) * 3; // 15
x = 3 + 2 * 3 * 3 + 5 % 2 / 2; // 21
x = –(2 * 3) + 6 / 2 / 3 + 9 % 4; //-4
int y=10, z = 5;
z += y += 5; //y=15, z=20 -> evaluated from right to left

Packages
A package is a group of classes that belong together. It is a group of similar types of classes,
interfaces and sub-packages. It is a container for classes & interfaces. It is a way to organize classes
into groups and reduce mess. The advantages of Java Package are:
• packages are used to categorize the classes and interfaces so that they can be easily
maintained.
• package provides access protection. Package protects accessibility of class members.
• package removes naming collision. Classes in different packages can have the same name.

Package in Java can be categorized in two: built-in package and user-defined package.

Built-in Packages
The Java platform provides an enormous class library suitable for use in your own applications.
This library is known as the Application Programming Interface or API for short. Its packages
represent the tasks most commonly associated with general-purpose programming. For example,
a String object contains state and behavior for character strings; a File object allows a programmer
to easily create, delete, inspect, compare, or modify a file on the file system; a Socket object allows
for the creation and use of network sockets; various GUI objects control buttons and checkboxes
and anything else related to graphical user interfaces. There are literally thousands of classes to
choose from. This allows you, the programmer, to focus on the design of your particular
application, rather than the infrastructure required to make it work.

43
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Importing Packages
Application developers use Java API classes when writing programs. To include these classes into
programs, we use the import statement. The purpose of the import statement is to let the compiler
know that the program is using a class that’s defined by the Java API.

Because the Java API contains literally thousands of classes, some form of organization is needed
to make the classes easier to access. Java does this by grouping classes into manageable groups
called packages. A package is a namespace that organizes a set of related classes. Conceptually
you can think of packages as being similar to different folders on your computer. You might keep
HTML pages in one folder, images in another, and scripts or applications in yet another. Because
software written in the Java programming language can be composed of hundreds or thousands of
individual classes, it makes sense to keep things organized by placing related classes and interfaces
in packages.

The import statements must appear at the beginning of the class file, before any class declarations.
This occurs immediately following the package statement (if it exists) and before any class
definitions. You can include as many import statements as are necessary to import all the classes
used by your program.

This is the general form of the import statement:


import pkg1[.pkg2].classname;
import pkg1[.pkg2].*;
Here, pkg1 is the name of a top-level package, and pkg2 is the name of a subordinate package
inside the outer package separated by a dot (.). There is no practical limit on the depth of a package
hierarchy, except that imposed by the file system. Finally, you specify either an explicit classname
or an asterisk (*). * means you import all the classes in a particular package by listing the package
name followed by an asterisk wildcard, like this:
import javax.swing.*;

This code fragment shows both forms in use:


import java.util.Date;
import java.io.*;
The first one imports a specific class called Date from java.util package. Other classes in the
java.util package are not imported. In the second case, all classes in java.io package are imported
to your program. This may import the classes your program does not need along with the ones it
needs.

As of Java 8, the built-in packages in Java are the following:


• java.lang — basic language functionality and fundamental types

44
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

• java.util — collection data structure classes


• java.io — file operations
• java.math — multiprecision arithmetic
• java.nio — the non-blocking I/O framework for Java
• java.net — networking operations, sockets, DNS lookups, ...
• java.security — key generation, encryption and decryption
• java.sql — Java Database Connectivity (JDBC) to access databases
• java.awt — basic hierarchy of packages for native GUI components
• javax.swing — hierarchy of packages for platform-independent rich GUI components
• java.applet — classes for creating an applet
• java.beans — contains classes related to developing beans which are components based on
the JavaBean architecture.
• java.text — provides classes and interfaces for handling text, dates, numbers, and messages
in a manner independent of natural languages.
• java.rmi — provides the Remote Method Invocation (RMI) package.
• java.time — the main API for dates, times, instants, and durations.

All of the standard Java classes included with Java are stored in a package called java or javax.
The basic language functions are stored in a package inside of the java package called java.lang.
Normally, you have to import every package or class that you want to use, but since Java can’t run
without much of the functionality in java.lang, it is automatically imported by the compiler for all
programs. This is equivalent to the following line being at the top of all of your programs:
import java.lang.*;

If a class with the same name exists in two different packages that you import using *, the compiler
will remain silent, unless you try to use one of the classes. In that case, you will get a compile-
time error and have to explicitly name the class specifying its package.

Example: Date class is defined in both java.util and java.sql packages


import java.util.*;
import java.sql.*;
class Test {
public static void main(String args[]) {
//this line generates a compile error since the compiler is confused to which Date
//class you are referring to.
Date dt;
//so, you should fully qualify it by specifying the package
java.util.Date dt;
}
}

45
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Strictly speaking, import statements are never required. But if you don’t use import statements to
import the API classes your program uses, you must fully qualify the names of the classes when
you use them by listing the package name in front of the class name.

Example:
Date dt; //requires import
java.util.Date dt; //fully qualified, no import needed

Example: displaying date with fully qualified approach


java.util.Date dt = new java.util.Date();
int dd = dt.getDate();
int mm = dt.getMonth() + 1; //returns first month as 0, so add 1
int yy = dt.getYear() % 100; //returns year-1900, so use % to get 15 instead of 115 for 2015
System.out.println(dd + "/" + mm + "/" + yy);

User Defined Packages


Java applications which users write are made up of classes. When the number of classes grow, it
tends to be difficult to manage. To solve this, Java allows developers to organize the classes in
Java applications using packages. Package can be defined and then made to contain related classes.

To create a package, simply include a package command as the first statement in a Java source
file. Any classes declared within that file will belong to the specified package. The package
statement defines a name space in which classes are stored. If you omit the package statement, the
class names are put into the default package, which has no name. While the default package is fine
for short, simple programs, it is inadequate for real applications. Most of the time, you will define
a package for your code.

This is the general form of the package statement:


package packagename;
Here, packagename is the name of the package. For example, the following statement creates a
package called MyPackage.
package MyPackage;

Java uses file system directories to store packages. For example, the .class files for any classes you
declare to be part of MyPackage must be stored in a directory called MyPackage. Remember that
it is case-sensitive, and the directory name must match the package name exactly.

Example: the program defines a class called Addition in a package called arithmetic
package arthimetic;
import java.util.Scanner;
public class Addition {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
double a, b, c;

46
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println("Enter two numbers: ");


a = sc.nextDouble();
b = sc.nextDouble();
c = a+b;
System.out.println("the sum is " + c);
}
}

47
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Exercise
1. Convert the following algebraic expression into Java code:
𝑎+𝑏+𝑐+𝑑+𝑒
a. 𝑚 =
5
b. y = mx+b2
c. y = ax2 + bx + c
2. What is the output of the following program?
int x = 10, y;
y = x += 3 + 4;
System.out.println(x + " " + y);
3. What is the output of the following program?
int x = 10, z = 5;
x += z = 4;
System.out.println(x + " " + z);

4. What is the result of the following code fragment?


int x = 5, y = 10;
int z = ++x * y--;

5. What is the result of the following code fragment? Explain.


System.out.println("1 + 2 = " + 1 + 2);
System.out.println("1 + 2 = " + (1 + 2));

6. Convert the following if statements into ternary operator


int mark = sc.nextInt();
String status;
if(mark < 50)
status = "failed";
else
status = "pass";

7. What does the following code fragment print?


System.out.println(3 + 2 + "abc");
System.out.println("abc" + 3 + 2);
System.out.println("abc" + 3 * 2);

8. Write a program that accepts the coefficients of quadratic equation and then solve it. The
program accepts values of a, b and c and then compute both roots and display.

48
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 3
Decision and Repetition Statements
Control Structure
The statements inside your Java codes are generally executed from top to bottom, in the order that
they appear. Control flow statements, however, break up the flow of execution by employing
decision making, looping, and branching, enabling your program to conditionally execute
particular blocks of code.

Java, like any programming language, uses control statements to cause the flow of execution to
advance and branch based on changes to the state of a program. Java control statements can be put
into the following categories: selection, iteration, and jump. Selection statements allow your
program to choose different paths of execution based upon the outcome of an expression or the
state of a variable. Iteration statements enable program execution to repeat one or more statements
again and again. Jump statements allow your program to execute in a nonlinear fashion.

3.1 Decision Making


For decision making, Java provides two statements: the if statement and the switch statement.

The if Statement
The if-then statement is the most basic of all the control flow statements. It tells your program to
execute a certain section of code only if a particular test evaluates to true. The if statement relies
heavily on the use of boolean expressions, which are expressions that yield a simple true or false
result.

Syntax:
if (boolean-expression){
statement;
}

Example: a program that checks if a number is even or not


int num = 16;
if (num % 2 == 0)
System.out.println(num + " is even");

if-else statements
An if-else statement adds an additional element to a basic if statement: a statement or block that’s
executed if the boolean expression is false. The basic syntax is
if (boolean-expression){
statement
}
else {
statement
}

49
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: a program that determines if a student passed or failed


double average;
Scanner sc = new Scanner(System.in);
average = sc.nextDouble();
if(average >= 50)
status = "promoted";
else
status = "failed";

else-if statements
A common programming construct that is based upon a sequence of nested ifs is the if-else-if
ladder. It looks like this:
if(condition){
statements;
}
else if(condition){
statements;
}
else if(condition){
statements;
}
...
else {
statements;
}

The if statements are executed from the top down. As soon as one of the conditions controlling the
if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed.
If none of the conditions is true, then the final else statement will be executed. The final else acts
as a default condition; that is, if all other conditional tests fail, then the last else statement is
performed. If there is no final else and all other conditions are false, then no action will take place.

Example: a program that accepts mark and displays letter grade


int score = 76;
char grade;
if (score >= 90)
grade = 'A';
else if (score >= 80)
grade = 'B';
else if (score >= 70)
grade = 'C';
else if (score >= 60)
grade = 'D';
else
grade = 'F';
System.out.println("Grade = " + grade);

50
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Switch
Switch provides an easy way to dispatch execution to different parts of your code based on the
value of an expression.

Unlike if-then and if-then-else statements, the switch statement can have a number of possible
execution paths. A switch works with the byte, short, char, and int primitive data types. It also
works with enumerated types, the String class, and a few special classes that wrap certain primitive
types: Character, Byte, Short, and Integer.

Syntax:
switch (expression) {
case value1:
// statement sequence
break;
case value2:
// statement sequence
break;
...
default:
// default statement sequence
}

The body of a switch statement is known as a switch block. A statement in the switch block can
be labeled with one or more case or default labels. The switch statement evaluates its expression,
then executes all statements that follow the matching case label.

The following code example, declares an int named month whose value represents a month. The
code displays the name of the month, based on the value of month, using the switch statement.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int month = sc.nextInt();
String monthString;
switch (month) {
case 1: monthString = "January"; break;
case 2: monthString = "February"; break;
case 3: monthString = "March"; break;
case 4: monthString = "April"; break;
case 5: monthString = "May"; break;
case 6: monthString = "June"; break;

51
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

case 7: monthString = "July"; break;


case 8: monthString = "August"; break;
case 9: monthString = "September"; break;
case 10: monthString = "October"; break;
case 11: monthString = "November"; break;
case 12: monthString = "December"; break;
default: monthString = "Invalid month"; break;
}
System.out.println(monthString);
}

The break statement is optional. If you omit the break, execution will continue on into the next
case. It is sometimes desirable to have multiple cases without break statements between them.
For example, consider the following program:
int month = 4;
String season;
switch (month) {
case 12:
case 1:
case 2:
season = "Winter"; break;
case 3:
case 4:
case 5:
season = "Spring"; break;
case 6:
case 7:
case 8:
season = "Summer"; break;
case 9:
case 10:
case 11:
season = "Autumn"; break;
default:
season = "Bogus Month";
}
System.out.println("April is in the " + season + ".");

52
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

3.2 Loops/Iteration
In Java, like in other programming languages, a loop repeatedly executes the same set of
instructions until a termination condition is met. Java provides three iteration statements: for,
while, and do-while.

The for loop


The basic principle behind a for loop is that the loop itself maintains a counter variable — that is,
a variable whose value is increased each time the body of the loop is executed. The for loop lets
you set this up this in one convenient statement.

The general format of the for structure is


for(initialization; condition; iteration) {
// body
}
The for loop operates as follows.
• When the loop first starts, the initialization portion of the loop is executed. Generally, this
is an expression that sets the value of the loop control variable, which acts as a counter that
controls the loop. It is important to understand that the initialization expression is only
executed once.
• Next, condition is evaluated. This must be a Boolean expression. It usually tests the loop
control variable against a target value.
• If condition expression is true, then the body of the loop is executed. If it is false, the loop
terminates.
• Next, the iteration portion of the loop is executed. This is usually an expression that
increments or decrements the loop control variable.
• The loop then iterates, first evaluating the conditional expression, then executing the body
of the loop, and then executing the iteration expression with each pass. This process repeats
until the controlling expression is false.

Example: a program that checks if a number is prime or not


int num = 14;
boolean isPrime = true; //start with the assumption that it is prime & then disprove in a loop
for(int i=2; i <= num/2; i++) {
if((num % i) == 0) {
isPrime = false;
break;
}
}

53
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

if(isPrime == True)
System.out.println(“It is prime”);
else
System.out.println(“It is not prime”);

Multiple Expressions in for Loop


One obscure aspect of for loops is that the initialization and count expressions can actually be a
list of expressions separated by commas. This can sometimes be useful if you need to keep track
of two counter variables at the same time. For example, here’s a program that counts from 1 to 10
and 10 to 1 at the same time, using two counter variables:
public static void main(String[] args) {
int a, b;
for (a = 1, b = 10; a <= 10; a++, b--)
System.out.println(a + “ “ + b);
}

In the initialization expression, you can’t declare variables if you use more than one expression.
That’s why variables a and b are declared before the for statement in the example above.
You can’t list more than one expression in the test expression. However, you can use compound
conditions created with logical operators, so you don’t need to use an expression list.

Omitting Expressions
Another aspect of for loops is that all three of the expressions are optional. If you omit one or more
of the expressions, you just code the semicolon as a placeholder so the compiler knows. Omitting
the test expression or the iteration expression is not common, but omitting the initialization
expression is common. For example, the variable you’re incrementing in the for loop may already
be declared and initialized before you get to the loop. In that case, you can omit the initialization
expression, as in this example:
Scanner sc = new Scanner(System.in);
System.out.print(“Where should I start? “);
int a = sc.nextInt();
for ( ; a >= 0; a--)
System.out.println(a);

You can also omit all three of the expressions if you want to, as in this example:
for(; ;)
System.out.println(“Oops”);
This program also results in an infinite loop. There’s little reason to do this because while(true)
has the same effect and is more obvious.

54
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The while loop


The while statement continually executes a block of statements while a particular condition is true.

The syntax is:


while (expression) {
statement(s)
}
The while statement evaluates expression, which must return a boolean value. If the expression
evaluates to true, the while statement executes the statement(s) in the while block.
The while statement continues testing the expression and executing its block until the expression
evaluates to false.

Example: printing the values between 1 and 10


public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}

The do loop
Java also provides a do-while statement, which can be expressed as follows:
do {
statement(s)
} while (expression);

The difference between do-while and while is that do-while evaluates its expression at the bottom
of the loop instead of the top. Therefore, the statements within the do block are always executed
at least once, even if the condition is false from the beginning.

Example: display even numbers between 1-100


public static void main(String[] args){
int count = 1;
do {
if(count % 2 == 0)
System.out.println("Count is: " + count);
count++;
} while (count <= 100);
}

55
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Nested Loops
Loops can contain loops in the body of the loop. The technical term for this is nested loop. A nested
loop is simply a loop that is completely contained inside another loop. The loop that’s inside is
called the inner loop, and the loop that’s outside is called the outer loop.

Example: a program that displays multiplication table


int prod = 1;
System.out.print("*\t");
for(int t=1; t<=12; t++) //display column header
System.out.print(t + "\t");
for(int i=1; i<=12; i++) {
System.out.print("\n" + i);
for(int j=1;j<=12; j++) {
prod = i * j;
System.out.print("\t" + prod);
}
}

3.3. Jumping
Java supports three jump statements: break, continue, and return. These statements transfer control
to another part of a program.

The break Statement


By using break statement, you can force immediate termination of a loop, bypassing the
conditional expression and any remaining code in the body of the loop. When a break statement
is encountered inside a loop, the loop is terminated and program control resumes at the next
statement following the loop.

Example: terminate loop if i is 10


public static void main(String args[]) {
for(int i = 0; i < 100; i++) {
if(i == 10)
break;
System.out.println("i: " + i);
}
System.out.println("Loop complete.");
}

56
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The continue Statement


Sometimes it is useful to force an early iteration of a loop. That is, you might want to continue
running the loop, but stop processing the remainder of the code in its body for this particular
iteration. The continue statement performs such an action. In while and do-while loops, a
continue statement causes control to be transferred directly to the conditional expression that
controls the loop. In a for loop, control goes first to the iteration portion of the for statement and
then to the conditional expression. For all three loops, any intermediate code is bypassed.

The continue statement skips the current iteration of a loop and jump to the next iteration.
Example: add number between 0 and 100 excluding numbers from 40-60
double sum = 0;
for(int t = 1; t < 100; t++) {
if(t >= 40 && t <= 60)
continue;
sum = sum + t;
}

57
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Exercise

1. Write a program that accepts a number form user and calculates the factorial of the input. If
the input is n, calculate n! and display the result on console.

2. Write a program that displays prime numbers between 2 and 1000.

3. Write a program that adds the odd integers between 1 and 99 using a for loop structure. Display
the sum on a console.

4. A certain shop sells five different products whose retail prices are as follows: product 1, $2.98;
product 2, $4.50; product 3, $9.98; product 4, $4.49; and product 5, $6.87. Write an application
that reads a pair of numbers as follows:
- product number
- quantity sold for one day
Your program should use a switch structure to help determine the retail price for the product.
It should calculate and display the total price of the item taking quantity into consideration.

5. Write a program that produces the following shape. The output produced by this program is
shown here:
*********
********
*******
******
*****
****
***
**
*

58
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 4
Classes and Objects

What Is an Object?
Objects are key to understanding object-oriented technology. Look around right now and you'll find many
examples of real-world objects: cat, desk, television set, bicycle, book, etc.

Real-world objects share two characteristics: They all have state and behavior. Cats have state (name,
color, breed, hungry, etc) and behavior (meowing, stalking, wagging tail, etc). Bicycles also have state
(current gear, current pedal cadence, current speed) and behavior (changing gear, changing pedal cadence,
applying brakes). Identifying the state and behavior for real-world objects is a great way to begin thinking
in terms of object-oriented programming.

Generally, all objects have three essential features:


• state
• behavior
• identity
An object’s state is what the object knows. An object's state is defined by the attributes of the object and by
the values they have. An attribute is a feature of an object, which distinguishes it from other kinds of objects.
For example, one of the attributes of any cat object is that it has a color.

An attribute is usually something static. This means that it cannot be changed without changing the essential
nature of the object to which it belongs. For example, all cats have the attribute color. Though attributes
themselves are usually static, the value of an attribute is usually dynamic. So you can alter the state of an
object by changing the value of its attributes.

Another characteristic of objects is that they have behavior, which means they can do things. Like state, the
specific behavior of an object depends on its type. But unlike state, the behavior isn’t different for each
instance of a type.

Identity is what makes the object unique. Students have ID no, or an email which is unique. This can identify
one student from the other student object. This is important when implementing the equals method, to
determine if the objects are different or not.

Take a minute right now to observe the real-world objects that are in your immediate area. For each object
that you see, ask yourself two questions: "What possible states can this object be in?" and "What possible
behavior can this object perform?". Make sure to write down your observations. As you do, you will notice
that real-world objects vary in complexity; a lamp in your room may have only two possible states (on and
off) and two possible behaviors (turn on, turn off), but your radio might have additional states (on/off,
current volume, current station) and behavior (turn on, turn off, increase volume, decrease volume, seek,
scan, and tune). You may also notice that some objects, in turn, will also contain other objects. For example,
a car contains tires, engine, seats, etc. These real-world observations all translate into the world of object-
oriented programming.

59
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Software objects are conceptually similar to real-world objects: they too consist of state and behavior. A
software object stores its state in fields (variables in some programming languages) and exposes its behavior
through methods (functions in some programming languages). Methods operate on an object's internal state
and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring
all interaction to be performed through an object's methods is known as data encapsulation — a
fundamental principle of object-oriented programming.

Fig Software object

By attributing state and providing methods for changing that state, the object remains in control of how the
outside world is allowed to use it. For example, if the bicycle only has 6 gears, a method to change gears
could reject any value that is less than 1 or greater than 6.

Fig bicycle object

Bundling code into individual software objects provides a number of benefits, including:
1. Modularity: the source code for an object can be written and maintained independently of the source
code for other objects. Once created, an object can be easily passed around inside the system.
2. Information-hiding: by interacting only with an object's methods, the details of its internal
implementation remain hidden from the outside world.
3. Code re-use: if an object already exists (perhaps written by another software developer), you can
use that object in your program. This allows specialists to implement/test/debug complex, task-
specific objects, which you can then trust to run in your own code.

60
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

4. Plugability and debugging ease: if a particular object turns out to be problematic, you can simply
remove it from your application and plug in a different object as its replacement. This is analogous
to fixing mechanical problems in the real world. If a tyre breaks, you replace it, not the entire
machine.

Classes
A class is the blueprint from which individual objects are created. In real world, you'll often find many
individual objects all of the same kind. For example, there may be thousands of other bicycles in existence,
all of the same make and model. Each bicycle was built from the same set of blueprints and therefore
contains the same components. In object-oriented terms, we say that your bicycle is an instance of the class
of objects known as bicycles.

All classes must be defined by a class declaration that provides the name for the class and the body of the
class. Here’s the most basic form of a class declaration:
[public] class ClassName {
data members;
methods;
}
The public keyword indicates that this class is available for use by other classes. Although it is optional,
you usually include it on your class declarations. After all, the main reason you write class declarations is
so that other classes can create objects from the class.

The ClassName is an identifier that provides a name for your class. You can use any identifier you want to
name a class, but the following three guidelines can simplify your life:
• Begin the class name with a capital letter. If the class name consists of more than one word,
begin each word with capital. For example, Ball, Car, Dog, Bicycle, RetailCustomer, and
GuessingGame.
• Whenever possible, use nouns for your class names. Classes create objects, and nouns are the
words you use to identify objects. Thus, most class names should be nouns.
• Avoid using the name of a Java API class. This is not must, but if you create a class that has the
same name as a Java API class, you have to use fully qualified names (like java.util.Scanner) to tell
your class and the API class with the same name apart.

The data or variables defined within a class are called instance variables or fields. The code is contained
within methods. Collectively, the methods and variables defined within a class are called members of the
class. In most classes, the instance variables are acted upon and accessed by the methods defined for that
class. Thus, it is the methods that determine how a class’ data can be used.

Access Level Modifiers


Access level modifiers determine whether external classes can use a particular field or invoke a particular
method of a class. There are two levels of access control:
• At the top level — public, or package-private (if no explicit modifier specified).
• At the member level — public, private, protected or package-private (if no explicit modifier
specified).

61
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The top level access modifier applies to classes. A class may be declared with the modifier public, in which
case that class is visible to all classes everywhere. But if a class has no modifier (the default, also known
as package-private), it is visible only within its own package.

At the member level, for both fields and methods, you can also use the public modifier or no modifier
(package-private) just as with top-level classes, and with the same meaning. For members, there are two
additional access modifiers: private and protected. The private modifier specifies that the member can only
be accessed in its own class. The protected modifier specifies that the member can only be accessed within
its own package (as with package-private) and, in addition, by a subclass of its class in another package.

The following table shows the access to members permitted by each modifier.
Modifier Package Subclass World
Public Y Y Y
protected Y Y N
no modifier Y N N
Private N N N

The second column indicates whether classes in the same package as the class (regardless of their parentage)
have access to the member. The third column indicates whether subclasses of the class — declared outside
this package — have access to the member. The fourth column indicates whether all classes have access to
the member.

Example: class definition (with package-private access level)


class Rectangle {
public double width;
private double height;
protected double area;
double perimeter; //package-private
}

Data Members
There are several kinds of variables in classes:
• Member variables in a class—these are called fields.
• Variables in a method or block of code—these are called local variables.
• Variables in method declarations—these are called parameters.

A data member is a variable that is defined in the body of a class, outside of any of the class’ methods.
Fields are available to all the methods of a class. In addition, if the data member/field specifies the public
keyword, then it is visible outside of the class. If you don’t want the field to be visible outside of the class,
use the private keyword instead.

Fields are defined the same as any other Java variable, but can have a modifier that specifies whether the
field is public, protected or private.

62
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: public field declarations


public int trajectory = 0;
public String name;
public int age = 20;

To create a private field, specify private instead of public:


private int x_position = 0;
private int y_position = 0;
private String error_message = “”;

Fields can also be declared as final:


public final int MAX_SCORE = 1000;
The value of a final field can’t be changed once it has been initialized.

For local variables and parameters, using access modifier is not allowed. This makes sense since these
variables are already limited in their scope to the method they are defined in. Hence, trying to use access
modifiers when defining local variables and parameters will cause compile error.
Example: the following variable definitions are not allowed
Public void add(public double a, public double b) {
private double sum = a + b;
System.out.println("The sum is " + sum);
}

Constructors
It can be tedious to initialize all of the variables in a class each time an instance is created. Because the
requirement for initialization is so common, Java allows objects to initialize themselves when they are
created. This automatic initialization is performed through the use of a constructor.

A constructor initializes an object immediately upon creation. Thus when we use the new keyword to create
object, the class constructor is called. A constructor has the same name as the class in which it resides and
is syntactically similar to a method. Once defined, the constructor is automatically called immediately after
the object is created, before the new operator completes.

Constructors have no return type, not even void. This is because the implicit return type of a class’s
constructor is the class type itself. It is the constructor’s job to initialize the internal state of an object so
that the code creating an instance will have a fully initialized, usable object immediately.

Broadly, constructors can be divided into three: default constructor, parameterized constructor and copy
constructor. Copy constructor can be seen one type of parameterized constructor.

63
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Default Constructors
If you don’t define a constructor in your class, Java creates one for you. This generated constructor is called
the default constructor. It doesn’t accept any parameters and it doesn’t do anything, but it does allow your
class to be instantiated.

Example: default constructor


public class Rectangle{
double width, height, area, perimeter;
public Rectangle() {
System.out.println("Rectangle is created");
}
}
public class Square {
double width, height, area, perimeter;
}
In the first example, the class explicitly declares a default constructor that doesn’t accept any parameters
and has no statements in its body. In the second example, Java creates a default constructor that works just
like the constructor shown in the first example.

The default constructor is not created if you declare any constructors for the class. As a result, if you declare
a constructor that accepts parameters and still want to have a default constructor, you must explicitly declare
a default constructor for the class.

Example: attempt to create instance of Rectangle class will generate error


public class Rectangle {
public double width, height, area, perimeter;
public Rectangle(double w, double h) {
width = w;
height = h;
}
public static void main(String args[]){
Rectangle rect = new Rectangle(); //error

}
}
This program won’t compile because it doesn’t explicitly provide a default constructor for the Rectangle
class, and because it does provide other constructors, the default constructor isn’t automatically generated.

Parameterized Constructors
A constructor that has parameters is known as parameterized constructor. Parameterized constructor is used
to provide different values to the distinct objects. It initializes the object to the values of the parameter
passed when new keyword is used to create object.

64
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: parameterized constructor


class Student {
String id;
String name;
//parameterized constructor
public Student (String i, String n) {
id = i;
name = n;
}
public void display() {
System.out.println(id + " " + name);
}
public static void main(String args[]) {
Student s1 = new Student(“111/05”, "John Tom");
Student s2 = new Student(“222/04”, "Abebe Bekele");
s1.display();
s2.display();
}
}

Example:
public class Car {
private int numLiters;
private int horsepower;
private String color;
private String model;
private String make;

// a constructor that accepts all state attributes


public Car(String mk, String mdl, int nltr, int hpr) {
this.model = mdl;
this.make = mk;
this.numLiters = nltr;
this.horsepower = hpr;
}
// a constructor that uses parameters and default state values
public Car(int yr, String mk, String mdl) {
this.make = mk;
this.model = mdl;
this.numLiters = 2;
this.horsepower = 200;
this.color = "blue";
this.numDoors = 2;
}
// a default constructor
public Car() {
this.make = "Ford";
this.model = "Focus";
this.horsepower = 200;

65
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

this.color = "blue";
}
public static void main(String args[]) {
Car defaultCar = new Car();
System.out.println("DefaultCar: " + defaultCar);
Car chevy = new Car(2000, "Chevy", "Cavalier");
System.out.println("Chevy: " + chevy);
Car dodge = new Car("Toyota", "Corolla", 5, 400);
System.out.println("Dodge Car: " + dodge);
}
}

The following three car objects are created:

Copy Constructor
Another common form of a constructor is called a copy constructor. A copy constructor is a constructor that
creates a new object as a copy of an existing object. The argument of such a constructor is a reference to an
object of the same type as is being constructed. Once it gets its object argument, it creates a copy of it and
create new object.

Example: copy constructor


class Student{
String id;
String name;
Date birthdate
public Student(String i, String n, Date b){
id = i;
name = n;
birthdate = b;
}
public Student(Student s){
id = s.id;
name =s.name;
birthdate = s.birthdate;

66
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

}
void display(){
System.out.println("ID: " + id);
System.out.println("Name: " + name);
System.out.println("Birthdate: " + birthdate);
}
public static void main(String args[]) {
Student s1 = new Student(“111/05”, "Karan", new Date(1/01/1990));
Student s2 = new Student(s1);
s1.display();
s2.display();
}
}

Calling Constructors
From within a constructor, you can explicitly invoke another constructor from the same class by using the
this() statement. You may want to do this if you have several overloaded constructors in a class, all of which
must execute much of the same code.

Example:
class CoffeeCup {
private int number;
public CoffeeCup() {
this(237); // Calls other constructor
// Could have done more construction here
}
public CoffeeCup(int amount) {
number = amount;
}
}
In this example, the default constructor invokes the other constructor that takes an int as parameter. It passes
237 to the other constructor, which assigns that value to number.

You cannot call this() from methods, only from constructors. If you do call this() in a constructor, you must
call it first, before any other code in the constructor, and you can only call it once. Any code you include
after the call to this() will be executed after the invoked constructor completes.

Destructors
Often, constructors acquire various system resources such as memory. We need a disciplined way to give
resources back to the system when they are no longer needed to avoid resource leaks. The most common
resource acquired by constructors is memory. Java performs automatic garbage collection of memory to
help return memory back to the system. When an object is no longer used in the program (i.e., there are no
references to the object), the object is marked for garbage collection. The memory for such an object can

67
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

be reclaimed when the garbage collector executes. Therefore, memory leaks that are common in other
languages like C and C++ (because memory is not automatically reclaimed in those languages) are less
likely to happen in Java. However, other resource leaks can occur.

To add a destructor to a class, you simply define the finalize( ) method. The Java run time calls that method
whenever it is about to recycle an object of that class. Inside the finalize( ) method you will specify actions
that must be performed before an object is destroyed. The garbage collector runs periodically, checking for
objects that are no longer referenced by any running state or indirectly through other referenced objects.
Right before resource is freed, the Java run time calls the finalize( ) method on the object.

The finalize( ) method has this general form:


protected void finalize( ) {
// finalization code here
}
Here, the keyword protected is a modifier that prevents access to finalize() by code defined outside its
class. It is important to understand that finalize( ) is only called just prior to garbage collection. It is not
called when an object goes out-of-scope immediately. This means that you cannot know when — or even
if — finalize( ) will be executed. Therefore, your program should provide other means of releasing system
resources, etc., used by the object. It must not rely on finalize( ) for normal program operation.

In Java, the tight linkage of the destruction of an object and the calling of its finalize( ) method does not
exist. In Java, objects are not explicitly destroyed when they go out of scope. Rather, an object is marked
as unused when there are no longer any references pointing to it. Even then, the finalize( ) method will not
be called until the garbage collector runs. Thus, you cannot know precisely when or where a call to finalize(
) will occur. Even if you execute a call to the garbage collector, there is no guarantee that finalize( ) will
immediately be executed.

Example: this Java program will fail after 5 calls to f().


class Car {
static final int MAX = 5;
static int count = 0;
public Car() {
if(count < MAX)
count++;
else {
System.out.println("Error -- can't construct");
System.exit(1);
}
}
// finalization
protected void finalize() {
count--;
}
static void f() {

68
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Car ob = new Car(); // create an object


}
public static void main(String args[]) {
for(int i=0; i < (MAX*2); i++) {
f();
System.out.println("Current count is: " + count);
}
}
}
This program will fail after five calls to f( ), as this output shows:
Current count is: 1
Current count is: 2
Current count is: 3
Current count is: 4
Current count is: 5
Error — can’t construct

The reason the program fails is that garbage collection does not occur each time f( ) returns. Thus, finalize(
) is not invoked, and the value of count is not decremented. After five calls to the method, count reaches
its maximum value and the program fails.

Instantiating Objects
When you create a class, you are creating a new data type. You can use this type to declare objects of that
type. However, obtaining objects of a class is a two-step process. First, you must declare a variable of the
class type. This variable does not define an object. Instead, it is simply a variable that can refer to an object.
Second, you must acquire an actual, physical copy of the object and assign it to that variable. You can do
this using the new operator. The new operator dynamically allocates (that is, allocates at run time) memory
for an object and returns a reference to it. This reference is the address in memory of the object allocated
by new. This reference is then stored in the variable. Thus, in Java, all class objects must be dynamically
allocated.

It is important to understand that new allocates memory for an object during run time. The advantage of
this approach is that your program can create as many or as few objects as it needs during the execution of
your program. However, since memory is finite, it is possible that new will not be able to allocate memory
for an object because insufficient memory exists. If this happens, a run-time exception will occur. For the
sample programs in this handout, you won’t need to worry about running out of memory, but you will need
to consider this possibility in real-world programs that you write.

It has this general form for object creation is:


classname objname = new classname( );

69
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Here, objname is a variable of the class type being created. The classname is the name of the class that is
being instantiated. The class name followed by parentheses specifies the constructor for the class. A
constructor defines what occurs when an object of a class is created.

Example: defining the class


public class Rectangle {
double width, height;
double area;
public void calcArea() {
area = widt * height;
}
}

Example: creating instance of Rectangle class


Rectangle myrect; // declare reference to object
myrec = new Rectangle(); // allocate a Rectangle object

You can combine the two steps into one as follows:


Rectangle myrect = new Rectangle();

The first line declares myrect as a reference to an object of type Rectangle. After this line executes, myrect
contains the value null, which indicates that it does not yet point to an actual object. Any attempt to use
myrect at this point will result in a compile-time error. The next line allocates an actual object and assigns
a reference to it to myrect.

After the second line executes, you can use myrect as if it were a Rectangle object. But in reality, myrect
simply holds the memory address of the actual Rectangle object. The effect of these two lines of code is
depicted in the figure below.

70
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Statement Effect

null
Rectangle myrect;
myrect

myrect = new Rectangle() width

myrect
height

area

Rectangle object

Fig declaring an object of type Rectangle

Assigning Object Reference Variables


Object reference variables act differently than you might expect when an assignment takes place. For
example, what do you think the following fragment does?
Rectangle b1 = new Rectangle ();
Rectangle b2 = b1;
You might think that b2 is being assigned a reference to a copy of the object referred to by b1. That is, you
might think that b1 and b2 refer to separate and distinct objects. However, this would be wrong. Instead,
after this fragment executes, b1 and b2 will both refer to the same object. The assignment of b1 to b2 did
not allocate any memory or copy any part of the original object. It simply makes b2 refer to the same object
as does b1. Thus, any changes made to the object through b2 will affect the object to which b1 is referring,
since they are the same object.

This situation is depicted here:

width
b1
height

area
b2
Rectangle object

Although b1 and b2 both refer to the same object, they are not linked in any other way. For example, a
subsequent assignment to b1 will simply unhook b1 from the original object without affecting the object or
affecting b2. For example:

71
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Rectangle b1 = new Rectangle ();


Rectangle b2 = b1;
// ...
b1 = null;
Here, b1 has been set to null, but b2 still points to the original object.

Accessing Members
To access data members and methods of classes using objects, we use the dot(.) operator. This is the only
way to access members of class since Java does not support pointers. This has the general format like:
objectname.field;
objectname.method();

Example: accessing data members and methods


Rectangle b1 = new Rectangle ();
System.out.println(b1.width);
System.out.println(b1.height);
b1.calcArea();
System.out.println(b1.area);

Static Members
Static members are a special type of field or method that isn’t associated with a particular instance of a
class. Instead, static fields and methods are associated with the class itself. That means you don’t have to
create an instance of the class to access a static field or methods. You access a static field or method by
specifying the class name, not a variable that references an object.

To create such a member, precede its declaration with the keyword static. When a member is declared
static, it can be accessed before any objects of its class are created, and without reference to any object.
You can declare both methods and variables to be static. The most common example of a static member is
main( ). main( ) is declared as static because it must be called before any objects exist.

Instance variables declared as static are, essentially, like global variables. When objects of its class are
declared, no copy of a static variable is made. Instead, all instances of the class share the same static
variable.

Static Fields
Each object of a class has its own copy of all the instance variables of the class. In certain cases, only one
copy of a particular variable should be shared by all objects of a class. A static class variable is used for
these and other reasons. A static class variable represents class-wide information—all objects of the class
share the same piece of data. The declaration of a static member begins with the keyword static.

A static field is declared with the static keyword, like this:


[access modifier]static type identifier [= value];

72
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example:
public class Rectangle {
private static int rectangleCount;

}

The position of the static and access modifiers are interchangeable. As a result, the following statement
works as well:
static private int rectangleCount;
As a convention, most programmers tend to put the visibility keyword first.

Local variables can’t be defined as static variables. It is not possible to use the static keyword within a class
method. Thus, the following code won’t compile:
public class Rectangle {
static private void calcArea() {
static int x;
}
}
In other words, fields can be static, but local variables can’t.

Obviously, constructors can’t initialize static field members. So, one question that may arise is when are
the static variables initialized? Static fields are created and initialized when the class is first loaded. That
happens when a static member of the class is referred to or when an instance of the class is created,
whichever comes first. Another way to initialize a static field is to use a static initializers.

Static Initializers
Java provides a feature called a static initializer that’s designed specifically to let you initialize static fields.
The general form of a static initializer is this:
static {
statements...
}
As you can see, a static initializer is similar to an initializer block, but begins with the word static. Like an
initializer block, you code static initializers in the class body but outside of any other block, such as the
body of a method or constructor.

The first time you access a static member such as a static field or a static method, any static initializers in
the class are executed provided you haven’t already created an instance of the class. That’s because the
static initializers are also executed the first time you create an instance. In that case, the static initializers
are executed before the constructor is executed.

Example: static initializers


class Rectangle {
public static int x;

73
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

static {
x = 32;
}
// other class members such as constructors and methods go here...
}

Static Methods
A static method is a method declared with the static keyword. Like static fields, static methods are
associated with the class itself, not with any particular object created from the class. As a result, you don’t
have to create an object from a class before you can use static methods defined by the class.

The best-known static method is main, which is called by the JVM to start an application. The main method
must be static, which means that applications are by default run in a static context.

Outside of the class in which they are defined, static methods and variables can be used independently of
any object. To do so, you need only specify the name of their class followed by the dot operator. For
example, if you wish to call a static method from outside its class, you can do so using the following general
form:
classname.method([argument])
Here, classname is the name of the class in which the static method is declared. As you can see, this format
is similar to that used to call non-static methods through object-reference variables except that here we are
using the name of the class instead of object name.

A static variable can be accessed in the same way—by use of the dot operator on the name of the class.
This is how Java implements a controlled version of global methods and global variables.

Methods declared as static have several restrictions:


• They can only call other static methods.
• They can only access static data.
• They cannot refer to this or super in any way.

Example:
class Rectangle {
static int width = 42;
static int height = 99;
static void display() {
System.out.println("width = " + width);
System.out.println("height = " + height);
}
}
class ABC {
public static void main(String args[]) {
Rectangle.display();
System.out.println("width = " + Rectangle.width);

74
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

}
}

Static methods can’t access instance (non-static) data members. For example, the following code generates
error (static can’t access member)
public class TestClass {
private int x = 5; // an instance field
public static void main(String[] args) {
int y = x; // error: won’t compile
}
}

Even if the static members can’t access instance field and methods, you can access static methods and fields
from an instance method. For example, the following code works fine:
public class Invoice {
private static double vatRate = 0.15;
private double itemPrice;
public double computeTax() {
return itemPrice * vatRate;
}
}

Common Application of Static members


A. Counting Instances
One common use for static variables is to keep track of how many instances of a class have been created.

Example:
public class Car {
private static int carCount = 0;
public Car() {
carCount++;
}
private static void printCount() {
System.out.println("There are now " + carCount + " cars.");
}
public static void main(String[] args) {
printCount();
for (int i = 0; i < 10; i++) {
Car c1 = new Car();
printCount();
}
}
}

75
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

B. The Singleton Pattern


A singleton is a class that you can use to create only one instance. When you try to create an instance, the
class first checks to see if an instance already exists. If so, the existing instance is used. If not, a new instance
is created.

You can’t achieve this effect by using Java constructors, because a class instance has already been created
by the time the constructor is executed. That’s why you can use the this keyword from within a constructor.
As a result, the normal way to implement a singleton class is to declare all the constructors for the class as
private. That way, the constructors aren’t available to other classes.

Then, you provide a static method that returns an instance. This method either creates a new instance or
returns an existing instance. Here’s a barebones example of a singleton class:
class Triangle {
private static Triangle instance;
private Triangle() { }
public static Triangle getInstance() {
if (instance == null)
instance = new Triangle();
return instance;
}
}

Here, the Triangle class contains a private instance variable that maintains a reference to an instance of the
class. Then, a default constructor is declared with private visibility to prevent the constructor from being
used outside of the class. Finally, the static getInstance() method calls the constructor to create an instance
if the instance variable is null. Then, it returns the instance to the caller.

Here’s a bit of code that calls the getInstance() method twice, and then compares the resulting
objects:
Triangle s1 = Triangle.getInstance();
Triangle s2 = Triangle.getInstance();
if (s1 == s2)
System.out.println("The objects are the same");
else
System.out.println("The objects are not the same");
When this code is run, the first call to getInstance creates a new instance of the Triangle class. The second
call to getInstance simply returns a reference to the instance that was created in the first call. As a result,
the comparison in the if statement is true, and the first message is printed to the console.

Example: singleton for Student class


class Student {
private static Student stud;
public String ID;

76
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

public String fullname;


public String birthdate;
private Student() { }
public static Student getInstance() {
if (stud == null)
stud = new Student();
return stud;
}
}
class TestSingleton {
public void createStudent() {
Student st1 = Student.getInstance();
st1.ID = "321/04";
st1.fullname = "John Vilanova";
st1.birthdate = "01/02/1980";
Student st2 = Student.getInstance();
System.out.println(st1.ID + " " + st1.fullname + " " + st1.birthdate);
System.out.println(st2.ID + " " + st2.fullname + " " + st2.birthdate);
}
public static void main(String args[]) {
TestSingleton ts = new TestSingleton();
ts.createStudent();
}
}

C. Preventing Instances
Sometimes, you want to create a class that can’t be instantiated at all. Then, the class consists entirely of
static fields and methods. A good example in the Java API is the Math class. Its methods provide utility-
type functions that aren’t really associated with a particular object.

You may occasionally find the need to create similar classes yourself. For example, you might create a class
with static methods for validating input data. Or, you might create a database access class that has static
methods to retrieve data from a database. You don’t need to create instances of either of these classes.

You can use a simple trick to prevent anyone from instantiating a class. To create a class instance, you have
to have at least one public constructor. If you don’t provide a constructor in your class, Java automatically
inserts a default constructor, which is public. All you have to do to prevent a class instance from being
created, then, is to provide a single private constructor, like this:
public class Validation {
private Validation() {} // prevents instances
public static boolean isValidName(String name) {
//name should contain only A-Z, a-z
for(int t=0; t<name.length(); t++) {
if (name.charAt(t) >=65 && name.charAt(t) <= 90) //capital letters

77
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

continue;
else if (name.charAt(t) >=97 && name.charAt(t) <= 122) //small letters
continue;
else
return false;
}
return true;
}
}
Now, because the constructor is private, the class can’t be instantiated.

The this Reference


Java conserves storage by maintaining only one copy of each method per class; this method is invoked by
every object of that class. Each object, on the other hand, has its own copy of the class’s instance variables.

When a method of a class references data member of a specific object of that class, how does Java ensure
that the proper object is referenced? If you have two objects of the same type called a and b, you might
wonder how it is that you can call a method foo( ) for both those objects:
class Banana {
void foo(int i) { /* ... */ }
public static void main(String args[]) {
Banana a = new Banana(), b = new Banana();
a.foo(1);
b.foo(2);
}
}
If there’s only one method called foo(), how can that method know whether it is being called for the object
a or b?

The answer is that each object has access to a reference to itself—called the this reference. The this
reference is used implicitly to refer to both the instance variables and methods of an object.

So, when a method needs to refer to the object that invoked it, it can use the this reference. this can be used
inside any method to refer to the current object. That is, this is always a reference to the object on which
the method was invoked. You can use this anywhere a reference to an object of the current class’ type is
permitted.

To allow you to write the code in a convenient object-oriented syntax, the compiler does some undercover
work for you. There is a secret first argument passed to the method foo(), and that argument is the reference
to the object that is being manipulated. So the two method calls above become something like:
Banana.foo(a, 1);
Banana.foo(b, 2);

78
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

This is internal and you can’t write these expressions and get the compiler to accept them, but it gives you
an idea of what’s happening.

Suppose you are inside a method and you’d like to get the reference to the current object. Since that
reference is passed secretly by the compiler, there’s no identifier for it. However, for this purpose there is
a keyword: this. The this keyword—which can be used only inside a method—produces the reference to
the object the method has been called for. You can treat this reference just like any other object reference.

this can be used inside any method to refer to the current object. That is, this is always a reference to the
object on which the method was invoked. You can use this anywhere a reference to an object of the current
class’s type is permitted.

The this keyword is usually used to qualify references to instance variables of the current object. For
example:
public calss Employee {
String firstName;
String lastName;
public Employee(String last, String first) {
this.lastName = last;
this.firstName = first;
}
}

Here, this isn’t really necessary because the compiler can tell that lastName and firstName refer to class
variables. However, suppose you use lastName and firstName as the parameter names for the constructor:
public Employee(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
Here, the this keywords are required to distinguish between the parameters named lastName and firstName
and the instance variables with the same names.

Inner Classes and Anonymous Inner Classes


A. Inner Classes
It is possible to define a class within another class; such classes are known as nested classes. The scope of
a nested class is bounded by the scope of its enclosing class. Thus, if class B is defined within class A, then
B is known to A, but not outside of A. A nested class has access to the members, including private members,
of the class in which it is nested. However, the enclosing class does not have access to the members of the
nested class.

The most important type of nested class is the inner class. An inner class is a non-static nested class. It has
access to all of the variables and methods of its outer class and may refer to them directly in the same way

79
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

that other non-static members of the outer class do. Thus, an inner class is fully within the scope of its
enclosing class.

An inner class is simply a class that is contained inside another class. However, there is more to it than that.
Here are some key points about inner classes:
• An inner class automatically has access to all the fields and methods of the outer class — even
private fields and methods. Thus, an inner class has more access to its outer class than a subclass
has to its superclass.
• An inner class carries with it a reference to the current instance of the outer class that enables it to
access instance data for the outer class.
• Because of the outer class instance reference, you can’t create or refer to an inner class from a static
method of the outer class. You can, however, create a static inner class.
• One of the main reasons for creating an inner class is to create a class that is only of interest to the
outer class. As a result, you usually declare inner classes to be private so other classes can’t access
them.

Declaring Inner Classes


The basic structure for creating an inner class is as follows:
class outerClassName {
//body of outer class
[private|protected|public] class innerClassName {
// body of inner class
}
}
The class that contains the inner class is called an outer class. You can use a visibility modifier with the
inner class to specify whether the class should be public, protected, or private. This visibility determines
whether other classes can see the inner class.

The outer class first has to create instance of the inner class before using it. Just like it is necessary to create
instance of any other classes, the same is true for inner classes. Since inner classes are visible outside of
outer class, it is the outer class that creates instance of the inner class.

Example: employee information and address


import java.util.Date;
public class Employee {
public String name = "Charles";
public String sex;
public float salary;
public Date birthDate;
public Address address;
public Employee(String aName, String aSex, int aSalary, Date aBirthDate, int num, String st, String ct)
{
name = aName;
sex = aSex;
birthDate = aBirthDate;

80
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

salary = aSalary;
address = new Address(num, st, ct);
}
void printDetails() {
System.out.println("Name: " + name + " \nSex: " + sex + " \nBirth date: " + birthDate +
" \nSalary:" + salary);
}

// inner class
class Address {
int number = 0;
String street = "";
String city = "";
Address(int num, String aStreet, String aCity) {
number = num;
street = aStreet;
city = aCity;
}
void printDetails() {
System.out.println("Address: " + number + " " + street + " , " + city);
}
}

public static void main(String[] args) {


Employee emp1 = new Employee("Bob", "Male", 5000, new Date(10/12/1980), 33,
"Lane Street", "Springfield");
Employee emp2 = new Employee("Rosa", "Female", 6000, new Date(10/12/1980),
123, "Pop Street", "Lancing");
emp1.printInformation();
emp2.printInformation();
}
public void printInformation() {
printDetails();
address.printDetails();
System.out.println();
}
}

Occasionally, code in an inner class needs to refer to the instance of its outer class. To do that, you list the
name of the outer class followed by the dot operator and this. For example, if Address class wants to access
instance of Employee class, then it goes like:
Employee.this.methodname(); //to access methods
Employee.this.fieldname; //to access data members

81
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: more example of inner class


Class Airplane {
//create instances of inner class
Engine en = new Engine();
Wing wn = new Wing();
LandingGear lg = new LandingGear();

class Engine {
//code here
}
class Wing {
//code here
}
Class LandingGear {
//code here
}
}

B. Anonymous Inner Classes


An anonymous inner class is an inner class that is not given a name. An anonymous class is a class that is
defined on the spot, right at the point where you want to instantiate it. Because you code the body of the
class right where you need it, you don’t have to give it a name. That’s why it is called an anonymous class.

Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate
a class at the same time. They are like local classes except that they do not have a name. Use them if you
need to use a local class only once.

Creating an anonymous class


The basic form for declaring and instantiating an anonymous class is this:
new ClassOrInterface() {
class-body
}
As you can see, you specify the new keyword followed by the name of a class or interface that specifies the
type of the object created from the anonymous class. This class or interface name is followed by
parentheses, which may include a parameter list that’s passed to the constructor of the anonymous class.
Then, you code a class body enclosed in braces. This class body can include anything a regular class body
can include: fields, methods, even other classes or interfaces.

Example: creating anonymous inner class


class Engine {
public void start() { }

82
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

}
public class Car {
//anonymous inner class definition
Engine en = new Engine() {
float maxSpeed = 100; //100km per hour
public void start() {
System.out.println(“Engine starting…”);
}
};
public void startEngine() {
en.start();
}
public static void main(String[] args) {
Car cr = new Car();
cr.startEngine();
}
}

Here are some things that you should keep in mind when you work with anonymous classes:
• You can’t create a constructor for an anonymous class. Because the anonymous class doesn’t have
a name, there is no way to you call the constructor anyway.
• If you list parameters in the parentheses following the class name, Java looks for a constructor in
the base class that matches the parameters you supply. If it finds one, that constructor is called with
the parameters. If not, a compiler error is generated.
• You can’t pass parameters if the anonymous class is based on an interface. That only makes sense,
because interfaces don’t have constructors so Java wouldn’t have anything to pass the parameters
to.
• An anonymous class is a special type of inner class. So, like any inner class, it automatically has
access to the fields and methods of its outer class.
• An anonymous class can’t be static.

Anonymous class is simply a subclass


Anonymous inner classes are a way of creating subclasses of other classes with a short approach. So what
is happening exactly in the code above is that we are creating an object of Subclass with a reference variable
of superclass. After creating, the class object becomes a subclass of the superclass being instantiated.

The code on the left is a short form of the code on the right.

83
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Engine en = new Engine() { Class CarEngine extends Engine {


float maxSpeed = 100f; //100km per hour float maxSpeed = 100f; //100km per hour
public void start() { public void start() {
System.out.println(“Engine starting…”); System.out.println(“Engine starting…”);
} }
}; }
CarEngine en = new CarEngine();

Since anonymous inner classes are sub classes, they can be created in two ways: using a class or using an
interface. The engine example given above uses a class defined outside the car class to create anonymous
inner class inside car class.

Example: anonymous inner class created using interface


public interface CarBattery {
public void recharge();
}
public class Car {
//An anonymous inner class that implements CarBattery interface
CarBattery cb = new CarBattery() {
public void recharge() {
System.out.println(“Battery is recharging…”);
}
};
public void startCar() {
//code here
}
}

When to Use an Anonymous Class


As discussed above, an anonymous class behaves just like a local class and is distinguished from a local
class merely in the syntax used to define and instantiate it. In your own code, when you have to choose
between using an anonymous class and a local class, the decision often comes down to a matter of style.
You should use whichever syntax makes your code clearer. In general, you should consider using an
anonymous class instead of a local class if:
• The class has a very short body.
• Only one instance of the class is needed.
• The class is used right after it is defined.
• The name of the class does not make your code any easier to understand.

Anonymous inner classes are usually used for creating event handling code in Java. In GUI based Java
applications, to respond to events like button click, menu selection, etc, we can use anonymous classes.

84
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Built-in Classes

1. String Class
Implementing strings as built-in objects allows Java to provide a full complement of features that make
string handling convenient. For example, Java has methods to compare two strings, search for a substring,
concatenate two strings, change the case of letters within a string, etc. Also, String objects can be
constructed a number of ways, making it easy to obtain a string when needed.

In Java, String object is immutable i.e. once a String object has been created, you cannot change its content.
Naturally, this may seem to be a serious restriction. However, this is not the case and you can still perform
all types of string operations. Each time you need an altered version of an existing string, a new String
object is created that contains the modifications. The original string is left unchanged. This approach is used
because fixed, immutable strings can be implemented more efficiently than changeable ones.

For those cases in which a modifiable string is desired, there is a companion class to String called
StringBuffer, whose objects contain strings that can be modified after they are created. Both the String
and StringBuffer classes are defined in java.lang. Both are declared final, which means that neither of
these classes may be subclassed. This allows certain optimizations that increase performance to take place
on common string operations.

String Class Constructors


The String class supports several constructors. To create an empty String, you call the default constructor.
For example,
String s = new String();
will create an instance of String with no characters in it.

Frequently, you will want to create strings that have initial values. The String class provides a variety of
constructors to handle this. To create a String initialized by an array of characters, use the constructor
shown here:
String(char chars[ ])

Here is an example:
char chars[] = { 'a', 'b', 'c' };
String s = new String(chars);
This constructor initializes s with the string “abc”.

You can specify a subrange of a character array as an initializer using the following constructor:
String(char chars[ ], int startIndex, int numChars)
Here, startIndex specifies the index at which the subrange begins, and numChars specifies the number of
characters to use. Here is an example:
char chars[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
String str = new String(chars, 2, 3);

85
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

This initializes str with the characters cde.

You can construct a String object that contains the same character sequence as another String object using
this constructor:
String(String strObj)

Methods of String Class


The String class has a number of methods for comparing strings and portions of strings. The following table
lists these methods.
Method Description
boolean endsWith(String suffix) Returns true if this string ends with or begins with the
boolean startsWith(String prefix) substring specified as an argument to the method.

Considers the string beginning at the index offset, and


boolean startsWith(String prefix, int
returns true if it begins with the substring specified as an
offset)
argument.

Compares two strings lexicographically. Returns an integer


int compareTo(String str2) indicating whether this string is greater than (result is > 0),
equal to (result is = 0), or less than (result is < 0) the argument.

Compares two strings lexicographically, ignoring differences


in case. Returns an integer indicating whether this string is
int compareToIgnoreCase(String str)
greater than (result is > 0), equal to (result is = 0), or less than
(result is < 0) the argument.

Returns true if and only if the argument is a String object that


boolean equals(Object anObject)
represents the same sequence of characters as this object.

Returns true if and only if the argument is a String object that


boolean equalsIgnoreCase(String
represents the same sequence of characters as this object,
anotherString)
ignoring differences in case.

Tests whether the specified region of this string matches the


boolean regionMatches(int toffset, specified region of the String argument.
String other, int ooffset, int len) Region is of length len and begins at the index toffset for this
string and ooffset for the other string.

86
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Tests whether the specified region of this string matches the


specified region of the String argument string.
boolean regionMatches(boolean
Region is of length len and begins at the index toffset for this
ignoreCase, int toffset, String other,
string and ooffset for the other string.
int ooffset, int len)
The boolean argument indicates whether case should be
ignored; if true, case is ignored when comparing.

Tests whether this string matches the specified regular


boolean matches(String regex)
expression.

The following table describes the various string search methods.


Method Description
int indexOf(int ch) Returns the index of the first (last) occurrence of the
int lastIndexOf(int ch) specified character.

Returns the index of the first (last) occurrence of the


int indexOf(int ch, int fromIndex)
specified character, searching forward (backward) from
int lastIndexOf(int ch, int fromIndex)
the specified index.

int indexOf(String str) Returns the index of the first (last) occurrence of the
int lastIndexOf(String str) specified substring.

Returns the index of the first (last) occurrence of the


int indexOf(String str, int fromIndex)
specified substring, searching forward (backward) from
int lastIndexOf(String str, int fromIndex)
the specified index.
Returns true if the string contains the specified character
boolean contains(CharSequence s)
sequence.

The String class has four methods for replacing characters or substrings.
Method Description
String replace(char oldChar, char Returns a new string resulting from replacing all occurrences of
newChar) oldChar in this string with newChar.

String replace(CharSequence
Replaces each substring of this string that matches the literal
target, CharSequence
target sequence with the specified literal replacement sequence.
replacement)

String replaceAll(String regex, Replaces each substring of this string that matches the given
String replacement) regular expression with the given replacement.

String replaceFirst(String regex, Replaces the first substring of this string that matches the given
String replacement) regular expression with the given replacement.

87
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Other methods of String class:


Method Description
Searches for a match as specified by the string argument
String[] split(String regex) (which contains a regular expression) and splits this string into
String[] split(String regex, int limit) an array of strings accordingly. The optional integer argument
specifies the maximum size of the returned array.
CharSequence subSequence(int Returns a new character sequence constructed
beginIndex, int endIndex) from beginIndex index up untilendIndex - 1.
Returns a copy of this string with leading and trailing white
String trim()
space removed.
Returns a copy of this string converted to lowercase or
String toLowerCase()
uppercase. If no conversions are necessary, these methods
String toUpperCase()
return the original string.
Returns a new string that is a substring of this string. The first
String substring(int beginIndex, int integer argument specifies the index of the first character. The
endIndex) second integer argument is the index of the last character
returned + 1.
Returns a new string that is a substring of this string. The
integer argument specifies the index of the first character.
String substring(int beginIndex)
Here, the returned substring extends to the end of the original
string.
char charAt(int index) Returns the character at the specified position in the string.
static String valueOf(double num)
static String valueOf(long num) Return the value of argument converted into string. It is used
static String valueOf(Object ob) to convert other data types into string.
static String valueOf(char chars[ ])
int length() Returns the number of characters in the String

Finding length of a string


One of the most basic string operations is determining the length of a string. You do that with the length
method. For example:
String s = "wonderful day";
int len = s.length();
Here, len is assigned a value of 13 because the string s consists of 13 characters.

String Modifications
The trim method removes white space characters (spaces, tabs, newlines, and so on) from the start and end
of a word. For example:
String s = " Umpa Lumpa "; //space at the beginning and end
s = s.trim();

88
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Several of the methods of the String class return modified versions of the original string. The toLowerCase()
method converts a string to all lowercase letters. The toUpperCase method works the same, but converts
strings to all uppercase letters.
String t, u;
String s = "Umpa Lumpa";
t = s.toLowerCase();
u = s.toUpperCase();
System.out.println(t + " " + u); //umpa lumpa UMPA LUMPA

Extracting characters from a string


You can use the charAt() method to extract a character from a specific position in a string. When you do,
keep in mind that the index number for the first character in a string is 0, not 1.

Example: counting the number of vowels in a string


String s = "The beautiful ones are not born yet";
int vowelCount = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if ( (c == 'A') || (c == 'a') || (c == 'E') || (c == 'e') || (c == 'I') || (c == 'i') ||
(c == 'O') || (c == 'o') || (c == 'U') || (c == 'u') )
vowelCount++;
}
System.out.println("That string contains "+ vowelCount + " vowels.");

Extracting substrings from a string


The substring method lets you extract a portion of a string. This method has two forms. The first accepts a
single integer parameter. It returns the substring that starts at the position indicated by this parameter and
extending to the rest of the string. Remember that string positions start with 0, not 1.

Example: extracting substring from a string


String s = "Baseball game";
String b = s.substring(4); //ball game
String c = s.substring(0, 8); //Baseball

Example: substring of a string


String str = "coffee";
System.out.println(str.substring(3));

The index of the first character in a string is 0 and hence the above code returns fee starting from index 3
untill the end of the string.
c o f f e e
0 1 2 3 4 5

89
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: substring of a string


String str = "supporting";
System.out.println(str.substring(3, 7));
The string returned by substring() would be "port" which is in between index 3 and 7, not including
character at index 7.
s u p p o r t i n g
0 1 2 3 4 5 6 7 8 9

Searching Strings
The String class provides two methods that allow you to search a string for a specified character or
substring: indexOf( ) and lastIndexOf( ). indexOf() starts searching from beginning of the string and goes
till the end of the string. lastIndexOf() on the other hand begins from the end of the string and goes till the
beginning of the string.

Example:
String s = "Now is the time for all good men to come to the aid of their country.";
System.out.println(s);
System.out.println("indexOf(t) = " + s.indexOf('t'));
System.out.println("lastIndexOf(t) = " + s.lastIndexOf('t'));
System.out.println("indexOf(the) = " + s.indexOf("the"));
System.out.println("lastIndexOf(the) = " + s.lastIndexOf("the"));
System.out.println("indexOf(t, 10) = " + s.indexOf('t', 10));
System.out.println("lastIndexOf(t, 60) = " + s.lastIndexOf('t', 60));
System.out.println("indexOf(the, 10) = " + s.indexOf("the", 10));
System.out.println("lastIndexOf(the, 60) = " + s.lastIndexOf("the", 60));

Output:
Now is the time for all good men to come to the aid of their country.
indexOf(t) = 7
lastIndexOf(t) = 65
indexOf(the) = 7
lastIndexOf(the) = 55
indexOf(t, 10) = 11
lastIndexOf(t, 60) = 55
indexOf(the, 10) = 44
lastIndexOf(the, 60) = 55

Replacing parts of a string


You can use the replaceFirst() or replaceAll() methods to replace a part of a string that matches a pattern
you supply with some other text. For example, here’s the main method of a program that gets a line of text
from the user, and then replaces all occurrences of the string cat with dog:
String s = "I love cats. Cats are the best";
s = s.replaceAll("cat", "dog");

90
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println(s); // I love dogs. dogs are the best

String Comparison
The String class includes several methods that compare strings or substrings within strings. To compare
two strings for equality, use equals( ). It has this general form:
boolean equals(Object str)
Here, str is the String object being compared with the invoking String object. It returns true if the strings
contain the same characters in the same order, and false otherwise. The comparison is case-sensitive.

To perform a comparison that ignores case differences, call equalsIgnoreCase( ). When it compares two
strings, it considers A-Z to be the same as a-z. It has this general form:
boolean equalsIgnoreCase(String str)

Example: string comparison


String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " + s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " + s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " + s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " + s1.equalsIgnoreCase(s4));

equals( ) versus ==
It is important to understand that the equals( ) method and the == operator perform two different operations.
As just explained, the equals( ) method compares the characters inside a String object. The == operator
compares two object references to see whether they refer to the same instance. The following program
shows how two different String objects can contain the same characters, but references to these objects
will not compare as equal:
String s1 = "Hello";
String s2 = new String(s1);
System.out.println(s1 + " equals " + s2 + " -> " + s1.equals(s2));
System.out.println(s1 + " == " + s2 + " -> " + (s1 == s2));
The contents of the two String objects are identical, but they are distinct objects. This means that s1 and s2
do not refer to the same objects and are, therefore, not ==.

compareTo( )
Often, it is not enough to simply know whether two strings are identical. For sorting applications, you need
to know which is less than, equal to, or greater than the other. A string is less than another if it comes
before the other in alphabetical order. A string is greater than another if it comes after the other in
alphabetical order. The String method compareTo( ) and compareToIgnoreCase() serves this purpose. It
has this general form:
int compareTo(String str);
int compareToIgnoreCase(String str);

91
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: bubble sort


class SortString {
static String arr[] = {"Now", "is", "the", "time", "for", "all", "good", "men", "to", "come", "to",
"the", "aid", "of", "their", "country" };
public static void main(String args[]) {
for(int j = 0; j < arr.length; j++) {
for(int i = j + 1; i < arr.length; i++) {
if(arr[i].compareTo(arr[j]) < 0) {
String t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}

System.out.println(arr[j]);
}
}
}

2. Math Class
Java’s built-in operators are useful, but they don’t come anywhere near providing all the mathematical
needs of most Java programmers. That’s where the Math class comes in. It includes a bevy of built-in
methods that perform a wide variety of mathematical calculations, from basic functions such as calculating
an absolute value or a square root to trigonometry functions such as sin and cos, to practical functions such
as rounding numbers or generating random numbers.

Math class methods allow the programmer to perform certain common mathematical calculations.

Constants of Math Class


Math class defines two constants: PI and E.
Constant Description Value

Math.PI The constant Pi (π), the ratio of a circle’s radius and 3.141592653589793
diameter

Math.E The base of natural logarithms 2.718281828459045

Methods
The Math class provides many built-in methods. You can use these functions to calculate such things as the
absolute value of a number, the minimum and maximum of two values, square roots, powers, and
logarithms

92
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Method Description

static double sin(double arg) Returns the sine of the angle specified by arg in radians.
static double cos(double arg) Returns the cosine of the angle specified by arg in radians.
static double tan(double arg) Returns the tangent of the angle specified by arg in radians.
static double asin(double arg) Returns the angle whose sine is specified by arg.
static double acos(double arg) Returns the angle whose cosine is specified by arg.
static double atan(double arg) Returns the angle whose tangent is specified by arg.
static double exp(double arg) Returns e raised to the arg.
static double log(double arg) Returns the natural logarithm of arg.
Returns the base 10 logarithm of the argument. The
static double log10(argument)
argument and the return value are doubles.
Returns y raised to the x;
static double pow(double y, double x)
Math.pow(2.0, 3.0); //8.0
static double sqrt(double arg) Returns the square root of arg.
Returns the cube root of the argument. The argument and
static double cbrt(argument)
return value are doubles.

More Math Functions


Method Description

abs(number arg) Returns the absolute value of arg.


static double ceil(double arg) Returns the smallest integer greater or equal to arg.
static double floor(double arg) Returns the largest integer less than or equal to arg.
static double max(double x, double y) Returns the maximum of x and y.
static double min(double x, double y) Returns the minimum of x and y.
static double rint(double arg) Returns the integer nearest in value to arg.
static int round(float arg) Returns arg rounded up to the nearest int.
static long round(double arg) Returns arg rounded up to the nearest long.
static double random( ) returns a pseudorandom number
static double toRadians(double angle) method converts degrees to radians
static double toDegrees(double angle) converts radians to degrees
static double IEEEremainder(double
returns the remainder of dividend/divisor.
dividend, double divisor)

93
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

random( ) returns a pseudorandom number. This value will be between 0 and 1. Most of the time, you will
use the Random class when you need to generate random numbers. If you want to generate random
numbers between 0 – 1000, multiply the result by 1000.

Example:
public class MathClassTest {
public static void main(String[] args) {
int a = 100;
int b = -50;
int c = 3;
double x = 25.0;
double y = 3.0;
double z = 4.0;

System.out.println("abs(b) = " + Math.abs(b));


System.out.println("cbrt(x) = " + Math.cbrt(x));
System.out.println("exp(y) = " + Math.exp(z));
System.out.println("hypot(y,z)= " + Math.hypot(y,z));
System.out.println("log(y) = " + Math.log(y));
System.out.println("log10(y) = " + Math.log10(y));
System.out.println("max(a, b) = " + Math.max(a, b));
System.out.println("min(a, b) = " + Math.min(a, b));
System.out.println("pow(a, c) = " + Math.pow(a, c));
System.out.println("random() = " + Math.random());
System.out.println("signum(b) = " + Math.signum(b));
System.out.println("sqrt(x) = " + Math.sqrt(y));
}
}

The random method generates a random double value between 0.0 (inclusive, meaning it could be 0.0) and
1.0 (exclusive, meaning it can’t be 1.0). However, most computer applications that need random values
need random integers between some arbitrary low value (usually 1, but not always) and some arbitrary high
value. For example, a program that plays dice needs random numbers between 1 and 6, while a program
that deals cards needs random numbers between 1 and 52.

As a result, you need a Java expression that converts the double value returned by the random function into
an int value within the range your program calls for. The following code shows how to do this, with the
values set to 1 and 365 for days of the year:
int low = 1; // the lowest value in the range
int high = 365; // the highest value in the range
int rnd = (int)(Math.random() * (high - low + 1)) + low;

Example: rolling a dice whose value is between 1 and 6


public class RollDice {
public static void main(String[] args) {
int roll;
System.out.println(“Here are 100 random rolls of the dice:”);
for (int i=0; i<100; i++) {
roll = randomInt(1, 6);

94
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println(roll + " ");


}
System.out.println();
}
public static int randomInt(int low, int high) {
int result = (int)(Math.random() * (high - low + 1)) + low;
return result;
}
}

3. Date Class
The Date class encapsulates the current date and time. It supports the following constructors:
Date( )
Date(long millisec)
Date(String)

The first constructor initializes the object with the current date and time. The second constructor accepts
one argument that equals the number of milliseconds that have elapsed since midnight, January 1, 1970.

Method Description
boolean after(Date date) Returns true if the invoking Date object contains a date that is later
than the one specified by date. Otherwise, it returns false.
boolean before(Date date) Returns true if the invoking Date object contains a date that is earlier
than the one specified by date. Otherwise, it returns false.

int compareTo(Date date) Compares the value of the invoking object with that of date. Returns
0 if the values are equal.
Returns a negative value if the invoking object is earlier than date.
Returns a positive value if the invoking object is later than date.

int compareTo(Object obj) Operates identically to compareTo(Date) if obj is of class Date.


Otherwise, it throws a ClassCastException.
boolean equals(Object date) Returns true if the invoking Date object contains the same time and
date as the one specified by date.
Otherwise, it returns false.
long getTime( ) Returns the number of milliseconds that have elapsed since January
1, 1970.
getSeconds() Returns the number of seconds past the minute represented by this
date.
getMinutes() Returns the number of minutes past the hour represented by this date.
getHours() Returns the hour represented by this date
getDate() Returns the day of the month represented by this date.

95
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

getMonth() Returns the month represented by this date. The value is between 0-
11.
getYear() Returns the year represented by this date, minus 1900. It returns a 2
digit year value.
void setTime(long time) Sets the time and date as specified by time, which represents an
elapsed time in milliseconds from midnight, January 1, 1970.

String toString( ) Converts the invoking Date object into a string and returns the result.

Example: display current current system time and date


Date dt = new Date();
int dd = dt.getDate();
int mm = dt.getMonth() + 1; //month is 0-11
int yy = dt.getYear() % 100; //get only last two digits
System.out.println(dd + "/" + mm + "/" + yy);
Date birthdate = new Date(“”);

Date Comparison
There are three ways to compare two Date objects. First, you can use getTime( ) to obtain the number of
milliseconds that have elapsed since midnight, January 1, 1970, for both objects and then compare these
two values. Second, you can use the methods before( ), after( ), and equals( ). Because the 12th of the month
comes before the 18th, for example, new Date(99, 2, 12).before(new Date (99, 2, 18)) returns true. Finally,
you can use the compareTo( ) method, which is defined by the Comparable interface and implemented by
Date.

96
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Exercise
1. What is the output of the following program?
String s1 = "ab";
String s2 = s1;
s1 = s1 + "c";
System.out.println(s1 + " " + s2);
2. How many String objects are created in the following program?
int count = 5;
String msg = “There are “;
String msg += count;
String msg += “ apples in the basket.”;
3. Define a class called Course that has three data members: course title, course code, and credit
hour. Include default, parameterized and copy constructor that initializes objects. Also include a
method that accepts course information from user and another method that displays course
information.
4. Define a class called RightTraingle that represents a right angle triangle. It should accept the
base and height of the triangle and then compute its hypotenuse, perimeter and area. Define three
methods one for computing hypotenuse, the other for perimeter and the third one for area. After
the computation, display the result. Also data validate so that base and height can’t be negative.
5. Write a program that calculates GPA of a student after accepting grades of five courses and their
respective credit hours. The course class should be defined as inner class of student class. The
program should accept student details like ID, full name, sex, and birth date. It also should accept
course title, course code, credit hour, and grade for that course. Based on this, the program
computes GPA and display in a grade report format.

97
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 5
Arrays
An array is a set of variables that are referenced using a single variable name combined with an index
number. Each item of an array is called an element. All the elements in an array must be of the same type.
Thus, the array itself has a type that specifies what kind of elements it can contain. For example, an int
array can contain int values, and a String array can contain strings.

Here are a few additional tidbits of array information to ponder before you get into the details of creating
and using arrays:
• An array is itself an object. You can refer to the array object as a whole rather than a specific
element of the array by using the array’s variable name without an index. For example, if x[5] refers
to an element of an array, then x refers to the array itself.
• An array has a fixed length that’s set when the array is created. This length determines the number
of elements that can be stored in the array. The maximum index value you can use with any array
is one less than the array’s length. Thus, if you create an array of 10 elements, you can use index
values from 0 to 9.
• You can’t change the length of an array after you create the array.

Array is one type of variable which stores multiple values with same data type. It has many dimensions
such as one dimension, two dimensions, or multidimensional. Array is non-primitive data type.

1. One-Dimensional Arrays
A one-dimensional array is, essentially, a list of similar data typed variables. Single dimensional arrays
store only one column of data. To create an array, you first must create an array variable of the desired type.
The general form of a one-dimensional array declaration is
type var-name[ ];

Here, type declares the base type of the array. The base type determines the data type of each element that
comprises the array. Thus, the data type for the array determines what type of data the array will hold. For
example, the following declares an array named month_days with the type “array of int”:
int month_days[];

Although this declaration establishes the fact that month_days is an array variable, no array actually exists.
In fact, the value of month_days is set to null, which represents an array with no value. To link month_days
with an actual, physical array of integers, you must allocate one using new and assign it to month_days.
new is a special operator that allocates memory.

All objects in Java (including arrays) must be allocated dynamically with operator new. For an array, the
programmer specifies the type of the array elements and the number of elements as part of the new
operation. The general form of new as it applies to one-dimensional arrays appears as follows:
array-var = new type[size];

Here, type specifies the type of data being allocated, size specifies the number of elements in the array, and
array-var is the array variable that is linked to the array. That is, to use new to allocate an array, you must
specify the type and number of elements to allocate.
The elements in the array allocated by new will automatically be initialized to zero. This example allocates
a 12-element array of integers and links them to month_days.
int c[]; // declares the array

98
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

c = new int[ 12 ]; // allocates the array

After this statement executes, month_days will refer to an array of 12 integers. Further, all elements in the
array will be initialized to zero.

The preceding declaration also can be performed in a single step as follows:


int month_days[] = new int[12];

Initializing an Array
Arrays can be initialized in different ways.

One way to initialize the values in an array is to simply assign them one by one:
String[] days = new Array[7];
Days[0] = “Sunday”;
Days[1] = “Monday”;
Days[2] = “Tuesday”;
Days[3] = “Wednesday”;
Days[4] = “Thursday”;
Days[5] = “Friday”;
Days[6] = “Saturday”;

Java has a shorthand way to create an array and initialize it with constant values:
String[] days = { “Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” };

In the second case, each element to be assigned to the array is listed in an array initializer. Here is an
example of an array initializer for an int array:
int[] primes = { 2, 3, 5, 7, 11, 13, 17 };

The length of an array created with an initializer is determined by the number of values listed in the
initializer.

An alternative way to code an initializer is like this:


int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17 };
To use this type of initializer, you use the new keyword followed by the array type and a set of empty
brackets. Then, you code the initializer.

Iterating Over Array


Loops provide a way to iterate over arrays. One of the most common ways to process an array is with a for
loop.

Example: a program that stores numbers from 1-100 on an array


int[] numbers = new int[100];
for (int i = 0; i < 100; i++)
numbers[i] = i;

And here’s a loop that fills an array of player names with strings entered by the user:
String[]scientist[] = new String[10];
for (int i = 0; i < scientist.length; i++) {
System.out.print(“Enter scientist’s name: “);

99
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

scientist[i] = sc.nextLine(); // sc is a Scanner


}

Java introduced a new type of for loop called an enhanced for loop that is designed to simplify loops that
process arrays and collections. When used with an array, the enhanced for loop has this format:
for (type identifier : array) {
statements...
}

The type identifies the type of the elements in the array, and the identifier provides a name for a local
variable that is used to access each element. And array names the array you want to process. Here’s an
example:
String[] days = { “Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” };
for (String d : days) {
System.out.println(d);
}

When using enhanced for loop, knowing the array size is not necessary because Java will handle that
internally. This makes it very simple way of iterating over arrays.

2. Multidimensional Arrays
In Java, multidimensional arrays are actually arrays of arrays. When the elements of an array are
themselves arrays, we say that the array is multidimensional. If the number of dimensions is only two, then
the array is called a two-dimensional array.

Multidimensional arrays are often used to represent tables of values consisting of information arranged in
rows and columns. To identify a particular table element, we must specify the two subscripts — the first
identifies the element’s row and the second identifies the element’s column. Arrays that require two
subscripts to identify a particular element are called two-dimensional arrays.

Two-dimensional arrays are often used to track data in a column and row format, much the way a
spreadsheet works. For example, suppose you’re working on a program that tracks five years worth of sales
(2001 through 2005) for ABC company, with the data broken down for each of four sales territories (North,
South, East, and West). You could create 20 separate variables, with names such as sales2001North,
sales2001South, sales2001East, and so on to store these values. But that gets a little tedious.

Thinking of a two-dimensional array as a table or spreadsheet is common, like this:

North South East West

2001 23,853 22,838 36,483 31,352


2002 25,483 22,943 38,274 33,294

2003 24,872 23,049 39,002 36,888

2004 28,492 23,784 42,374 39,573


2005 31,932 23,732 42,943 41,734

100
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

For example, the following declares a two-dimensional array variable called sales to store.
double[][] sales = new double[5][4];

Here’s an example that initializes the sales array:


double[][] sales = {
{23853.0, 22838.0, 36483.0, 31352.0}, // 2001
{25483.0, 22943.0, 38274.0, 33294.0}, // 2002
{24872.0, 23049.0, 39002.0, 36888.0}, // 2003
{28492.0, 23784.0, 42374.0, 39573.0}, // 2004
{31932.0, 23732.0, 42943.0, 41734.0} // 2005
};

Like a one-dimensional array, a multidimensional array can be initialized using an array literal. Simply use
nested sets of curly braces to nest arrays within arrays. For example, we can declare, create, and initialize
a 5×5 multiplication table like this:
int[][] products = { {0, 0, 0, 0, 0},
{0, 1, 2, 3, 4},
{0, 2, 4, 6, 8},
{0, 3, 6, 9, 12},
{0, 4, 8, 12, 16} };

Using loop, the size of each row can be defined.


int twod[][] = new int[4][];
int k = 0;
for(int i=0; i<4; i++){
twod = new int[4][i+1];
for(int j = 0; j<i+1; j++) {
twod[i][j] = k;
k++;
}
}

for(int I = 0; i<4; i++) {


for(int j = 0; j<i+1; j++)
System.out.print(twod[i][j] + " ");
System.out.println();
}

When working with multidimensional arrays, it is often necessary to use nested loops to create or initialize
them. For example, you can create and initialize a large multiplication table as follows:
int[][] products = new int[13][13];
System.out.print("\t");
for(int row = 0; row <= 12; row++)
System.out.print(row + "\t");
System.out.print("\n");

for(int row = 0; row <= 12; row++) {


System.out.print(row);

101
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

for(int col = 0; col <= 12; col++) {


products[row][col] = row * col;
System.out.print("\t" + products[row][col]);
}
System.out.println();
}
When you create a multidimensional array using the new keyword, you always get a rectangular array: one
in which all the array values for a given dimension have the same length. This is perfect for rectangular
data structures, such as matrixes. However, because multidimensional arrays are implemented as arrays of
arrays in Java, instead of as a single rectangular block of elements, you are in no way constrained to use
rectangular arrays.

For example, since our multiplication table is symmetrical about the diagonal from top left to bottom right,
we can represent the same information in a nonrectangular array with fewer elements:
int[][] products = { {0},
{0, 1},
{0, 2, 4},
{0, 3, 6, 9},
{0, 4, 8, 12, 16} };

To iterate over such arrays, you need to check the length of each row. You can use something like this:
for(int i = 0; i < products.length; i++) {
for(int j=0; j<products[i].length; j++)
System.out.print(products[i][j]);
System.out.println();
}

To initialize arrays whose row lengths vary, it is possible to use loops. For example, to initialize triangular
array like the one above, it is possible to use this code.
int k = 0;
int[][] products = new int[4][];
for(int row = 0; row < 4; row++) {
products[row] = new int[row+1]; // allocate an array of for each row
for(int col = 0; col < row+1; col++) // For each element of the int[],
products[row][col] = k++;
}

This produces the following output:


0
1 2
3 4 5
6 7 8 9

Iterating over An Array


To iterate over multidimensional array, it is necessary to use nested loops. To access all the data in two-
dimensional array, one needs two loops. As the number of dimension increases, the number of loops needed
also increases.

Example: iterating over the sales table and calculating the total sales for each year
double[][] sales = {

102
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

{23853.0, 22838.0, 36483.0, 31352.0}, // 2001


{25483.0, 22943.0, 38274.0, 33294.0}, // 2002
{24872.0, 23049.0, 39002.0, 36888.0}, // 2003
{28492.0, 23784.0, 42374.0, 39573.0}, // 2004
{31932.0, 23732.0, 42943.0, 41734.0} // 2005
};
double total = 0;
for(int t = 0; t < sales.length; t++) {
total = 0; //re-initialize when you begin a new row
for(int u = 0; u < sales[t].length; u++) {
total = total + sales[t][u];
System.out.print(sales[t][u] + “\t”);
}
System.out.print(total + “\n”);
}

3. Methods and Properties of Arrays Class


To get the length of an array, use the length field. This can be used in association with loops to iterate over
the array. For example:
int[] primes = { 2, 3, 5, 7, 11, 13, 17 };
System.out.println(primes.length); // 7

Java defines a class called Arrays, which provides a collection of static methods that are useful for working
with arrays. The Arrays class is in the java.util package, so you have to use an import statement for the
java.util.Arrays class or the entire java.util.* package to use this class.
Method Description
static int binarySearch (array, key) Searches for the specified key value in an array. The return value
is the index of the element that matches the key. Returns –1 if
the key couldn’t be found. The array must be sorted in ascending
order for this method to work.
boolean equals(array1, array2) Returns true if the two arrays have the same element values. This
method only checks equality for one-dimensional arrays.
boolean deepEquals(array1, Returns true if the two arrays have the same element values. This
array2) method works for arrays of two or more dimensions.

static void fill(array, value) Fills the array with the specified value. The value and array must
be of the same type and can be any primitive type or an object.
static void fill(array, from, to, Fills the elements indicated by the from and to int parameters
value) with the specified value. The value and array must be of the same
type and can be any primitive type or an object.

static void sort(array) Sorts the array into ascending sequence.


static void sort(array, from, to) Sorts the specified elements of the array into ascending
sequence.

103
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

static String toString(array) Formats the array values in a string. Each element value is
enclosed in brackets, and the element values are separated from
each other with commas.

Filling an array
The fill method can be handy if you want to pre-fill an array with values other than the default values for
the array type. For example, here is a routine that creates an array of integers and initializes each element
to the value 100:
int[] startValues = new int[10];
Arrays.fill(startValues, 100);

Sorting an array
The sort method is a quick way to sort an array into sequence. For example, these statements create an array
with 100 random numbers, and then sort the array into sequence so the random numbers are in order:
int[] lotto = {4, 90, 65, 84, 99, 81};
Arrays.sort(lotto); //4 65 81 84 90 99

Searching an array
The binarySearch method is an efficient way to locate an item in an array by its value. For example, suppose
you want to find out if your lucky number is in the lotto array created in the previous example.
int lucky = 13;
int foundAt = Arrays.binarySearch(lotto, lucky);
if (foundAt > -1)
System.out.println(“My number came up!”);
else
System.out.println(“I’m not lucky today.”);

Converting arrays to strings


The toString method of the Arrays class is handy if you want to quickly dump the contents of an array to
the console to see what it contains. This method returns a string that shows the array’s elements enclosed
in brackets, with the elements separated by commas.
For example, here’s a routine that creates an array, fills it with random numbers, and then uses the toString
method to print the array elements:
int[] lotto = {4, 90, 65, 84, 99, 81};
System.out.println(Arrays.toString(lotto));
Here’s a sample of the console output created by this code:
[4, 90, 65, 84, 99, 81]
Note that the toString method works only for one-dimensional arrays. To print the contents of a two-
dimensional array with the toString method, use a for loop to call the toString method for each subarray.

4. ArrayList Class
Java defines a class called ArrayList that supports dynamic arrays that can grow as needed. In Java,
standard arrays are of a fixed length. After arrays are created, they cannot grow or shrink, which means that
you must know in advance how many elements an array will hold. But, sometimes, you may not know until

104
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

run time precisely how large of an array you need. To handle this situation, the collections framework
defines ArrayList. In essence, an ArrayList is a variable-length array of object references. That is, an
ArrayList can dynamically increase or decrease in size. Array lists are created with an initial size. When
this size is exceeded, the collection is automatically enlarged. When objects are removed, the array may be
shrunk.

The ArrayList solves the most common problems of working with normal arrays like:
• An array list automatically resizes itself whenever necessary. Arrays have fixed size which you
can’t change during run time. ArrayList has no such limitation.
• An array list lets you insert elements into the middle of the collection. With an array, inserting
elements in the middle is pretty hard to do unless you are overwriting existing value.
• An array list lets you delete items. If you delete an item from an array, the deleted element becomes
null but the empty slot that was occupied by the item stays in the array.
• The ArrayList class actually uses an array internally to store the data you add to the array list. The
ArrayList class takes care of managing the size of this array. When you add an item to the array list
and the underlying array is full, the ArrayList class automatically creates a new array with a larger
capacity and copies the existing items to the new array before it adds the new item.

The ArrayList class is in the java.util package, so your program must import either java.util.ArrayList or
java.util.*. ArrayList has the constructors shown here:
ArrayList( )
ArrayList(Collection c)
ArrayList(int capacity)
The first constructor builds an empty array list. The second constructor builds an array list that is initialized
with the elements of the collection c. The third constructor builds an array list that has the specified initial
capacity. The capacity is the size of the underlying array that is used to store the elements. The capacity
grows automatically as elements are added to an array list.

To create an array list, you first declare an ArrayList variable, and then call the ArrayList constructor to
instantiate an array list object and assign it to the variable. You can do this on separate lines:
ArrayList signs;
signs = new ArrayList();
or, you can do it on a single line:
ArrayList signs = new ArrayList();

If you are using Java 1.5 and later, you can also specify the type of elements the array list is allowed to
contain. The syntax for this is:
ArrayList<datatype> name = new ArrayList<datatype>();

For example, this statement creates an array list that holds String or Integer objects:
ArrayList<String> books = new ArrayList<String>();
ArrayList<Integer> marks = new ArrayList<Integer>();

After you create an array list, you can use the add method to add objects to the array list. For example,
here’s code that adds strings to an array list:
ArrayList books = new ArrayList();
books.add(“Practical Java Programming”);
books.add(“Basics of Electronic Equipments”);

105
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

books.add(“PHP Simplified”);
books.add(“The Beauty of Chemistry”);
books.add(“Computer Design and Manufacturing”);

If you specified a type when you created the array list, the objects you add via the add method must be of
the correct type.

Accessing Elements
To access a specific element in an array list, you can use the get method. It specifies the index value of
the element you want to retrieve. For example, here’s a for loop that prints all the strings in an array list:
for (int i = 0; i < books.size(); i++)
System.out.println(books.get(i));
Here, the size method is used to set the limit of the for loop’s index variable.

The easiest way to access all the elements in an array list is by using an enhanced for statement. It lets you
retrieve the elements without bothering with indexes or the get method. For example:
for (String s : books)
System.out.println(s);
Here, each String element in the books array list is printed to the console.

Methods of ArrayList Class


Method Description
Adds the specified object to the array list. If you specified a type
add(Object element)
when you created the array list, the object must be of the correct
type.
Adds the specified object to the array list at the specified index
add(int index, Object element)
position. If you specified a type when you created the array list,
the object must be of the correct type.
Adds all of the elements of the specified collection to this array
addAll(Collection c)
list.
addAll(int index, Collection c) Adds all the elements of the specified collection to this array list at
the specified index position.
clear() Deletes all elements from the array list.
Returns a boolean that indicates whether or not the specified
contains(Object elem)
object is in the array list.
Returns a boolean that indicates whether or not this array list
containsAll(Collection c)
contains all the objects that are in the specified collection.
ensureCapacity(int Increases the array list’s capacity to the specified value. (If the
minCapacity) capacity is already greater than the specified value, this method
does nothing.)
get(int index) Returns the object at the specified position in the list.
Returns the index position of the first occurrence of the specified
indexOf(Object elem)
object in the array list. If the object isn’t in the list, returns –1.
Returns a boolean value that indicates whether or not the array list
isEmpty()
is empty.
iterator() Returns an iterator for the array list.
Returns the index position of the last occurrence of the specified
lastIndexOf(Object elem)
object in the array list. If the object isn’t in the list, returns –1.

106
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Removes the object at the specified index. Returns the element


remove(int index)
that was removed.
Removes an object from the list. Note that more than one element
refers to the object; this method removes only one of them. It
remove(Object elem)
returns a boolean that indicates whether or not the object was in
the list.
Removes all objects whose index values are between the values
remove(intfromIndex,int
specified. Note that the elements at the fromIndex and toIndex
toIndex)
positions are not themselves removed.
removeAll(Collection c) Removes all the objects in the specified collection from this array.
Removes all the objects that are not in the specified collection
retainAll(Collection c)
from this array list.
Sets the specified element to the specified object. The element that
set(int index, Object elem) was previously at that position is returned as the method’s return
value.
size() Returns the number of elements in the list.
Returns the elements of the array list as an array of objects
toArray()
(Object[]).
Returns the elements of the array list as an array whose type is the
toArray(type[] array)
same as the array passed via the parameter.

For example, consider these statements:


ArrayList<String> nums = new ArrayList<String>();
nums.add(“One”);
nums.add(“Two”);
nums.add(“Three”);
nums.add(“Four”);
for (int i = 0; i < nums.size(); i++)
System.out.println(nums.get(i));

107
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Exercise
1. Write a program that accepts temperature of the last ten days and then store on an array. Using
the array, compute the average temperature. Also display the hottest and coldest days of the last
ten days.
2. Write a program that accepts and stores names of employees on an array. Using an insertion sort,
sort the employees in ascending order.
3. Write a program that stores prime numbers between 1 and 1,000,000 on an array.
4. Write a program that stores marks of ten subjects for five students. Based on the accepted mark,
calculate the total and average for each student and store it on the array.

108
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 6
Inheritance & Polymorphism
1. Inheritance
Inheritance is one of the cornerstones of object-oriented programming because it allows the creation of
hierarchical classifications. Using inheritance, you can create a general class that defines traits common to
a set of related items. This class can then be inherited by other, more specific classes, each adding those
things that are unique to it. The class that is inherited is called the parent class, the base class, or the
superclass. The class that inherits is called the child class, the derived class, sub class or the child class.
Therefore, a subclass is a specialized version of a superclass. It inherits all of the instance variables and
methods defined by the superclass and adds its own, unique elements. The terms subclass and superclass
seem to be the preferred term among Java gurus.

You need to know a few important things about inheritance:


▪ A derived class automatically takes on all the behavior and attributes of its base class. Thus, if you
need to create several different classes to describe types that aren’t identical but have many features
in common, you can create a base class that defines all the common features. Then, you can create
several derived classes that inherit the common features.
▪ A derived class can add features to the base class it inherits by defining its own methods and fields.
This is one way a derived class distinguishes itself from its base class.
▪ A derived class can also change the behavior provided by the base class. For example, a base class
may provide that all classes derived from it have a method named play(), but each class is free to
provide its own implementation of the play() method. In this case, all classes that extend the base
class provide their own implementation of the play method.
▪ Inheritance is best used to implement is-a-type-of (is-a) relationships. For example: Solitaire is a
type of game; a truck is a type of vehicle; a cat is a type of animal; an invoice is a type of transaction.
In each case, a particular kind of object is a specific type of a more general category of objects.

Animal

Cat Dog Goat

Fig Class hierarchy

The idea of inheritance is simple but powerful: when you want to create a new class and there is already a
class that includes some of the code that you want, you can derive your new class from the existing class.
In doing this, you can reuse the fields and methods of the existing class without having to write (and debug)
them yourself.

109
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors
are not members, so they are not inherited by subclasses, but the constructor of the superclass can be
invoked from the subclass.

Creating Subclasses
The basic procedure for creating a subclass is simple. You just use the extends keyword on the declaration
for the subclass. The basic format of a class declaration for a class that inherits a base class is this:
public class DerivedClassName extends BaseClassName {
// class body goes here
}

Java’s form of inheritance is called single inheritance. Single inheritance means that each Java class can
have only one superclass. You can only specify one superclass for any subclass that you create. Java does
not support multiple inheritance. In other words, Java does not support the inheritance of multiple
superclasses into a single subclass. This differs from C++, in which you can inherit multiple base classes.
You can, however, create a hierarchy of inheritance in which a subclass becomes a superclass of another
subclass. However, no class can be a superclass of itself.

Example: a Cat is an Animal


public class Animal {
public void walk() {
System.out.println("Animal walking…");
}
public void feed() {
System.out.println("Animal feeding…");
}
}
public class Cat extends Animal {
public void chaseMouse() {
System.out.println(“Chasing mouse…”);
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.walk();
myCat.feed();
myCat.chaseMouse();
}
}

A superclass’s public members are accessible anywhere in its subclass types. A superclass’s private
members are accessible only in methods of that superclass i.e. they are not accessible in the subclasses.
Private members are generally not inherited. However, if the superclass has public or protected methods
for accessing its private fields, these can also be used by the subclass.

110
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

A nested class has access to all the private members of its enclosing class—both fields and methods.
Therefore, a nested class (either public or protected) inherited by a subclass has indirect access to all of the
private members of the superclass.

A superclass’s protected access members serve as an intermediate level of protection between public and
private access. A superclass’s protected members are accessible in the superclass, in the subclasses and
other classes in the same package (protected members have package access).

Example:
public class Bicycle {
public int gear;
public int speed;
public Bicycle(int startSpeed, int startGear) {
gear = startGear;
speed = startSpeed;
}
public void setGear(int newValue) {
gear = newValue;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}
public class MountainBike extends Bicycle {
public int seatHeight;
public MountainBike(int startHeight, int startSpeed, int startGear) {
super(startSpeed, startGear);
seatHeight = startHeight;
}
public void setHeight(int newValue) {
seatHeight = newValue;
}
public static void main(String args[]) {
Bike b = new Bike(20, 3);
MountainBike mb = new MountainBike();
}
}

111
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Example: inheritance
class Art {
Art() {
System.out.println("Art constructor");
}
}
class Drawing extends Art {
Drawing() {
System.out.println("Drawing constructor");
}
}
public class Cartoon extends Drawing {
Cartoon() {
System.out.println("Cartoon constructor");
}
public static void main(String[] args) {
Cartoon x = new Cartoon();
}
}
The output for this program shows the automatic calls:
Art constructor
Drawing constructor
Cartoon constructor

Inheritance and Constructors


When you create an instance of a subclass, Java automatically calls the default or no-arg constructor of the
base class before it executes the subclass constructor.

Example:
public class Ball {
public Ball() {
System.out.println(“Hello from the Ball constructor”);
}
}
public class BaseBall extends Ball {
public BaseBall() {
System.out.println(“Hello from the BaseBall constructor”);
}
public static void main(String args[]) {
BaseBall bb = new BaseBall();
}
}
When you create an instance of the BaseBall class, the following two lines are displayed on the console:
Hello from the Ball constructor
Hello from the BaseBall constructor

112
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

If you want, it is possible to explicitly call a base class constructor from a subclass by using the super
keyword. Because Java automatically calls the no-arg or default constructor for you, the only reason to do
this is to call a constructor of the base class that uses a parameter.

The syntax for calling a superclass constructor is


super();
super(parameter list);
With super(), the superclass no-argument constructor is called. With super(parameter list), the superclass
constructor with a matching parameter list is called.

Example: calling superclass constructor


public class Vehicle {
public double speed;
public Vehicle(double speed) {
this.speed = speed;
}
}
public class Car extends Vehicle {
public double price;
public Car() {
super(80);
price = 300000;
}
}
Here, the Car constructor calls the Vehicle constructor to supply a speed for the Vehicle.

You need to obey a few rules and regulations when working with superclass constructors:
▪ If you use super to call the superclass constructor, you must do so in the very first statement in the
subclass constructor.
▪ If you don’t explicitly call super, the compiler inserts a call to the default constructor of the base
class. In that case, the base class must have a default constructor. If the base class doesn’t have a
default constructor, the compiler refuses to compile the program.
▪ If the superclass is itself a subclass, the constructor for its superclass is called in the same way. This
continues all the way up the inheritance hierarchy, until you get to the Object class, which has no
superclass.

Final Classes – Preventing Inheritance


Sometimes you will want to prevent a class from being inherited. To do this, precede the class declaration
with final. Declaring a class as final implicitly declares all of its methods as final, too. As you might expect,
it is impossible to declare a class as both abstract and final since an abstract class is incomplete by itself
and relies upon its subclasses to provide complete implementations.

Example:
final class A {
// ...
}
// The following class is illegal.
class B extends A { // ERROR! Can't subclass A

113
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

// ...
}

Generally, a subclass can do the following:


• The inherited fields can be used directly, just like any other fields.
• You can declare a field in the subclass with the same name as the one in the superclass, thus hiding
it (not recommended).
• You can declare new fields in the subclass that are not in the superclass.
• The inherited methods can be used directly as they are.
• You can write a new instance method in the subclass that has the same signature as the one in the
superclass, thus overriding it.
• You can write a new static method in the subclass that has the same signature as the one in the
superclass, thus hiding it.
• You can declare new methods in the subclass that are not in the superclass.
• You can write a subclass constructor that invokes the constructor of the superclass, either implicitly
or by using the keyword super.

2. Overriding Methods
When a class defines a method using the same name, return type, and arguments as a method in its
superclass, the method in the subclass overrides the method in the superclass. When the method is invoked
for an object of the subclass, it is the new definition of the method that is called, not the superclass's old
definition.

Method a subclasses declares a method that has the same signature as a public method of the base class, the
subclass version of the method overrides the base class version of the method. This technique lets you
modify the behavior of a base class to suit the needs of the subclass.

Note that to override a method, three conditions have to be met:


▪ The class must extend the class that defines the method you want to override.
▪ The method must be declared in the base class with public or protected access. You can’t override
a private method.
▪ The method in the subclass must have the same signature as the method in the base class. In other
words, the name of the method and the parameter types must be the same.

Example:
public class Animal {
public static void speak() {
System.out.println("The class method in Animal.");
}
public void walk() {
System.out.println("The instance method in Animal.");
}
}
public class Cat extends Animal {
public static void speak() {
System.out.println("The class method in Cat.");
}
public void walk() {
System.out.println("The instance method in Cat.");

114
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

}
public static void main(String[] args) {
Animal myAnimal = new Cat();
Animal.speak();
myAnimal.walk();
}
}

The Cat class overrides the instance method in Animal and hides the class method in Animal. The main
method in this class creates an instance of Cat and calls speak() on the class and walk() on the instance.

The output from this program is as follows:


The class method in Animal.
The instance method in Cat.
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is
"close enough" and then to modify behavior as needed. The overriding method has the same name, number
and type of parameters, and return type as the method it overrides. An overriding method can also return a
subtype of the type returned by the overridden method. This is called a covariant return type.

When overriding a method, you might want to use the @Override annotation that instructs the compiler
that you intend to override a method in the superclass. If, for some reason, the compiler detects that the
method does not exist in one of the superclasses, it will generate an error.

Example:
// Method overriding.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b;
}
void show() {
System.out.println("i and j: " + i + " " + j);
}
}
class B extends A {
int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
// this overrides show() in A
@Override
void show() {
System.out.println("k: " + k);
}
}
class TestOverride {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);

115
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

subOb.show(); // this calls show() in B


}
}

When an overridden method is called from within a subclass, it will always refer to the version of the
method defined by the subclass.

Method overloading is a powerful and useful feature. It's another form of polymorphism (ad-hoc
polymorphism). The idea is to create methods that act in the same way on different types of arguments and
have what appears to be a single method that operates on any of the types.

Final methods – Preventing Overriding


Sometimes, it may be necessary to prevent overriding methods in a subcalss. This is done by using final
methods. A final method is a method that can’t be overridden by a subclass. To create a final method, you
simply add the keyword final to the method declaration.

Example:
public class SpaceShip {
double speed;
public final int getSpeed() {
return this.speed;
}
}
Here, the method getSpeed is declared as final. Thus, any class that uses the SpaceShip class as a base class
can’t override the getSpeed method. If it tries, the compiler issues an error message.

Here are some additional details about final methods:


▪ Final methods execute more efficiently than non-final methods. That’s because the compiler knows
at compile time that a call to a final method won’t be overridden by some other method. The
performance gain isn’t huge, but for applications where performance is crucial, it can be noticeable.
▪ Private methods are automatically considered to be final. That’s because you can’t override a
method you can’t see.

Example:
class A {
public final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {
public void meth() { // ERROR! Can't override.
System.out.println("Illegal!");
}
}
Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to do so, a compile-time
error will result.

Hiding Methods

116
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

If a subclass defines a static method with the same signature as a static method in the superclass, then the
method in the subclass hides the one in the superclass. The distinction between hiding a static method and
overriding an instance method has important implications:
• The version of the overridden instance method that gets invoked is the one in the subclass.
• The version of the hidden static method that gets invoked depends on whether it is invoked from
the superclass or the subclass.

Example:
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
myAnimal.testClassMethod();
myAnimal.testInstanceMethod();
}
}

Output:
The static method in Animal
The instance method in Cat

3. Polymorphism
Dynamic, run-time polymorphism is one of the most powerful mechanisms that object-oriented design
brings to bear on code reuse and robustness. The ability of existing code to call methods on instances of
new classes without recompiling while maintaining a clean abstract interface is a profoundly powerful tool.

The term polymorphism refers to the ability of Java to use base class variables to refer to subclass objects,
keep track of which subclass an object belongs to, and use overridden methods of the subclass even though
the subclass isn’t known when the program is compiled.

A superclass reference variable can refer to a subclass object. Java uses this fact to resolve calls to
overridden methods at run time. When an overridden method is called through a superclass reference, Java
determines which version of that method to execute based upon the type of the object being referred to at
the time the call occurs. Thus, this determination is made at run time. When different types of objects are
referred to, different versions of an overridden method will be called. In other words, it is the type of the

117
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

object being referred to (not the type of the reference variable) that determines which version of an
overridden method will be executed. Therefore, if a superclass contains a method that is overridden by a
subclass, then when different types of objects are referred to through a superclass reference variable,
different versions of the method are executed.

Example: polymorphism
class Shape {
double dim1;
double dim2;
Shape(double a, double b) {
dim1 = a;
dim2 = b;
}
double area() {
System.out.println("Area for shape is undefined.");
return 0;
}
}
class Rectangle extends Shape {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Shape {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class FindAreas {
public static void main(String args[]) {
Shape f = new Shape(10, 10);
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Shape figref;
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
figref = f;
System.out.println("Area is " + figref.area());

118
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

}
}
The output from the program is shown here:
Inside Area for Rectangle.
Area is 45
Inside Area for Triangle.
Area is 40
Area for Figure is undefined.
Area is 0

Although, all the area methods are called by using Shape object, they call different area() methods because
of polymorphism.

In the following example, how can the playTune(…) method know which play() method to call? It receives
an Instrument reference. So how can the compiler possibly know that this Instrument reference points to
a Wind or Brass or Instrument? The compiler can’t. To get a deeper understanding of the issue, it’s helpful
to examine the subject of binding.
class Instrument {
public void play() {
System.out.println("Instrument play");
}
}
class Wind extends Instrument {
public void play() {
System.out.println("Wind play");
}
}
class Stringed extends Instrument {
public void play() {
System.out.println("Stringed play");
}
}
public class Music {
public static void playTune(Instrument ins) {
ins.play();
}
public static void main(String[] args) {
Wind flute = new Wind();
Stringed violin = new Stringed();
Instrument frenchHorn = new Instrument();
playTune (flute);
playTune (violin);
playTune (frenchHorn);
}
}

Connecting a method call to a method body is called binding. When binding is performed by the compiler,
it’s called early binding. This is done during compilation of source code. Languages like C have only one
kind of method call, and that’s early binding.

119
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

The other approach is called late binding, which means that the binding occurs at run-time based on the
type of object. Late binding is also called dynamic binding or run-time binding. When a language
implements late binding, there must be some mechanism to determine the type of the object at run-time and
to call the appropriate method. That is, the compiler still doesn’t know the object type, but the method-call
mechanism finds out and calls the correct method body.

All method binding in Java uses late binding unless a method has been declared final. This means that
ordinarily you don’t need to make any decisions about whether late binding will occur—it happens
automatically.

In the above program, in the playTune(…) method, the compiler does not know which play() method to
call because there are different paly() methods that can be called by Instrument class object ins. To
determine this, Java uses late-binding during run-time after checking the type of the object. This is what
allows polymorphism.

4. Accessing Superclass Members


Sometimes, it may be necessary to access superclass members directly. For example, if your method
overrides one of its superclass's methods, you can invoke the overridden method in the superclass. This can
be done through the use of the keyword super. You can also use super to refer to a hidden field. Consider
this class, superclass:
public class Vehicle {
public void start() {
System.out.println("Printed in Superclass.");
}
}

Here is a subclass, called Car, that overrides start() method:


public class Car extends Vehicle {
//overrides start method in Superclass
public void start() {
super.start();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Car cr = new Car();
cr.start();
}
}
Within subclass Car, the simple name start() refers to the one declared in subclass Car, which overrides the
one in superclass Vehicle. So, to refer to start() inherited from superclass Vehicle, subclass Car must use a
qualified name, using super as shown. Compiling and executing subclass prints the following:
Printed in Superclass.
Printed in Subclass

Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even
if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple
name. Instead, the field must be accessed through super.

5. Abstract Classes

120
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

There are situations in which you will want to define a superclass that declares the structure of a given
abstraction without providing a complete implementation of every method. That is, sometimes you will
want to create a superclass that only defines a generalized form that will be shared by all of its subclasses,
leaving it to each subclass to fill in the implementation details. Such a class determines the nature of the
methods that the subclasses must implement. One way this situation can occur is when a superclass is unable
to create a meaningful implementation for a method.

You can enforce that certain methods be overridden by subclasses by specifying the abstract type modifier.
These methods are sometimes referred to as subclasser responsibility because they have no implementation
specified in the superclass. Thus, a subclass must override them—it cannot simply use the version defined
in the superclass.

Java lets you declare that a method is abstract, which means that the method has no body. An abstract
method is just a prototype for a method: a return type, a name, a list of parameters, and (optionally) a throws
clause.

To declare an abstract method, use this general form:


abstract type methodname(parameter-list);
As you can see, no method body is present.

Any class that contains one or more abstract methods must also be declared abstract. To declare a class
abstract, you simply use the abstract keyword in front of the class keyword at the beginning of the class
declaration. There can be no objects of an abstract class i.e. an abstract class cannot be directly instantiated
with the new operator. Such objects would be useless, because an abstract class is not fully defined.

A class that contains at least one abstract method is called an abstract class, and must be declared with the
abstract modifier on the class declaration. For example:
public abstract class Shape {
public abstract double calculateArea();
}
If you omit the abstract modifier from the class declaration, the Java compiler brings up an error message
to remind you that the class must be declared abstract.

An abstract class can’t be instantiated. Thus, given the preceding declaration, the following line doesn’t
compile:
Shape b = new Shape(); //error: Shape is abstract

You can create a subclass from an abstract class Shape like this:
public class Rectangle extends Shape {
double width, height, area;
public double calculateArea() {
area = width * height;
}
}

In abstract classes, you cannot declare abstract constructors, or abstract static methods. Any subclass of an
abstract class must either implement all of the abstract methods in the superclass, or be itself declared
abstract.

Here are a few additional points to ponder concerning abstract classes:

121
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

▪ Not all the methods in an abstract class have to be abstract. A class can provide an implementation
for some of its methods but not others. In fact, you can declare an abstract class that doesn’t have
any abstract methods. In that case, the class can’t be instantiated.
▪ A private method can’t be abstract. That only makes sense, because a subclass can’t override a
private method, and abstract methods must be overridden.
▪ Although you can’t create an instance of an abstract class, you can declare a variable using an
abstract class as its type. Then, use the variable to refer to an instance of any of the subclasses of
the abstract class.
▪ A class can’t be both abstract and final. That would cause a logical paradox: must be inherited and
can’t be inherited at the same time. But the point is that because an abstract class can only be used
if you subclass it, and a final class can’t be subclassed, letting you specify both abstract and final
for the same class doesn’t make sense.

Example:
public abstract class Shape {
public abstract double area();
public abstract double circumference();
}
class Circle extends Shape {
protected double r;
protected static final double PI = 3.142;
public Circle(double r) {
this.r = r;
}
public double area() {
return PI * r * r;
}
public double circumference() {
return 2 * PI * r;
}
}
class Rectangle extends Shape {
protected double w, h;
public Rectangle(double w, double h) {
this.w = w;
this.h = h;
}
public double area() {
return w * h;
}
public double circumference() {
return 2 * (w + h);
}
}

6. Interface

122
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

There are a number of situations in software engineering when it is important for disparate groups of
programmers to agree to a "contract" that spells out how their software interacts. Each group should be able
to write their code without any knowledge of how the other group's code is written. Generally speaking,
interfaces are such contracts.

An interface is similar to an abstract class. However, it can only include abstract methods and final fields
(constants), and it can’t be used as a base class. Instead, a class implements an interface by providing an
implementation for each method declared by the interface.

Interfaces have two advantages over inheritance:


▪ Interfaces are easier to work with than inheritance, because you don’t have to worry about providing
any implementation details in the interface.
▪ A class can extend only one other class, but it can implement as many interfaces as you need.

In the Java programming language, an interface is a reference type, similar to a class, that can contain only
constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be
instantiated—they can only be implemented by classes or extended by other interfaces.

Creating a basic interface


Here’s a basic interface that defines an interface:
[access modifier] interface interfacename {
constants;
method signatures();
}

Variables can be declared inside interface declarations. They are implicitly final and static, meaning they
cannot be changed by the implementing class. They must also be initialized with a constant value. All
methods and variables are implicitly public if the interface, itself, is declared as public. So, the interface
fields are automatically assumed to be static, final, and public. You can include these keywords when you
create interface constants, but you don’t have to.

Implementing Interfaces
Once an interface has been defined, one or more classes can implement that interface. To implement an
interface, include the implements clause in a class definition, and then create the methods defined by the
interface. The general form of a class that includes the implements clause looks like this:
[access modifier] class classname [extends superclass] implements interface [,interface...] {
// class-body
}

Here, access is either public or not used. If a class implements more than one interface, the interfaces are
separated with a comma. If a class implements two interfaces that declare the same method, then the same
method will be used by clients of either interface. The methods that implement an interface must be declared
public. Also, the type signature of the implementing method must match exactly the type signature
specified in the interface definition.

Example:
public interface Shape {
// calculate area
public abstract double area();

123
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

// calculate volume
public abstract double perimeter();

// return shape name


public abstract String getName();
}
public class Rectangle implements Shape{
double width, height;
String name = “Rectangle”;
public double area(){
return width * height;
}
public double perimeter(){
return 2 *(width + height);
}
public String getName(){
return name;
}
}
public class RightTriangle implements Shape{
double width, height, hypotenuse;
String name = “Right angle triangle”;
public double area(){
return width * height * 1/2;
}
public double perimeter(){
calcHypotenuse();
return width + height + hypotenuse;
}
public double calcHypotenuse() {
hypotenuse = Math.sqrt(width*width + height*height);
}
public String getName(){
return name;
}
}

Besides abstract methods, an interface can also include final fields — that is, constants. Interface fields are
used to provide constant values that are related to the interface. For example:
public interface GolfClub{
int DRIVER = 1;
int SPOON = 2;
int NIBLICK = 3;
int MASHIE = 4;
}

Here, any class that implements the GolfClub interface has these four fields constants available. Note that
interface fields are automatically assumed to be static, final, and public. You can include these keywords
when you create interface constants, but you don’t have to.

124
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

What are the differences between abstract classes and interfaces? Abstract class and interface both are used
to achieve abstraction where we can declare the abstract methods. Abstract class and interface both can't be
instantiated.

But there are many differences between abstract class and interface that are given below.
Abstract class Interface
Abstract class can have abstract and non-abstract Interface can have only abstract methods.
methods.
Abstract class doesn't support multiple Interface supports multiple inheritance.
inheritance.
Abstract class can have final, non-final, static and Interface has only static and final variables.
non-static variables.
Abstract class can have static methods, main Interface can't have static methods, main method or
method and constructor. constructor.
Abstract class can provide the implementation of Interface can't provide the implementation of
interface. abstract class.
The abstract keyword is used to declare abstract The interface keyword is used to declare interface.
class.
Example: Example:
public abstract class Shape{ public interface Drawable{
public abstract void draw(); void draw();
} }
Simply, abstract class achieves partial abstraction (0 to 100%) whereas interface achieves fully abstraction
(100%).

125
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Exercise
1. Write a class that does the four Arithmetic operations. Define a method that accepts two numbers and
add them and return. Overload this method so that it can accept any number data type. Similarly, define
a method for subtraction, division and multiplication and overload them.
2. Define an abstract class called Employee. Put the common things that all employees have in common
in the Employee class. One such common method is a method that computes tax. Include aslo properties
like employee ID, first name, and last name in the abstract class. Then create two derived classes that
extends the Employee class: SalariedEmployee and HourlyEmployee. In the HourlyEmployee include
a method computes the salary to be paid to the employee after accepting the hours the employee worked
and the hourly payment.
3. Declare an interface called Instrument with three methods: play(), adjust(), and what(). Then implement
these methods in Wind, Stringed, and Percussion classes. Implement all the methods of the interface in
these classes. The what() method simply returns the type of the instrument. In the other two methods,
you can produce simple output using System.out. Create instances of classes and assign to reference of
type Instrument. Call the methods and see the effect.

126
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Chapter 7
Exceptions
What is Exception?
An exceptional condition is a problem that prevents the continuation of the method or scope that is being
executed. An exception is an event, which occurs during the execution of a program that disrupts the normal
flow of the program's instructions. Division is a simple example. If you’re about to divide by zero, it’s
worth checking for that condition or otherwise program execution would be interrupted. Trying to open
non-existing file for reading is another error.

An exception is an object that’s created when an error occurs in a Java program and Java can’t automatically
fix the error. The exception object contains information about the type of error that occurred. However, the
most important information — the cause of the error — is indicated by the name of the exception class used
to create the exception. You don’t usually have to do anything with an exception object other than figure
out which exception you have.

Example: a code that generates an exception (division by 0)


1: class Division {
2: static void subroutine() {
3: int a = 10 / 0;
4: }
5: public static void main(String args[]) {
6: Division.subroutine();
7: }
8: }

The resulting stack trace from the default exception handler shows how the entire call stack is displayed:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Division.subroutine(Division.java:3) at Division.subroutine(Division.java:3)
at Division.main(Division.java:6)
Java Result: 1

Types of Exceptions
All exceptions are descendants of Throwable class which is the parent of all exceptions. Thus, Throwable
is at the top of the exception class hierarchy. Immediately below Throwable are two subclasses that partition
exceptions into two distinct branches. One branch is headed by Exception. The other branch is headed by
Error.

127
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Fig Types of exceptions

There are three kinds of exceptions. The first kind of exception is the checked exception. These are
exceptional conditions that a well-written application should anticipate and recover from. For example,
suppose an application prompts a user for an input file name, and then opens the file for reading. Normally,
the user provides the name of an existing, readable file, so the execution of the application proceeds
normally. But sometimes the user supplies the name of a nonexistent file, and opening the file fails throwing
java.io.FileNotFoundException. A well-written program will catch this exception and notify the user of the
mistake, possibly prompting for a corrected file name.

All exceptions that extend Throwable class except RuntimeException and Error are known as checked
exceptions e.g. FileNotFoundException, IOException, SQLException, etc. Checked exceptions are
checked at compile-time and the program will not compile if it is not handled.

The second kind of exception is the error. These are exceptional conditions that are external to your
application, and that the application usually cannot anticipate or recover from. Once error occurs, the
application can’t recover from it and hence comes to a halt. Exceptions of type Error are used by the Java
run-time system to indicate errors having to do with the run-time environment itself. For example, suppose
that an application successfully opens a file for reading, but is unable to read the file because of a hardware
or system malfunction. The unsuccessful read will throw java.io.IOError. StackOverflowError is another
example of such an error that is thrown when the program runs out of stack space. Another error is
OutofMemoryError thrown when there is shortage of memory. An application might choose to catch this
exception, in order to notify the user of the problem.

Errors are not possible to catch and handle.

Example: this code causes stack overflow error


public class Test {
void method1() {

128
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

method2();
}
void method2() {
method1();
}
public static void main(String args[]) {
Test test = new Test();
test.method1();
}
}

Output:
Exception in thread "main" java.lang.StackOverflowError
at javatest.StackOverflow.method1(StackOverflow.java:3)
at javatest.StackOverflow.method2(StackOverflow.java:6)
….

The third kind of exception is the runtime exception. These are exceptional conditions that are internal to
the application, and that the application usually cannot anticipate or recover from. These usually indicate
programming bugs, such as logic errors or improper use of an API. For example, consider the application
described previously that passes a file name to the constructor for FileReader. If a logic error causes a null
to be passed to the constructor, the constructor will throw NullPointerException. The application can catch
this exception, but it probably makes more sense to eliminate the bug that caused the exception to occur.

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

Example: run time exceptions


String s = null;
System.out.println(s.length()); //NullPointerException

String s = "abc";
int i = Integer.parseInt(s); //NumberFormatException

int a[] = new int[5];


a[10] = 50; //ArrayIndexOutOfBoundsException

Errors and runtime exceptions are collectively known as unchecked exceptions.

Catching Exceptions
When the Java run-time system detects exceptions, such as an attempt to divide by zero, it constructs a new
exception object and then throws this exception. This causes the execution of the program to stop, because
once an exception has been thrown, it must be caught by an exception handler and dealt with immediately.

If the program does not supply any exception handlers of its own, the exception is caught by the default
handler provided by the Java run-time system. Any exception that is not caught by your program will
ultimately be processed by the default handler. The default handler displays a string describing the
exception, prints a stack trace from the point at which the exception occurred, and terminates the program.
The exception message you have seen above for the division by zero is produced by default handler.

129
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

In general, whenever you use a statement that might throw an exception, you should write special code to
anticipate and catch the exception.

You catch an exception by using a try statement, which has this general form:
try {
block of code that may generate errors
}catch (ExceptionType1 exOb) {
code executed when exception ExceptionType1 is generated
}catch (ExceptionType2 exOb) {
code executed when exception type ExceptionType2 is generated
}
finally {
block of code to be executed before try block ends
}

Here, you place the statements that might throw an exception within a try block. Then, you catch the
exception with a catch block. ExceptionType is the type of exception that has occurred.

Here are a few things to note about try statements:


• You can code more than one catch block. That way, if the statements in the try block might throw
more than one type of exception, you can catch each type of exception in a separate catch block.
• For scoping purposes, the try block is its own self-contained block, separate from the catch block.
As a result, any variables you declare in the try block are not visible to the catch block. If you want
them to be, declare them immediately before the try statement.
• You can also code a special block called a finally block after all the catch blocks.
• The various exception classes in the Java API are defined in different packages. If you use an
exception class that isn’t defined in the standard java.lang package that’s always available, you
need to provide an import statement for the package that defines the exception class.

Example: handling division by 0 exception


class Division {
public void subroutine() {
try{
int a = 10 / 0;
}catch(ArithmeticException xp) {
System.out.print(xp.getMessage());
}
}
public static void main(String args[]) {
Division.subroutine();
}
}

Output:
java.lang.ArithmeticException: / by zero

The above try catch handles only one type of error i.e. ArithmeticException. If the code in the try catch
generates other types of exception, the try catch will not handle it. To handle all kinds of exception, it is

130
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

possible to make it general using Exception class which can catch any kind of error instead of
ArithmeticException.

Example: handling all types of exception with one catch


public void subroutine() {
try{
int a = 10 / 0; //this generates ArithmeticException error
String name = null;
if(name.equals(“John”)) //this generates NullPointerException error
System.out.println(“Your name is John”);
}catch(Exception xp) {
System.out.print(xp.getMessage());
}
}

The finally Block


A finally block appears after all of the catch blocks for a statement. It is executed whether or not any
exceptions are thrown by the try block or caught by any catch blocks. Its purpose is to let you clean up any
mess that might be left behind by the exception, such as open files or database connections.

The finally block always executes when the try block exits. This ensures that the finally block is executed
even if an unexpected exception occurs.

But finally is useful for more than just exception handling — it allows the programmer to avoid having
cleanup code accidentally bypassed by a return, continue, or break statements. Putting cleanup code in a
finally block is always a good practice, even when no exceptions are anticipated.

The basic framework for a try statement with a finally block is this:
try {
statements that can throw exceptions
}
catch (exception-type identifier) {
statements executed when exception is thrown
}
finally {
statements that are executed whether or not
exceptions occur
}

Example:
public class DivisionWithZeros {
public static void main(String[] args) {
int answer = divideNumbers(5, 0);
}
public static int divideNumbers(int a, int b) {
try {
int c = a / b;
System.out.println(“It worked!”);
}
catch (Exception e) {

131
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println(“It didn’t work.”);


}
finally {
System.out.println(“Better clean up the mess.”);
return 0;
}
}
}

Output:
It didn’t work.
Better clean up the mess.

Exception Propagation
When an error occurs within a method, the method creates an object and hands it off to the runtime system.
The object, called an exception object, contains information about the error, including its type and the state
of the program when the error occurred. Creating an exception object and handing it to the runtime system
is called throwing an exception.

After a method throws an exception, the runtime system attempts to find something to handle it. The set of
possible codes to handle the exception is the ordered list of methods that had been called to get to the
method where the error occurred. The list of methods is known as the call stack.

The call stack.

The call stack showing three method calls, where the first method called has the exception handler.

The runtime system searches the call stack for a method that contains a block of code that can handle the
exception. This block of code is called an exception handler. The search begins with the method in which
the error occurred and proceeds through the call stack in the reverse order in which the methods were called.
When an appropriate handler is found, the runtime system passes the exception to the handler. An exception
handler is considered appropriate if the type of the exception object thrown matches the type that can be
handled by the handler.

The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all
the methods on the call stack without finding an appropriate exception handler, the runtime system (and,
consequently, the program) terminates.

132
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Searching the call stack for the exception handler.

The call stack showing three method calls, where the first method called has the exception handler.

Exception Objects
Inside the standard package java.lang, Java defines several exception classes. The most general of these
exceptions are subclasses of the standard type RuntimeException. Since java.lang is implicitly imported
into all Java programs, most exceptions derived from RuntimeException are automatically available.

Each type of exception that can occur is represented by a different exception class. For example, here are
some typical exceptions:
• ArithmeticException: You tried an illegal type of arithmetic operation, such as dividing an integer
by zero.
• ArrayIndexOutOfBoundsException: when array index is past the last array index.
• ClassNotFoundException: a necessary class couldn’t be found.
• FileNotFoundException: when you try to open a file for reading/writing but the file does not exist.
• IllegalArgumentException: you passed an incorrect argument to a method.
• IOException: A method that performs I/O encountered an unrecoverable I/O error.
• InputMismatchException: the console input doesn’t match the data type expected by a method
of the Scanner class.
• NegativeArraySizeException: array created with a negative size.
• NullPointerException: occurs when your program creates an object reference, but has not yet
created an object and assigned it to the reference. Attempting to use such a null reference causes a
NullPointerException to be thrown.
• NumberFormatException: invalid conversion of a string to a numeric format.
• StringIndexOutOfBounds: attempt to index outside the bounds of a string.

There are many other types of exceptions besides these.

Exception classes have built-in methods and fields. We can get information about the exception using this
methods and fields. Though there are many methods in exception classes, the following are the most
important.
Method Description

133
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

String getMessage() A text message that describes the error.


void printStackTrace() Prints the stack trace to the standard error stream.
void printStackTrace
Sends the stack trace to the specified stream.
(PrintWriter stream)
Returns a description of the exception. This description includes the name
String toString()
of the exception class followed by a colon and the getMessage message.

Example: displaying information about the error using exception object methods
try {
int c = 10 / 0;
}
catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}

Output:
/ by zero
java.lang.ArithmeticException: / by zero
at Division.main(Division.java: 8)

Multiple catch Clauses


In some cases, more than one exception could be raised by a single piece of code. To handle this type of
situation, you can specify two or more catch clauses, each catching a different type of exception. When an
exception is thrown, each catch statement is inspected in order, and the first one whose type matches that
of the exception is executed. After one catch statement executes, the others are bypassed, and execution
continues after the try/catch block.

Example:
class MultiCatch {
public static void main(String args[]) {
try {
int a = args.length;
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
} catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out of bounds: " + e);
}
System.out.println("After try/catch blocks.");
}
}

This program will cause a division-by-zero exception if it is started with no commandline parameters, since
a will equal zero. It will survive the division if you provide a command-line argument, setting a to

134
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

something larger than zero. But it will cause an ArrayIndexOutOfBoundsException, since the int array
c has a length of 1, yet the program attempts to assign a value to c[42].

When you use multiple catch statements, it is important to remember that exception subclasses must come
before any of their superclasses. This is because a catch statement that uses a superclass will catch
exceptions of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after
its superclass. Further, in Java, unreachable code is an error.

Example: this program contains an error.


class SuperSubCatch {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
} catch(Exception e) {
System.out.println("Generic Exception catch.");
}
/* this catch is never reached because ArithmeticException is a subclass of Exception. */
catch(ArithmeticException e) { // ERROR - unreachable
System.out.println("This is never reached.");
}
}
}

Throws clause
If a method is capable of causing an exception that it does not handle, it must specify this behavior so that
callers of the method can guard themselves against that exception. You do this by including a throws clause
in the method’s declaration. A throws clause lists the types of exceptions that a method might throw. This
is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses.

All other exceptions that a method can throw must be declared in the throws clause. If they are not, a
compile-time error will result. This is the general form of a method declaration that includes a throws
clause:
[access modifier] type method-name(parameter) throws ExceptionType1, ExceptionType2, …
{
body of method
}

Example: using throws


class Test {
double salary[] = {2000, 4000, 3000, 7000, 1000, 15000};
public void displayArray() throws ArrayIndexOutOfBoundsException {
for(int i=0; i < 10; i++)
System.out.print(salary[i]);
}
public static void main(String args[]) {
try{
Test dv = new Test();
dv.displayArray();
}catch(Exception xx) {

135
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

System.out.println("Error:" + xx.toString());
}
}
}

Output:
Error:java.lang.ArrayIndexOutOfBoundsException: 6

The displayArray() method throws a type of exception called ArrayIndexOutOfBoundsException. The loop
in the body tries to iterate 10 times but the array has only 6 elements. This generates an error when the value
of i is 6. This throws an exception. But there is no exception handler in the method, and hence the exception
is passed to the calling method. The main method which calls displayArray() should have a try catch block
to handle this error. The output given above is produced by the main method.

Throwing an Exception
So far, you have only been catching exceptions that are thrown by the Java run-time system. However, it is
possible for your program to throw an exception explicitly, using the throw statement.

The throw statement is executed to indicate that an exception has occurred and the method execution could
not complete successfully. This is called throwing an exception. A throw statement specifies an object to
be thrown.

All methods can use the throw statement to throw an exception. The throw statement requires a single
argument: a throwable object. Throwable objects are instances of any subclass of the Throwable class.
Here's an example of a throw statement.
throw someThrowableObject;

The flow of execution stops immediately after the throw statement; any subsequent statements are not
executed. The nearest enclosing try block is inspected to see if it has a catch statement that matches the
type of the exception. If it does find a match, control is transferred to that statement. If not, then the next
enclosing try statement is inspected, and so on. If no matching catch is found, then the default exception
handler halts the program and prints the stack trace.

Example: check division by 0 and throw an exception


class Division {
public void subroutine() throws Exception {
int a, b = 0;
if(b == 0)
throw new ArithmeticException ("zeeroo");
a = 10 / 0;
}
public static void main(String args[]) {
try{
Division dv = new Division();
dv.subroutine();
}catch(Exception xx) {
System.out.println(xx.getMessage());
}
}
}

136
Prepared by:Tesfamariam G.
Learning module for Java 2015 E.C

Output:
zeeroo

Here are the essential points to glean from the above example:
• You throw an exception by executing a throw statement. The throw statement specifies the type of
exception object to be thrown.
• If a method contains a throw statement, it must include a throws clause in its declaration.
• A method that calls a method that throws an exception must either catch or throw the exception.

Example:
class Test {
double salary[] = {2000, 4000, 3000, 7000, 1000, 15000};
public double getElement(int i) throws ArrayIndexOutOfBoundsException {
if(i >= salary.length)
throw new ArrayIndexOutOfBoundsException("Trying to access invalid array location");
else
return salary[i];
}
public static void main(String args[]) {
try{
Test dv = new Test();
dv.displayArray();
}catch(Exception xx) {
System.out.println("Error:" + xx.getMessage());
}
}
}

Output:
Error: Trying to access invalid array location

137
Prepared by:Tesfamariam G.

You might also like