You are on page 1of 150

History of Java and Tour of JDK

Java is an object-oriented programming language developed by Sun Microsystems, and modeled


on C++, the Java language was designed to be small, simple, and portable across platforms and
operating systems, both at the source and at the binary level, which means that Java programs
(applets and applications) can run on any machine that has the Java virtual machine installed

One might be surprised to learn that Java did not come into being because of Internet or World
Wide Web (WWW), although it was WWW which propelled into java what it is as a language
today and a de-facto standard for Server Side Softwares.

Because of the similarities between C++ and Java, it is tempting to think of Java as the “Internet
version of C++”, but it would be a big mistake since Java has practical and philosophical
difference with C++.

The history of java goes back to 1991, when a group of Sun Engineers led by Mr. Patrick
Naughton and James Gosling wanted to design a small computer language that was to be used
for consumer and electronic devices like Remote Controls, TV Switchboxes etc. Now since these
devices were manufactured by different manufacturers who may choose different CPUs (Central
Processing Units), the program should not be tied down to any single architecture. The project
was code named “Green”.

The languages was then called as Oak and since Oak was already an existing computer
languages, it was code named as JAVA. But unfortunately, Sun did not get the project for which
they were bidding and it was in 1994 with the advent of the WWW and browsers, java was
propelled back in to the main stream.

The JAVA as a language was reveled to the world in the Sun world 1995 conference and from
there onwards different versions have come out with all the latest technologies being
incorporated. The different versions are being dealt with separately in the coming modules.

Java was basically invented as a platform independent software to be run on various electronic
devices like remote controls, micro-wave ovens etc. The emphasis was on platform
independence.

Platform independence-that is, the ability of a program to move easily from one computer system
to another-is one of the most significant advantages that Java has over other programming
languages, particularly if your software needs to run on many different platforms. If you're writing
software for the World Wide Web, being able to run the same program on many different systems
is crucial to that program's success.

It was with the increasing popularity of the Internet, java became as a language for the internet
which lays emphasis on the client-server programming.

Java achieves this platform independence by breaking up the process of compilation and
interpretation in to two individual steps. We have two separate executable files for this purpose
called the Compiler and the Interpreter.

In the earlier programming languages, any code written was compiled and immediately
interpreted to the underlying operating system machine standard and hence if the same program
was taken to another machine having a different operating system, it would not work.
In Java, after compilation a class file is generated which is also called as byte code file and this
class file is then interpreted as per the underlying machine standard. If we take this class file from
one machine to another, it would still run, because interpretation is done as per that machine’s
operating system.

The Java compiler takes your Java program and, instead of generating machine codes from your
source files, it generates bytecodes. Bytecodes are instructions that look a lot like machine code,
but are not specific to any one processor.

To execute a Java program, you run a program called a Bytecode interpreter, which in turn reads
the bytecodes and executes your Java program. The Java Bytecode interpreter is often also
called the Java virtual machine or the Java runtime

Java bytecodes are a special set of machine instructions that are not specific to any one
processor or computer system. A platform-specific Bytecode interpreter executes the Java
bytecodes

For running java programs, we would require software called as Java Development Kit, which can
be downloaded from www.java.sun.com site. The earlier version of JDK was 1.0 and the other
major versions were 1.1, 1.2 and the present version 1.3. Many authors and books also call JDK
1.3 as Java 3 and this is specifically stated to ensure that there is no confusion.

We will be studying on Java Development Kit 1.3 and all the codes and error messages are of
this version. Please note that the description of error messages differs from version to version.

Once we download the software and install the same on the machine, the directory structure
would like this and the important directories and files are explained herewith.

Name of the Folder Description

bin Contains all the executable files which is


required to run the java programs like java.exe,
javac.exe

demo Contains some demo applets and applications along with


source codes.

jre Contains the run-time environment and officially called as


the Java Runtime Environment

lib Contains the library files that support the executable and
UI development.

src.jar file archive that contains the class library source ode (a
collection of files with .java extension)

Uninst.isu file The un-installation file


Tools of JDK

After having successfully installed the JDK, we will quickly go through the various tools which will
be required for execution of the java programs.

Now for executing our tools, we would first require to set the path in the autoexec.bat directory or
we can individually create a batch file and run the same before executing java codes.

We need to insert the following line in the autoexec.bat file or in the user defined batch file and
the same is

set path= c:\jdk1.3\bin where jdk1.3 is the directory name (default directory in which u have your
jdk installed)

Once we have executed the batch file, to ensure that our jdk is properly installed, we just need to
just type javac on the dos prompt and it would give us a list of options. (Incase our jdk is not
properly installed or the path is not properly given then it would give us a bad command output)

Name of the Executable Description

javac Compiler

java Interpreter

appletviewer Applet viewer

javadoc Documentation generator

The first executable used would obviously be javac which would generate a class file from the
source code file. We can see what the various options of javac are by just calling javac on the dos
prompt. To compile a particular source we will have to say javac Test.java wherein Test.java is
the source code file name. (Note: All java files should end with the .java extension).

The java executable is for interpreting the .class file generated from the earlier compiler option.
Not interpreting a class file, we do not need to give the .java extension and it would simply be
java Test, wherein Test is the name of the class file automatically generated.

The appletviewer is a mini browser inbuilt into JDK specifically for running the java Applets. (Java
Applets are not a part of the certification exam and is not explained hence forth).

The javadoc is a document generator by which automatic documentation will be generated from
the java codes based on special comments given in the source code file. (This is also not a part
of the SL 275 objectives).

Java’s popularity is because of the following 3 important points:-

a) Applets
b) Security
c) Portability
Java Applets are simple java class files embedded in an html file which is dynamically
downloaded across the network by the web server when an appropriate APPLET Tag is
encountered.

Java Applets are dynamic in the sense that they can respond to events and user inputs and not
just simple animations or sounds.

Java programs are secure because they run within the JVM (Java Virtual Machine) which will be
talked in depth later on. Java achieves the security by confining a java program to the java
execution environment and not allowing it to access to other parts of the computer.

The other main popularity of java is the fact that it is portable (as already explained earlier).

Features of Java

The authors of java had written an influential White Paper that explains the design goals and
accomplishments of Java and they are the following which is also called as the features of java.
In each of the points the excerpts from the white paper is taken what the java designers say
about each buzzword.

1 Simple

“We wanted to build a system that could be programmed easily without a lot of esoteric training
and which leveraged today’s standard practice. So even though we found that C++ was
unsuitable, we designed java as close to C++ as possible in order to make the system more
comprehensible. Java omits many rarely used, poorly understood, confusion features of C++ that
in our experience bring more grief than benefit”.

The basic syntax of Java is a cleaned up version of C++, there is no need for header files, pointer
arithmetic, structures etc. There has been a lot of improvement of the C++ language, keeping in
touch with the basics of C++. Hence anyone coming into java from the C++ background would
find the same very simple. Also a lot of IDEs (Integrated Development Environment) Softwares
like JBuilder, Visual Café etc have been made for easy execution of java programs.

2 Object Oriented

“Simply stated, object-oriented design is a technique for programming that focuses on the data (=
objects) and on the interfaces to that object. To make an analogy with carpentry, an object
oriented carpenter would be mostly concerned with the chair he was building and secondarily with
the tools used to make it, a non object oriented carpenter would think primarily of his tools. The
object facilities of java are essentially those of C++”

Java is based on the C++ Model of OOPs which is fundamental in the achievement of the other
features of java. Java language is based on the purist’s “everything is an object” paradigm which
is simple and easy to extend. The advantages of OOPs are explained in the later sections. The
major difference between Java and C++ lies in multiple inheritance for which java has found a
better solution. The reflection mechanism and object serialization features make it much easier to
implement persistent objects and GUI builders that can integrate off the shelf components.

3 Distributed

“Java has an extensive library of routines for coping with TCP/IP protocols like HTTP and FTP.
Java applications can open and access objects across the Net via URLs with the same ease as
when accessing a local file System.”
The networking capabilities of Java are fantastic and there is a separate package called java.net
having classes related to both Socket Oriented and Packet Oriented data communication. Java
also improves on the CGI scripting and uses an elegant mechanism called Servlets and JSP
which makes server side programming in java extremely efficient.

Java was originally designed for the distributed environment of the internet by properly handling
the TCI / IP protocols. In many of the earlier languages the distributed environment was an after
thought but not Java. Java has a complete package called java.net which contains classes which
take care of the distributed environment like URL, Datagram Packet, Datagram Socket, and
URLConnection etc.

4 Robust

“Java is intended for writing programs that must be reliable in a variety of ways. Java puts a lot of
emphasis on early checking for possible problems, later dynamic (run-time) checking and
eliminating situations that are error prone. The single biggest difference between Java and C/C++
is that java has a pointer model that eliminates the possibility of overwriting memory and
corrupting data.”

Java program is robust by which it will successfully execute reliably in a variety of systems. It
was possible to achieve this because of the following features / tools of Java

a) Strictly Typed: Java is a strictly typed language and forces the programmer
to find the mistakes early in the program development and it also check the
code at compile time and at run time also. It follows strict naming principles
also.

b) Good Memory Management: Memory Management is a tedious and difficult


task in the traditional programming environments and it was the duty of the
programmer to allocated and de-allocated memory from the programs. In
java the de-allocation of memory is completely automatic because there is a
Garbage Collection which will automatically reclaim the unused objects.
(Garbage Collection is dealt in depth later on in this module).

c) Proper Handling of Exceptions: One of the reasons for the program failure
in the earlier programming languages was the mishandling of exceptional
conditions (specifically the run-time errors). Java provides for a proper object
oriented way of exceptional handling by which all errors (including run-time
errors) can and should be managed by the program.

5 Secure

“Java is intended to be used in networked / distributed environments. Towards that end a lot of
emphasis has been placed on security. Java enables the construction of virus - free, tamper free
systems.”

Java achieves this security with the concept of Java Virtual Machine (JVM) which has been
explained in depth in the later sections.

6 Architecture - Neutral

“The compiler generates an architecture neutral object file format - the compiled code is
executable on many processors, given the presence of the Java run-time system. The java
compiler does this by generating byte code instructions which have nothing to do with particular
computer architecture. Rather they are designed to be both easy to interpret on any machine and
easily translated into native machine on the fly.”

With the advantage of byte codes, it is possible for a java code which is compiled on one machine
to be executed on any other machine. This is possible due to the concept of Byte Codes
explained earlier. The goal of java was “write once, run anywhere, anytime, forever”.

7 Portable

“Unlike the C and C++, there are no implementation dependent aspects of the specification. The
sizes of the primitive data types are specified as is the behavior of arithmetic on them.”

The main advantages of java are that once written on any platform, it can be executed in the
similar way in other platforms also. This is because the data types in Java are having a fixed size
and having a fixed size of number types eliminates a major porting headache. The Strings are
saved in standard Unicode format.

“The libraries that are a part of the system define portable interfaces”

8 Interpreted

“The java interpreter can execute Java bytecodes directly on any machine to which the interpreter
has been ported. Since linking is a more incremental and light weight process, the development
process can be much more rapid and exploratory.”

As said earlier Java enables the creation of cross platform programs by compiling into an
intermediate representation called Java Bytecode. There is a great advantage while we are
developing an application with java being an interpreted language.

9 High Performance

“While the performance of interpreted bytecodes is usually more than adequate, there are
situations where higher performance is required. The bytecodes can be translated on the fly (at
run time) into machine code for the particular CPU the application is running on”

The earlier attempts at cross platform were done at the expense of performance. But java
although interpreted, 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. The java
runtime systems that provide this feature lose none of the benefits of the platform independent
code.

10 Multi-Threaded

“The benefits of multithreading are better interactive responsiveness and real time behavior”

Multi-Threading is very simply in java and threads in java also have the capacity to take
advantage of multi-processor systems if the base operating system does so. The code for the
multi-threading remains the same across machines, but the implementation of multithreading is
off-loaded to the underlying operating systems.

Java supports multi-threaded programming, which allows a programmer to write programs that
do many things simultaneously. Java comes with a elegant yet sophisticated but simple and easy
solutions for multi-process synchronization that enables a programmer to construct smoothly
running interactive systems.
11 Dynamic

“In a number of ways, Java is more dynamic languages that C or C++. It was designed to adapt
to an evolving environment. Libraries can freely add new methods and instance variables without
any effect on their clients. In java, finding out run time information is straight forward.”

Java programs carry with them substantial amounts of runtime 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.

Concept of JVM

The JVM stands for the Java Virtual Machine, an imaginary machine within which all the java
programs are executed.

The three parts of the JVM are

a) Class Loader
b) Byte-Code Verifier
c) Interpreter

The duty of the Class Loader is to load all the classes necessary for the successful compilation of
the code. Infact the package java.lang is automatically loaded without the need for importing the
same (equivalent to the famous first line include statement in C language).

After the compilation, a .class file is generated and when we execute the .class file, first of all the
Byte Code Verifier is called, whose duty is to check whether any changes have been made to the
byte codes after the same have been generated (whether the .class file have been tampered with
or not). Incase there is infact a change, it generated an exception or else allows the Interpreter to
go ahead with the code.

The Interpreter interprets the code and generates the necessary output.

The actual working of the Class Loader and Byte Code Verifier will be explained in the first code
module.

Setting the Path

By default the codes can be stored anywhere and when you type javac in the dos-prompt, it
would not know whether to look for the javac executable file and hence we need to type as
under:-

set path=c:\jdk1.3\bin

Here we assume that the directory of the JDK is jdk1.3.

Once we do this, then we do not have to worry and we can store the .java file where and just type
the above set path on the dos-prompt or even put it in the autoexec.bat file, so that we do not
have to type it every time.
Mis-Conceptions of Java

The following are the common Mis-conceptions of Java:

Java is the Internet version of C++

Although it is very true that java became a popular programming language because of the World
Wide Web and have a lot of features of C++, as it is also an Object Oriented Programming
language, it would be very wrong to take java as an extension of C++

Java has many advantages over C++ in the form of better memory management and exception
handling mechanism.

Java is Interpreted language and hence is slow for serious applications

The earlier versions of Java was slow and hence a JIT (Just in Time Compiler) and introduce and
with this the performance issues simply goes away. Java is great for network related programs
because of its intrinsic in-built classes.

All Java Programs run inside a Web Page

Java Applets run inside a web page, but it is quite possible to write stand alone java programs
that run independently of the web browser.

Java Applets are major security risk

This would not be true because all the java applets run within the Java Virtual Machine and it
would not be possible for applets to be in touch with the local file system, which the basic
requirement of Java Applets.

Brief explanation of the Important Terminology in Java

JDK

This is the short form for Java Development Kit. The Java Development Kit is the software which
is required for running Java Programs. The development environment for Java is very rich and
contains everything they need to get started creating powerful java programs

The JDK is available for most operating systems and the current version is JDK 1.3, with the beta
version 1.4 due to release very shortly. We have already seen earlier what programs are
available under the JDK and the directory structure of JDK.

J2SE

Java software can be broadly divided into 3 parts namely:

a) Java 2 Standard Edition (J2SE)


b) Java 2 Enterprise Edition (J2EE)
c) Java 2 Micro Edition (J2ME)

J2SE is for developing normal applications and applets, but not for the server side programs for
which we required J2EE Software.

The program which we work for executing our code is J2SE which we have seen earlier in the
module. The structure of the J2SE API is also discussed earlier. The J2SE JDK can be
downloaded from the site as under:-

http://java.sun.com/j2se/1.3/

Note: J2SE is the same thing as JDK 1.3.

J2EE

This stands for Java 2 Enterprise Edition, which is specifically for writing server side programs
like Servlets, Java Server Pages and Enterprise Java Beans. The J2EE is a set of specifications
based on which various Web Servers and Application Servers are said to be J2EE compliant.

Java™ 2 Platform Enterprise Edition enables solutions for developing, deploying and managing
n-tier server-centric enterprise applications

To reduce costs and fast-track enterprise application design and development, the Java 2
Platform, Enterprise Edition (J2EE ) technology provides a component-based approach to the
design, development, assembly, and deployment of enterprise applications. The J2EE platform
offers a multi-tiered distributed application model, the ability to reuse components, integrated
Extensible Markup Language (XML)-based data interchange, a unified security model, and
flexible transaction control.

Not only can you deliver innovative customer solutions to market faster than ever, but your
platform-independent J2EE component-based solutions are not tied to the products and
application programming interfaces (APIs) of any one vendor. Vendors and customers enjoy the
freedom to choose the products and components that best meet their business and technological
requirements.

J2ME

Java 2 Micro Edition is specifically used for writing embedded programs which can be executed
on Mobile Phones, PDAs (Personal Digital Assistant) and Palm Tops.

Java™ 2 Platform, Micro Edition (J2ME™) encompasses VMs and core APIs specified via
Configurations as well as vertical or market-specific APIs specified in Profiles

J2ME specifically addresses the vast consumer space, which covers the range of extremely tiny
commodities such as smart cards or a pager all the way up to the set-top box, an appliance
almost as powerful as a computer. Like the other editions, J2ME maintains the qualities that Java
technology has become famous for:
- built-in consistency across products in terms of running anywhere, any time,
over any device
- portability of the code
- leveraging of the same Java programming language
- safe network delivery
- applications written with J2ME are upwardly scalable to work with J2SE and
J2EE

With the delivery of J2ME, Sun provides a complete, end-to-end solution for creating state-of-the-
art networked products and applications for the consumer and embedded market. J2ME enables
device manufacturers, service providers, and content creators to gain a competitive advantage
and capitalize on new revenue streams by rapidly and cost-effectively developing and deploying
compelling new applications and services to their customers worldwide.

JVM

This stands for Java Virtual Machine and it is within this imaginary machine all the codes whether
it is a java application or a java applet is executed. The details of the JVM are explained later on
this module.

Java Hotspot

The Java HotSpot product line delivers the highest possible performance for Java applications.
Sun Microsystems has a version of Java HotSpot-technology-based VM for server-side
performance and now a version for client-side performance.

These two solutions share the Java HotSpot runtime environment, but have different compilers
suited to the distinctly different performance characteristics of clients and servers.

The Java HotSpot virtual machine (VM) is a key component in maximizing deployment of
enterprise applications. It is a core component of Java 2 Platform, Standard Edition (J2SE)
software, supported by leading application vendors and technologies.

The Java HotSpot VM supports virtually all aspects of development, deployment, and
management of corporate applications, and is used by:

Integrated development environments (IDEs), including Forte for Java, Community Edition,
Borland JBuilder, WebGain VisualCafé, Oracle JDeveloper, Metrowerks CodeWarrior, and the
NetBeans Open Source Project
Application server vendors, such as BEA Systems (WebLogic Server) and iPlanet
(iPlanetApplication Server)

Plugin

Many browsers include a JVM that is used to execute applets. Unfortunately browser JVMs
typically does not include the latest java features. The java Plugin solves this problem for us. By
using a plugin It directs a browser to use a specific JRE rather than the browser’s JVM. The JRE
is a subset of JDK. It does not include the tools and classes that are used in a development
environment.

Java API

API stands for Application Programming Interface and Java API is a set of pre-defined classes
which we will be using in our applications and applets. The Java API is not a part of the software
download and needs to be downloaded separately from the sun site.

JRE

JRE stands for Java Runtime Environment. Every java program would require a JRE for the
programs to be executed. When we install the JDK, the JRE is automatically installed in the
machine and the JRE for the applets is inbuilt into the browser.

Hot Java

HotJava was initial browser build by Sun Microsystems to show off the powers of java. The
builders had in mind the power of what is now called as applets so they made the HotJava
browser capable of interpreting the intermediate bytecodes. Nowadays most of the browsers
have in-build JRE in the system.

JAR

This stands for Java Archive and is an executable file which is present in the bin directory of the
JDK. The jar.exe is used for creating jar files and has various options by which we can add to an
archive, or extract from the archive or delete some files from the archive.

JAR (Java Archive) is a platform-independent file format that allows you to bundle a Java applet
and its requisite components (.class files, images and sounds) into a single file. Using the new
ARCHIVE attribute of the <APPLET> tag, this JAR file can be downloaded to a browser in a
single HTTP transaction, greatly improving the download speed. In addition, JAR supports
compression, which reduces the file size, further improving the download time.

The concept of JAR is very important for the preparation of Java Beans in which we will combine
all the java bean codes and then load the jar file in the bean box. This will be explained in Unit 2
when we do Java Beans.

AWT

This stands for Abstract Window Toolkit which is the GUI part of Java. All the class files related to
the GUI part like Buttons, Checkboxes, Menus are all a part of the awt package present in the
core java API.

We will be doing AWT in Section II of this module later on and all the class files will be explained
at that time.
Swing

Swing is a part of the Java Foundation Class and it is used for creating 100% pure java
components. The AWT class components rely more on the underlying operating system for their
look and feel and hence a component created in Windows will look slightly different from the
same component created in Mac machine.

However Swing components are pure and full java components and a swing Button created in
windows will look exactly the same created in Mac. All the swing components are present in the
swing package in the core API.

Applets

Applets are java class files which are embedded in an html file which is loaded and executed by a
web browser. The important classes and interfaces for Applets are present in the applet package
of the core java API. Applets are executed within the JVM present in the Web Browser and
cannot interact with the local files in the system and hence cannot transmit viruses.

Servlets

Java Servlets are server-side Java programs that web servers can run to generate content in
response to a client request in much the same way as CGI programs do. Servlets can be thought
of as applets that run on the server side without a user interface. Servlets are invoked through
URL invocation.

The main advantage of Servlet is that once started all the future requests are serviced by the
service () method of the Generic Servlet or the doGet() and doPost() method of the HttpServlet
class. Servlets are a part of the J2EE specifications and we can have session tracking, Http
Tunneling and a lot of other server side features with Servlets.

JSP

It stands for Java Server Pages. A Java Server Page (JSP) is a page much like an HTML page
that can be viewed in a web browser. However, as well as containing HTML tags, it can include a
set of JSP tags (understood by the server) that extend the ability of the web page designer to
incorporate dynamic content in a page. These tags provide functionality such as displaying
property values using simple conditionals, and are understood by the server's JSP engine.

One of the main benefits of Java Server Pages is that, like HTML pages, they do not need to be
compiled. The web page designer simply writes a page that uses HTML and JSP tags, and puts it
on their web server. The web page designer does not need to learn how to define Java classes or
use Java compilers.

JSP pages can access full Java functionality in the following ways:

• by embedding Java code directly in scriptlets in the page


• by accessing Java beans
• by using server-side tags that include Java Servlets

Both beans and Servlets are Java classes that need to be compiled, but they can be defined and
compiled by a Java programmer who then publishes the interface to the bean or the Servlet. The
web page designer can access a pre-compiled bean or servlet from a JSP page without having to
do any compiling themselves.
Java Beans

JavaBeans brings component technology to the Java platform. With the JavaBeans API you can
create reusable, platform-independent components. Using JavaBeans-compliant application
builder tools, you can combine these components into applets, applications, or composite
components. JavaBean components are known as Beans. The JavaBeans architecture defines
Java's reusable software component model.

Java Beans is a software Component. A bean is a reusable, platform neutral component, which
can be visually manipulated in a builder tool.

Primarily Java Bean is taken as a black box that is a software device with a known functionality,
but unknown internal functioning. The 3 interface facets that can be developed to independent
degrees are:

a) The methods that can be invoked on a bean


b) The readable and / or writeable properties that the bean expose
c) The events that a bean can signal to the outside world or accept from it.

EJB

EJB architecture is component architecture for the development and deployment of transactional
distributed object applications based server side software components. Applications written
using EJB is scalable, transactional and multi user secure. These applications may be written
once and then deployed on any server platform that supports the EJB specs.

EJB specifies a server side component model. Using a set of classes and interfaces from the
javax.ejb packages, developers can create, assemble and deploy components that conform to
the EJB specs. The various parties in the EJB are:

- The Bean: These are reusable business components that companies can purchase and use
to help solve business problems. Beans are not complete applications, but rather are
deployable components that can be assembled into a complete solution.

- The Container: This supplies the low-level runtime execution environment needed to run
EJB applications.

- The Service Provider: This is the application server logic to contain, manage and deploy
components. BEA, SilverStream, WebSphere, iPlanet etc.

- The Application Assembler: This is the overall application architect, for a specific
deployment. The mail goal is to combine various components and write the applications that
use components.

- The Deployer: The application made is deployed or installed into one or more application
servers.

- The System Administrator: Overall supervision of the deployed systems.

RMI

Remote Method Invocation (RMI) enables programmers to create distributed Java-to-Java


applications, in which the methods of remote Java objects can be invoked from other Java virtual
machines, possibly on different hosts.
A Java program can make a call on a remote object once it obtains a reference to the remote
object, by receiving the reference as an argument or a return value. A client can call a remote
object in a server, and that server can also be a client of other remote objects. RMI uses object
serialization to marshal and unmarshal parameters and does not truncate types, thereby
supporting true object-oriented polymorphism

JDBC

JDBC is a standard SQL database access interface that provides uniform access to a wide range
of relational databases. It also provides a common base on which higher level tools and
interfaces can be built. This comes with an ODBC Bridge. All the classes related to database
connectivity are in the java.sql package.

JDBC does the following things:

a) establish connection with a database


b) send SQL statements
c) processes the results

JDBC is the interface between the database and java end user application, servlet applet.
The Steps in JDBC are

1) Import the necessary classes.


2) Load the JDBC Driver
3) Identify the Data Source
4) Allocate a Connection Object
5) Allocate a Statement Object
6) Execute a Query using the Statement Object
7) Retrieve Data from the returned Result Set Object
8) Close the RS
9) Close the Statement
10) Close the Connection
JNI

Java Native Interface (JNI) is a standard programming interface for writing Java native methods
and embedding the Java virtual machine into native applications. The primary goal is binary
compatibility of native method libraries across all Java virtual machine implementations on a
given platform.

The Java 2 SDK extends JNI to incorporate new features in the Java platform. The changes are
driven by licensee and user comments.

The Java 2 SDK still supports the old native method interface (NMI), which was originally
implemented in Java Development Kit (JDKTM) 1.0. The old NMI is not part of the Java platform
standard, and is not supported by the Java HotSpot performance engine.

The JNI allows Java code that runs within a Java Virtual Machine (VM) to operate with
applications and libraries written in other languages, such as C, C++, and assembly. In addition,
the Invocation API allows you to embed the Java Virtual Machine into your native applications.

Java 2D

The Java 2D API introduced in JDK 1.2 provides enhanced two-dimensional graphics, text, and
imaging capabilities for Java programs through extensions to the Abstract Windowing Toolkit
(AWT). This comprehensive rendering package supports line art, text, and images in a flexible,
full-featured framework for developing richer user interfaces, sophisticated drawing programs and
image editors.

The Java 2D is used to display and print 2D graphics in the java programs. Java 2D API enables
us to display complex charts and graphs that use various lines and fill styles to distinguish sets of
data and also enables you to store and to manipulate image data--for example, you can easily
perform image-filter operations, such as blur and sharpen

Java 3D

Developers can easily incorporate high-quality, scalable, platform-independent 3D graphics into


Java technology-based applications and applets.

The Java 3DTM application programming interface (API) provides a set of object-oriented
interfaces that support a simple, high-level programming model. This enables developers to build,
render, and control the behavior of 3D objects and visual environments.

By leveraging the inherent strengths of the Java language, Java 3D technology extends the
concept of "Write Once, Run Anywhere" to 3D graphics applications.

JNDI

The Java Naming and Directory Interface (JNDI) is a standard extension to the Java platform,
providing Java technology-enabled applications with a unified interface to multiple naming and
directory services in the enterprise.

As part of the Java Enterprise API set, JNDI enables seamless connectivity to heterogeneous
enterprise naming and directory services. Developers can now build powerful and portable
directory-enabled applications using this industry standard. The Java Naming and Directory
Interface (JNDI) 1.2 is a major new upgrade release that adds new functionality to the basic
naming and directory support offered in the 1.1.x releases. New features include event
notification, and LDAPv3 extensions and controls. This release contains valuable contributions
from the following companies: Netscape, Novell, Tarantella Inc, Sun, BEA.

Java IDL

Java TM IDL is a technology for distributed objects--that is, objects interacting on different
platforms across a network. Java IDL is similar to RMI (Remote Method Invocation), which
supports distributed objects written entirely in the Java programming language. However, Java
IDL enables objects to interact regardless of whether they're written in the Java programming
language or another language such as C, C++, COBOL, or others.

This is possible because Java IDL is based on the Common Object Request Brokerage
Architecture (CORBA), an industry-standard distributed object model. A key feature of CORBA is
IDL, a language-neutral Interface Definition Language. Each language that supports CORBA has
its own IDL mapping--and as its name implies, Java IDL supports the mapping for Java. CORBA
and the IDL mappings are the work of an industry consortium known as the OMG, or Object
Management Group. Sun is a founding member of the OMG, and the Java IDL team has played
an active role in defining the IDL-to-Java mapping.

To support interaction between objects in separate programs, Java IDL provides an Object
Request Broker, or ORB. The ORB is a class library that enables low-level communication
between Java IDL applications and other CORBA-compliant applications.
Java Collections

This is the new API introduced in Jdk 1.2. A collection (sometimes called a container) is simply an
object that groups multiple elements into a single unit. Collections are used to store, retrieve and
manipulate data, and to transmit data from one method to another. Collections typically represent
data items that form a natural group, like a poker hand (a collection of cards), a mail folder (a
collection of letters), or a telephone directory (a collection of name-to-phone-number mappings).

Java 2 provides several types of collections, such as linked lists, dynamic arrays and hash tables
for our use. Collections offer a new way to solve several common programming problems. The
core of the Collection API is the new set of Interface called Set, Map and List.

X.509 Certificates

Certificates are digital documents attesting to the binding of a public key to an individual or other
entity. They allow verification of the claim that a given public key does in fact belong to a given
individual. Certificates help prevent someone from using a phony key to impersonate someone
else.

In their simplest form, certificates contain a public key and a name. As commonly used, a
certificate also contains an expiration date, the name of the certifying authority that issued the
certificate, a serial number, and perhaps other information. Most importantly, it contains the digital
signature of the certificate issuer. The most widely accepted format for certificates is defined by
the ITU-T X.509 international standard and thus, certificates can be read or written by any
application complying with X.509

ITU-T Recommendation X.509 [CCI88c] specifies the authentication service for X.500 directories,
as well as the widely adopted X.509 certificate syntax. The initial version of X.509 was published
in 1988, version 2 was published in 1993, and version 3 was proposed in 1994 and considered
for approval in 1995.

JPDA

The Java Platform Debugger Architecture (JPDA) consists of three interfaces designed for use by
debuggers in development environments for desktop systems.

a) The Java Virtual Machine Debugger Interface defines the services a VM must
provide for debugging.

b) The Java Debug Wire Protocol defines the format of information and requests
transferred between the process being debugged and the debugger front end, which
implements the Java Debug Interface.

c) The Java Debug Interface defines information and requests at the user code level.

RSA Signature

Digital Signature are used as a means of security and RSA is the most widely used digital
signature algorithm and is employed by most browsers, including Netscape Navigator and
Internet Explorer

In previous releases of Java Plug-in the lack of support for RSA signatures and dynamic trust
management has impacted the usability and deployment of the Java security architecture.
In order for Plug-in to be able to verify RSA signatures in a browser-independent way, JDK 1.2.2
has bundled a Cryptographic Service Provider (CSP) with Plug-in. This CSP is capable of
verifying RSA signatures. In particular, it supports the "MD2withRSA", "MD5withRSA", and
"SHA1withRSA" digital signature algorithms.

The bundled RSA provider is automatically registered with the Java Cryptographic Architecture
framework as part of the static initializer of the PluginClassLoader.

Versions of JDK and overview of Improvements and additions


in each version and
classes deprecated in various versions till JDK1.2

The initial release of java was revolutionary and it continued to evolve at an explosive pace. After
the release of Java 1.0, the features added by java 1.1 were more significant and substantial.

JDK 1.1 added many new library elements, redefined the way events were handled by applets
and deprecated several features of 1.0.

Features added by 1.1

1) Introduction of Java Beans which is software components that are written in java

2) Serialization which allows you to save and restore the state of an object

3) RMI, which allows a java object to invoke the methods of another java object that is
located on a different machine. This is very important for distributed applications.

4) JDBC which allows programs to access SQL databases from many different vendors

5) JNI, which provides a new way for the programs to interface with code libraries written in
other languages.

6) Reflection which is the process of determining the fields, constructors and methods of a
java object at runtime

7) Various security features, such as digital signatures, message digests, access control
lists and key generation.

8) Built in support for 16 bit character streams that handle Unicode characters

9) Significant changes to event handling that improve the way in which events generated by
the GUI elements are handled.

10) Inner classes which allow for one class to be defined within another

Features added by 2.0

1) Introduction of JFC of which Swing is the most important part

2) Introduction of Collection API


3) More flexible security mechanism is now available for java program. Policy files can
define the permissions for code from various sources. These determine for example,
whether a particular file or directory may be accessed or whether a connection can be
established to a specific host and port.

4) Digital certificates provide a mechanism to establish the identify of a user. You can think
of them as electronic passport.

5) Various security tools are available that enable you to create and store digital signatures,
sign JAR files and check the signature of a jar file.

6) The Accessibility library provided feature that make it easier for people with sight
impairments or other disabilities to work with computers.

7) The java 2D API provides advanced features for working with shapes, images and text.

8) Drag and drop capabilities allow you to transfer data within or between applications.

9) Text components can now receive Japanese, Chinese and Korean characters from the
keyword. This is done by using a sequence of keystrokes to represent one character.

10) The CORBA defines an Object Request Broker (ORB) and an IDL (Interface Definition
Language).

Classes deprecated in various versions till JDK 1.2

In JDK 1.1

The most affected class in the JDK 1.1 was the Date class in which most of the constructors have
been deprecated.

In JDK 1.2

The most important methods to be deprecated are the suspend (), resume and the stop ()
methods of the Thread class, because they can typically cause dead lock in the multi-threaded
program.

Difference between Java and C / C++

Although most of the C++ syntax has been taken by java the following are the functionalities,
which are present in C++ but not in Java.

1) Java does not include structures or unions


2) No automatic conversion done that result in loss of precision. For Example conversion
from long to int must be specifically casted.
3) No global functions or variables. Since code in java programs is encapsulated within one
or more classes
4) No concept multiple inheritance
5) No concept of destructors as the feature of Garbage Collector is there.
6) No goto keyword
7) Objects are passed by reference only whereas in C++ it can be passed by value or by
reference.

The following are the new features in Java not present in C++

1) Multi-Threading
2) Java Package
3) Interface. Although we had the concept of abstract classes, there was not a concept of
interface.
4) There is only the new keyword and no delete keyword in Java
5) The break and continue jump statements can take labels also
6) A new >>> right shift operator
7) A new documentation comment which will be used by the javadoc utility
8) The boolean data type can take only true and false as values.

OOPs Concepts

Object Oriented Programming Skills (OOPs) is one of the latest techniques in Programming and
is very popular with the concept of Objects. The advantage of OOP is that everything is taken as
an object and relationship between the objects.

Object oriented programming is like building structures like for example building a Computer.
When we use OOP our overall program is made up of lots of different self contained components
called as objects. Each object has a specific role in the program and all objects can talk to each
other in a well defined way

The advantage of OOP is that internally each of the components might be extremely complicated
and but we need not know the details of each component. We just need to know the overall
system functions because each component talks to one another in a well defined way.

In java everything is taken as an object and object oriented programming is the core of java.

All computer programs consist of two elements - code and data and a program can be
conceptually organized around its code or around its data. The process - oriented model
characterizes a program as a series of liner steps (that is code) and can be thought of as code
acting on data.

In Object oriented programming model the program is organized around its data (that is objects)
and a set of well defined interfaces to that data and can be thought of as data controlling access
to code.

Any object will have two sections within itself that is data and methods. The data is the variables
which the object has and the methods are the functions which act on those variables in the
object. These two sections can also be called as the State and Behavior where the state is the
data and the behavior is the methods within the object.

The four fundamental principals of OOPs are:

a) Polymorphism
b) Data Encapsulation
c) Inheritance
d) Data Abstraction
Polymorphism is taken from the Greek work ‘poly’ which means many and ‘morphus’ which
means forms and hence polymorphism would mean many forms.

The simplest example of polymorphism would be the ‘+’ operator. When we say 10 + 10 it knows
that it has integers on both the sides and it has to perform arithmetic calculation and would give
the answer as 20, but incase we say “Hello” + “There” it would know that both the side are strings
and it has to add them up or concatenate them.

Polymorphism is supported in java by means of concept of overloading which we will look later in
this module.

Encapsulation is the mechanism that binds together code and the data it manipulates, and
keeps both safe from outside interference and misuse. This is done in java by ensuring that the
data in an object can only be accessed by the methods of that object only and incase any other
object need to access the data of an object, it cannot do it directly but only through the methods
of that object.

This feature is like a protective capsule to the data ensuring that only the methods of an object
access the data of that object.

Inheritance is the process by which one object acquires the properties of another object. The
object from which a class inherits is called the super class or the parent class and the class which
inherits is called the sub class or child class.

Take the example of Animal class which will have two sub classes called Mammal class and
Reptile class and this continues. The Inheritance interacts with Encapsulation as well. For
example, the Animal class encapsulates some properties / features and all the subclasses will
have the same properties plus any of the properties which it adds as part of its specialization.

Data Abstraction is the feature of hiding the implementation from the user. For example, when
we start the computer, we are not bothered with the complexities of how the computer boots, but
once the computer is fully started then we start working with our programs.

Similarly when we sit in a car and drivers, we are not bothered with how the steering wheel
communicates with the wheels or how the car starts up etc. Similarly when we give a program to
a client, we just tell the client to click on the executable file and how the client is abstracted away
from the minute details of how the programs functions.

So in simple words Data Abstraction means giving only details which are required by the user and
not over-burdening him with many details

Dissecting the First Code

Now let’s get to write our first code. We will open any text editor (notepad or edit command in the
dos) and type in our code as under:

IMP: Remember java is case sensitive, that would mean letters which are supposed to be in
Capital should be in Capital only or otherwise specifically.

We will now type the following 7 lines of code as specifically written in a file in the text editor
(Which can be a Notepad or any other text editor)
Code

public class Test


{
public static void main (String args [])
{
System.out.println (“Hello, Welcome to Learning Java with Prof Venkat Krishnan”);
}
}

Points to be noted:

1 All source codes should be done within classes. There can be either one class or
more than one class in any source code file.
2 A class is a template for data and is also an object.
3 The opening brace {and the closing brace} define the body of the class or the
method.
4 If the braces do not occur in matching pairs, the compiler indicates an error.
5 Semi-colons at the end of the line is mandatory and omitting the same at the end of a
statement is a syntax error. A syntax error is caused when the compiler cannot
recognize the statement. The compiler normally issues an error message to help the
programmer to locate and fix the incorrect statements. Syntax errors are violation of
the language rules.
6 There should be atleast a semi-colon or an opening brace ( { ) but not both as
together at the end of a line.
7 One can call the class whatever you want (within the limits of identifier, which we will
see in the next sub-module), but the method, which is executed first in an application,
is always called the main ().
8 When you run your java application the method main () will typically cause methods
belonging to the other classes to be executed, but the simplest possible java
application consist of one class containing the main () method.
9 There can be only one main () in any source code file.
10 There can only be one public class in a source code file.
11 The syntax of the main () is fixed and is public static void main (String args[])
12 Also note the braces. There will be one set of braces for each and every class and
one for the method.
13 The class name should always be start with a capital Alphabet. This is not mandatory
but is java coding standard.

Now let’s see what each of the words in the file is meant:

1 public – This keyword indicates that the class and method is globally accessible. The
other access modifiers are default (nothing given), private and protected, which we
will see later on.

2 static – The keyword static ensures that it is accessible even though no objects of the
class exist.

3 void – This indicates that the method has no return type. It is mandatory for every
method to have a return type and incase there is no return type, the method should
be pre-fixed with void keyword.

4 (String args []) – Every method has a (), thorough which we can pass any parameter
required for the method and in this main () we pass the String array having the name
args. The array is defined by []. The name of the array can be anything, but it is a
convention to type it as args.
5 System – This is the name of the standard class that contains variables and methods
for supporting simple keyboard input and character outputs to the display. It is
contained in a package java.lang so it is always accessible just by using the simple
class name, System.

6 out – The object out represents the standard output stream – your display screen and
is a data member of the class System. The member out is a special kind of member
of the System class. Like the main () in our program, it is also static. This means that
out exists even though there is no object of type System. The out member is
referenced by using the class name, System, separated from the member name out
by a full stop.

7 println () – This is the println () method that belongs to the object out and that outputs
anything that is within the parameters of the method. Over here we are printing out
the text string in the println method.

Now we will name the source code file as Test.java and we will compile the file by going to the
dos-prompt and writing javac Test.java.

Once the class is properly compiled we will find a .class file with the same name as the source
code file. Over here we will check what the class loader which we have learnt earlier is

We will try to see what classes are loaded when we are compiling Test.java. We have written in
the code two classes String and System. To see what classes are loaded we will compile by
writing javac -verbose Test.java. To see what options are available with javac command just type
javac and press enter at the console.

After writing -verbose command, we will see that a lot of classes are loaded when the code is
compiled and finally the .class file is generated and the total amount taken is also mentioned for
our reference.

Now we will see what a Byte Code Verifier is. We will open the .class file in an editor, it will all be
in junk characters, but we will delete one of the legible characters and again type the same
character. We have not done anything but only edit the class file to see whether the Byte Code
Verifier checks it properly or not.

We will now execute the .class file (without re-compiling the same) (by typing java Test) and
bingo it refuses to work and will throw an exception. e.g. ClassFormatError. So the Byte Code
Verifier indeed does it job.

Now we will again recompile the Test.java so that the old class file is overwritten and then
execute by calling java Test. When we call the interpreter we will not type any extension after the
File name. The Interpreter calls the class file and not the .java file. We can check this by taking
the .java file else whether and then calling the interpreter.

Source Code Layout and Comments

In a source code, as we have seen earlier, it would contain the class keyword.

But the other keywords in the layout would be package and import statement (which we will see
later on).
In a normal source code layout, the package would be the first statement or line in the code
layout and will be followed by the import statement (if any) and followed by the class keyword.

The above order is mandatory and cannot be changed.

Also it is very important to remember that we should not use existing system defined class names
as our class names.

There are 3 types of comments in java and they are

a) Single Line comment which is \\

b) Multiple Line comment which is \* and ends with *\

c) Javadoc comment which is \** and *\.

A comment is a line which is not read by the java compiler and interpreter when it goes through
the source code file.

Javadoc is a special comment which is read by the javadoc utility

A blank space or white space have no effect in java, as the compiler does not take a white space
into consideration other than when it is within a String.

Identifiers

An identifier is something which identifies a class, a method name, a variable name, or a


parameter name.

For example, we have given the class name as Test, so here Test is the identifier and args is the
identifier for the String array being passed in the main method and main the identifier etc.

An identifier can begin with the following only:-

- May begin with a letter


- May begin with a Dollar sign ($)
- May begin with a underscore (_)

So any identifier cannot start with a numerical number or any other special character. To try this
just change the Test name to 1Test and see the error coming up.

Code

public class 1Test


{
public static void main (String args [])
{
System.out.println ("Hello, Welcome to Gurukul Online Learning Systems");
}
}

Output
1Test.java:1: <identifier> expected
public class 1Test
^
1Test.java:7: '{' expected
}
^
1Test.java:1: class <error> is public, should be declared in a file named <error>.java
public class 1Test
^
3 errors

Keywords and Blocks

Keywords are words having special meaning to the Java Technology Compiler. They identify a
data type name or program construct name

goto and const are reserved words in java, which means they are not keywords, but are reserved
for future use. There are 48 basic keywords and they are as under:-

abstract do implements private throw


boolean double import protected throws
break else instanceof public transient
byte extends int return true
case final interface short try
catch finally long static void
char float native super volatile
class for new switch while
continue future null synchronized
default if package this

A block is a set of codes which will be executed at once. The block should have the opening
braces ( { ) and closing braces ( } ). All methods and classes have blocks which mean that they
are executed in one single process.

Variables

A variable is a named piece of memory that you use to store information in your java programs –
a piece of data of some description. In short variables are locations in memory in which values
are stored.

If you define a variable to store integers, for example you cannot use it to store a value that is of
decimal fraction or a string value

Before you can use a variable, you have to declare it. After it is declared, you can then assign
values to it and use it. The declaration does the following -
a) Tells the compiler what the variable name is, so that it can referenced in future

b) Tells the compiler the type of data the variable will or can hold. Java is very particular
about the data type and if you specify any variable can hold integer, then that variable
cannot hold any other data type (i.e. String, Double, Float etc) and compiler check for the
same.

c) The place of declaration decides the scope of variables, whether the variable is local
variable or class variable or instance variable.

Therefore Variables are of 3 kinds namely, Local Variable, Class Variables or Instance
Variables.

Local Variables - They are local to the method and are visible only inside the method in which
they are declared. Incase we try to access the variables outside the method it would throw an
error. The important thing to note is that method / local variables need to be initialized or the
compiler would throw an error.

Code

class Test1
{
public static void main (String[] args)
{
System.out.println(a);
}

void met1()
{
int a = 10;
}
}

Output The compiler would throw an error that it cannot resolve the symbol a. Here the compiler
is trying to tell us that it does not understand what a means over here. This is because int a is
defined in met1 () and hence becomes a method variable and we are trying to access the same in
the main method where it does not have a scope.

class Test1A
{
public static void main(String[] args)
{
int a;
System.out.println(a);
}
}

Output The compiler would throw an error stating that variable is not initialized. This is because
the rule is that method variables need to be initialized before being used.

Class Variables - These variables are declared outside the main method right in the beginning
or right at the end. The scope of the class variable is for all the methods in that particular class.

The class variables need not be initialized as they take default values.
The Important point to be noted here is that there is only one memory location for the class
variables.

Default value of a class variable:


Data Type Default Value
boolean false
char \u0000 (that is nothing)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
String null

Before we go to the instance variables, we need to understand what the meaning of an instance
is. An instance is a copy of the object which we are creating with the new keyword and each
instance shall have a copy of the class variables and methods of that object.

For example, if we have a class called Test which has a method called met1() and we need to
call the method, then first of all we would be required to create an instance of the class and then
call the method with that instance.

Code

class Test2
{
int a;
public static void main(String[] args)
{
Test2 x = new Test2();
x.met1();
}
void met1()
{
System.out.println(a);
}
}

Output It would be 0 (zero) since it has taken the default value. In the above code we are
creating an instance of class Test2 and x is called the instance and with the instance we are
calling the method. This is the standard way any non static method needs to be called.

Instance Variables: Instance variables are created when objects are instantiated and therefore
they are associated with the object. They take different value for each object.

Code

class Test4
{
int a = 10;
public static void main(String[] args)
{
Test4 x = new Test4();
x.a = 20;

Test4 y = new Test4();


System.out.println(y.a);
}
}

Output: It would print out 10. This is because when we create a new instance a copy of the class
variable is given to each of the instances and hence when we change x.a = 20, we are changing
the value of a for the instance x and when we create a new instance it would by default have the
copy of the original class variable. Over here it is important to understand that there are 3
separate memory locations, one for the class variable and two memory locations for the two
different instances and a separate memory location would be created for any new instance.

We learnt what is static earlier on, but now we will properly examine this keyword. static keyword
can be applied either to a variable or to a method.

When static keyword is applied to a class variable (it can be prefixed only to a class variable, will
give a compilation error incase applied to a method variable), then it would mean that class
variable would be shared by all the instance of the classes. There would only be one memory
location and no different locations for the instance variables. Hence any change made by one
instance would change the original class variable also. Let’s see this by way of an example.

Code

class Test4A
{
static int a = 10;
public static void main(String[] args)
{
Test4 x = new Test4();
x.a = 20;

Test4 y = new Test4();


System.out.println(y.a);
}
}

Output: It would give 20 as the answer, because when we said x.a=20, we are infact changing
the original class variable’s value also to 20, since there is only one memory location for the static
class variable and instances. Non- static class variables are also called as instance variables.

Now let us see what the static keyword means when applied to a method. We have already seen
that for a non-static method an instance of a class is required and we can call a non-static
method only with the instance of the class.

Code

class Test5
{
public static void main(String[] args)
{
Test5.met1();
}

static void met1()


{
System.out.println("Hello World!");
}
}

Output It would give the output of Hello World. This would mean that for a static method, there is
no need for the instance of a class. We can directly call the static method with the class name,
since static methods are associated with the class directly.

static methods have a limitation however that it can only access static class variables and cannot
access non-static class variables.

Code

class Test6
{
int a = 10;
public static void main(String[] args)
{
System.out.println(a);
}
}

Output It would give an error stating that non-static variables cannot be referenced from static
context.

IMP: Over here one needs to understand the difference between directly printing out the class
variable and printing out the class variable with an instance of the class.

One of the standard questions in the exam would be why the main method should always be
static? The reason is that since the main method is called first by the compiler or it is starting
point of entry into a source code file and no instance of the class is created (instances can be
created only the main method), hence the main method should be static.

Data Types

The data types specify the size and type of values that can be stored in the variable.

There is no sizeof operator in Java as the size and representation of all types is fixed and is not
implementation dependent. Hence java is called as a strictly typed language.

Each primitive data type has a name, specifies how much memory is required to store a data item
of that data type, and identifies a legal range of values from which a data item of that data type
can be obtained. Again the Primitive data types can be classified into the following 4 major
categories

a) Textual Data Type


b) Integral Data Type
c) Logical Data Type
d) Floating Data Type
Textual Data Type: This is represented by char and individual characters and can hold only
single characters - The character should be put inside quotes (‘ ‘) while defining the same.
Characters are stored in 16-it Unicode characters and the range is from 0 to 255 and there is no
negative char. For example char c = ‘a’;

It is important to note that char in C/C++ and in Java are different because in C/C++, char is an
integer type with 8 bits wide. Java uses Unicode to represent characters. Unicode defines a fully
international character set that can represent all the characters found in all human languages.

Since java is designed to allow applets to be written for worldwide use, it makes sense that it
would use Unicode to represent characters.

The following table lists the special codes that can represent nonprintable characters, as well as
characters from the Unicode character set. Characters escape codes.

Escape Meaning
\n New line
\t Tab

The Integral Data Type can be represented in 3 forms namely;

a) Decimal – Where the decimal value is two


b) Octal – Where the leading zero indicates an octal value (E.g. 077)
c) Hexadecimal – Where the leading OX indicates a hexadecimal value (E.g. OX22)

The default Integral type is int and for Long it has to be explicitly followed by the letter L.

There are 4 types of variables that you can use to store data and all of these are signed that
mean you can use both negative and positive values. The four integer types differ in the range of
values they can store, so the choice of types for a variable depends on the range of data values
you are likely to need. The four integer types are:

Type Size Range

byte 8 bits -128 to 127


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

The smallest integral type is byte. This is a signed 8-bit and is especially useful when you are
working with a stream of data from a network or file. short is a signed 16-bit data type

IMP: It is very important to note here that integer expressions using byte and short are
AUTOMATICALLY PROMOTED to int before the calculation is done. This has a specific reason
and will be explained later on.

The type long is a 64-bit and is useful for those occasions where an int type is not large enough
to hold the desired values
We should specifically write L (capital alphabet) or l (small alphabet) after the initialized value of a
long to ensure that the compiler takes it as a long value, otherwise if we just declare long l =
12345678912, the compiler will take it as a int value and give an error.

Code

class Test7
{
public static void main(String[] args)
{
long l = 12345678912;
System.out.println(l);
}
}

Output The error would be integer number is too large, which proves that in spite of declaring as
a long data type, the compiler has taken the default of integral as int. To ensure that the compiler
takes it as a long data type, the initialized value should be followed by L and then we would get
the desired result.

We said earlier that byte and short are automatically promoted to int before any calculation is
done on them. This because their values are very small and the final result would be within the
size of a byte, but in between the calculation what should be done incase it goes beyond the
range. To prevent this, byte and short are automatically promoted to int. For example (10*10*10) /
100 would give answer as 100 but in between the value has gone to 1000 which is beyond the
range of a byte.

Code

class Test8
{
public static void main(String[] args)
{
byte b = 10;
byte c = 10;

byte d = b + c;

System.out.println(d);

}
}

Output: This would a error saying loss of precision since as per the rule byte gets converted into
a int during calculations on byte and short and int values cannot be accommodated in a byte
value (as int is 32 bits and byte is 8 bits). To ensure that the code gets properly compiled the
easy way is to change the data type of d as int.

However in many cases, we would want the value of d to be as a byte value only. In this case we
would be required to cast the result to ensure that it gets stored in a byte data type and this is
done by doing it in the following manner.

byte d = (byte) (b + c);

For values which are below 127, there would be no problem and there would serious issues
incase the values go beyond the value of 127. To under this let us see the following code
Code

class Test8
{
public static void main(String[] args)
{
byte b = 10;
byte c = 13;
byte d = (byte) (b * c);
System.out.println(d);
}
}

Output The output would be -126. Now we would be thinking how in the world did this figure
comes from. Whenever we cast any value into any smaller data type, there would be issue of loss
of precision.

To understand loss of precision, let us take an example of putting a cup of tea into a saucer fully,
it is bound to overflow and some tea would be lost. Similarly when we do casting there would be
loss of values.

Now let us take the above example and analyze the same. Since the value of 130 is beyond the
range of a byte as the maximum value of a byte would be only 127, it again goes back and starts
putting the bytes in the old blocks. Remember the range of a byte is from -128 to 127. So the
value of 128 is put in -128 and so on and hence the result of -126. It is very important to note
incase the value is very big, it will go on doing the above thing till it reaches -1 and then 0 and
then 1 and till 127 and again -128 and till keep on going like this.

In Java, the only logical data type is boolean which takes only two states, true or false. In java,
unlike C and C++ boolean is neither a number nor it can be treated as one. All tests of boolean
should test for true or false. Also note that boolean states are in small caps and not like other
languages where true should mandatorily be declared as TRUE and vice versa. It is also
important to note that boolean values cannot be converted or casted with other data types also.
The boolean data type is used by the control statements like if and for etc.

Floating-point numbers are also known as real numbers are used when evaluating expressions
that require fractional precision. There are two kinds of floating point types, float and double
which represent single and double precision numbers in the width and range as under:

Type Size Range

float 32 bit 3.4e-038 to 3.4e+038


double 64 bit 1.7e-308 to 1.7e+308

The default of floating point data type is double and hence for using float we should mandatorily
use f after the values (like long).

Code

class Test9
{
public static void main(String[] args)
{
float f = 10.11;
System.out.println(f);
}
}

Output It would give an error of loss of precision, since it has taken the default value of a double.

Coding Conventions

Classes should start with Capital Alphabets. The class will compile incase we have a small
alphabet class, but then it is a convention followed in the java world and hence we would like to
differ from the general rules of convention. The second letter incase one is there in the class
should also start with Capital alphabets. For Example IndexArrayOutOfBoundsException.

The methods should start with lower alphabets and the second word in the method should be
capital. For example. startsWith (), endWidth() or getDocumentBase() methods.

The interfaces should also follow the rules layed down for classes.

The packages should start with small alphabets. For Example java.lang, java.awt. etc

All variables (class and method) should start with small alphabets and the second word should
start with Capital Alphabets like the rule for methods.

Although the $ sign is permitted as an identifier, we should try to limit the use of $ sign in the
class names, because it was a special meaning when we are using the Inner classes.

Arrays

Array is a group of similar kind of data types that is reference by a common name. Suppose if we
want a group of integers from 1 to 100 to be reference by a common name, we create an array of
them.

Each variable in an array is called array element. It is important to note that the array numbering
stars from 0 and not 1.

Array is an object and not a primitive, even if it is made up of primitives. Like objects, array
required initialization and declaration only creates a reference to the array. To explain in depth, to
create a array is to 3 steps

a) Declaration
b) Creation
c) Initialization

Declaration

One is not obliged to create the array itself when you declare the array variable. The array
variable is distinct from the array itself. This is how one declares a array.
int a [] - This is a array of integers with the variable a
String s [] - This is a array of strings with the variable s

Creation

Once you declare an array of any data type, you should create the same with the help of the new
keyword and the same is done like this

a = new int [10];

s = new String [5];

The above example shows that the array with the variable a will store integers up to 10 values
and the second example creates that the s (String variable) will store Strings up to 5 values.

Remember: The array length starts from 0

The creation of array only reserves the space in memory for 10 integers and 5 strings, but nothing
is inside it.

Initialization

Once we have the memory reserved, we can put values into each of the individual spaces like
this:

a[0] = 10; This puts 10 as the first value of the array


a[1] = 20; This puts 20 as the second value of the array and so on.

Similarly we can put strings into the 5 spaces as under;

s[0] = “Gurukul” and so on.

Direct Declaration and Creation

The above 1 and 2 steps can be do simultaneous like this

int a [] = new int [10];

It is important to note that the [] box can be put before or after the array variable. This is also
correct.

int [] a = new int[10];

Direct Initialization

Since the above process is cumbersome, we can initialize an array with your own values when
you declare it and at the same time determine how many elements it will have. This is done as
below:
int a [] = { 1,25,30,55}

This creates an array with variable name as a and with values as put into the {} and with 4
elements.

Accessing Array Values

You can refer to an element of an array by using the array variable followed by the element’s
index value enclosed between square brackets. For Example

Existing Array: int a [] = { 1,25,30,55}

If we have to access the 2nd element of the array, we will do it like this int a[1], here we use 1
because, as said earlier, the array indexing begins with 1.

Important: Any attempt to access array indexes beyond the length of the array causes runtime
error. For example: If we try to access the 5th element, it will give a runtime error, because there
is no 5th element in the array. The exception thrown would be called as
ArrayIndexOutOfBoundsException.

We will cover the topic of runtime error and the different types of exceptions thrown in the other
modules.

Code

class Test22
{
public static void main(String[] args)
{
int a [] = new int[10];
System.out.println(a[10]);
}
}

Output

java.lang.ArrayIndexOutOfBoundsException
at Test22.main(Test22.java:6)
Exception in thread "main"

Array Bounds

In the java programming language, all array subscripts begin at zero. The number of elements in
an array is stored as part of the array object, as the length attribute. This value is used to perform
bounds checking of all runtime accesses. If an out-bounds access occurs, then a runtime error
occurs.

Use the length attribute to iterate on an array as follows:

int list[] = new list [10];

for (int I = 0 ; I < list.length ; I++)


{
System.out.println[i];
)

Using the length attribute makes the program maintenance easier

Array resizing

Once created, an array cannot be resized. However you can use the same reference variable to
refer to an entirely new array. Since an array cannot be resized, this is the biggest limitation of
arrays.

int d[] = new int [6];

d = new int [10];

In this case, the first array is effectively lost unless another reference to it is retained elsewhere.

Array Copying

The java language provides a special method in the System class arraycopy () to copy arrays.
The syntax for copying array is:

System.arraycopy ( original array, 0 (index to start with), new array, 0 (index of new array from
where copying has to start), original array.length (or number of references to be copied);

The above method can be proved with the help of this example.

// original array. int a[] = {1,2,3,4,5,6};

// new larger array. int d[] = {10,9,8,7,6,5,4,3,2,1};

System.arraycopy{a,0,d,0,a.length);

After this, the array d will have the following content: 1,2,3,4,5,6,4,3,2,1}

Note: The method System.arraycopy() copies, references, not objects, when dealing with array of
objects. The objects themselves do not change.

Code

class Test23
{
public static void main(String[] args)
{
int a[] = {1,2,3,4,5};

int b[] = {10,20,30,40,50,60,70,80};

System.arraycopy(a,2,b,3,2);

for (int i = 0; i<b.length;i++)


{
System.out.println(b[i]+" ");
}
}
}

Output

10 20 30 3 4 60 70 80

Multi-Dimensional Arrays

We have only worked with one-dimensional arrays up to now, that is arrays that use a single
index.

Why would you ever need the complications of using more indexes to access the elements of an
array?

Suppose that you have a fanatical interest in the weather and you are intent on recording the
temperature each day at 10 separate geographical locations throughout the year 1999. Once you
have sorted out the logistics of actually collecting this information, you can use an array of 10
elements corresponding to the number of locations, where each of these elements is an array of
365 elements to store the temperate values. You would declare this array with the statement

float temperature [] [] = new float [10] [365];

There are 10 arrays each having 365 elements. In referring to an element, the first square
brackets enclose the index for a particular array, and second pair of square brackets encloses the
index value for an element within that array.

So to refer to the temperate for day 100 for the sixth location, you would use temperature [5] [99].

In java, multidimensional arrays are actually array of arrays. To declare a multidimensional array
a variable, specify each additional index using another set of square brackets. For example, the
following declares a two-dimensional array variable called D.

int D [] [] = new int [2] [4]

The above array creates and allocated a 2 by 4 array. Internally this acts like a matrix in which the
first square bracket is for the number of rows and the second bracket is for the number of
columns.

Remember: Note that you can have an array with 0 columns but not with 0 rows. For example

int D[] [] = new int [2] [0] - Ok

int D[] [] = new int [0] [2] - Not Ok.


Java Operators

Java provides a fully featured set of operators, most of which are taken fairly directly from C and
C++. However Java’s operators differ in some important aspects from their counterparts in these
other languages and you need to understand clearly how java’s operators function. The Java
Operators can be classified into 8 Groups as under:

a) Unary Operators
b) Arithmetic Operators
c) Comparison Operators
d) Bitwise Operators
e) Short-Circuit Operators
f) Ternary Operators
g) Assignment Operators

The Unary operators can be classified further into :

1) Increment and Decrement Operators; ++ --


2) Unary plus and minus Operators; + -
3) The boolean complement operators; !
4) The Cast operator; ()

Increment and Decrement Operators

These operators modify the value of an expression by adding or subtracting 1. So for example, if
an int variable x contains 10, then ++x results in 11 and --x give you 9. This is the case because
the increment and decrement is done on x and the value is stored in x only

To understand how the position of these operators’ ++x and x++ affect their operation, you must
understand the different between the values stored by these operations and the result value they
give. For example, you could say y = x++; then the value assigned to y will be the original value
of x and if you say y = ++x, then the value assigned to y will be 1 more than the original value of
x. It is important to note here that in both these cases the value of x will be increment by 1.

The following table shows the value of x and y, before and after particular assignment using these
operators:

Initial value of x Expression Final Value of y Final value of x

10 y = x++ 10 11
10 y = ++x 11 11
10 y = --x 9 9
10 y = x-- 10 9

The Unary + and – operators

The unary + and – operators are distinct from the more common binary + and – operators which
are usually referred to as + and – (add and subtract).
The unary + has no effect beyond emphasizing the positive nature of a numeric literal. Unary –
negates an expression. So one might make a block of assignment just like this:

x = -3;
y = +3;
z = -(y+6);

The Boolean Complement Operator !

This operator inverts the value of a boolean expression so !true gives false and !false would give
true. This operator is usually used in the body of if() and else() to be swapped.

The Cast Operator

Casting is used for explicit conversion of the type of an expression. This is only possible for
plausible target types. The compiler and runtime system check for conformance with typing rules
and incase they do not match, then casting might be required.

Casts can be applied to change the type of primitive values, for example forcing a double value
into an int value like this:

int c = 10;
double b = 15.50;
int d = (int) (c x b);

Arithmetic Operators

The next highest in precedence, after the unary operators are the arithmetic operators. The
Arithmetic Operators are divided into two further sub groups, the first group having the *, / and %
operators. The second group have the lower precedence + and – operators.

Multiplication and Division Operators

The above operators can be used on all primitive numeric types and char. Integer division can
generate an ArithmeticException from a division by zero. The multiplication and division works as
it works in simple math examples which we learnt in school.

The important point to note here is that, whether you multiply or divide two integers, the result will
be calculated using the integer arithmetic in either int or long representation and u will have to
store the same in the wider of the types to ensure that precision is maintained.

Modulo Operator %

The modulo Operator gives a value which is related to the remainder of a division. It is generally
applied to two integers, although it can be applied to floating point numbers also. For example
when you say

int a = 7
int b = 3

int c = a % b the result would be 1.

The Addition and Subtraction Operators


The + and – operators perform addition and subtraction and they apply to operands of any
numeric type, but uniquely, the + operator is also permitted when either of the operand is a String
object.

When either of the operands of a + expression is a String object, the meaning of the operator is
changed from numeric addition to concatenation of text. In order to achieve this, both operators
must be handled as a text. If both operators are in fact String objects, this simple, however if one
of the operands is not a String object, then the non string operand is converted to a String object
before the concatenation is taken place.

How operands are converted into String Objects??

It is very useful in practice to know a little about how + converts operands into String objects. For
object types, conversion to a String object is performed simply by invoking the toString () of that
object. The toString () is defined in the java.lang.Object class which is the root of the class
hierarchy and therefore all objects have a toString () method.

Conversion of an operand of primitive type to a String is typically achieved by this, indirectly using
the conversion utility method in the wrapper classes. For example, the following code explains the
situation.

Code

class Test11
{
public static void main(String[] args)
{
int a = 10;
String s = "Hello";

System.out.println(a+s);
}
}

Output The output would be 10Hello. But how did it convert the primitive data type of int to a
String, so that it can be concatenated with s. This is properly explained in the following code.

Code

class Test11
{
public static void main(String[] args)
{
int a = 10;
String s = "Hello";

Integer i = new Integer(a);


String s1 = i.toString();

System.out.println(s1+s);
}
}

Output The output would be the same as 10Hello, but we have properly explained the procedure
over here. First of all the primitive int is converted into an Object via the use of Wrapper classes
(set of classes provided for each primitive data type for conversion into an object). Please note
that there is no class specifically called as Wrapper class, all the classes together are called as
Wrapper classes, since the purpose of these classes is to wrap the primitive into an object.

IMP: The rule for the + operator is that if both sides are primitives it would perform arithmetic
calculation and incase one side is a String, it would convert the other side to a String and then do
concatenation. The process would be from left to right.

Code

class Test12
{
public static void main(String[] args)
{
String s = 10 + 10 + "Hello";

String s1 = "Hello"+10+10;

System.out.println(s);
System.out.println(s1);
}
}

Output : The output would be 20Hello and Hello1010. The first output is 20 because for the first +
operator both the sides are numeric and hence it performed arithmetic calculation and then
concatenated the result with the String because the second + operator had a String on one of its
side.

The Comparison Operators

The comparison operators all return a boolean value. There are three types of comparison:

a) Ordinal - Which tests the relative value of the numeric operands

b) Object Type - Which tests if the runtime type of an object is of a


particular type or subclass of that particular type

c) Equality - Which test if two values are the same and may be applied
to values of non-numeric types also.

Ordinal Comparison operators are of the following type:

Operator Meaning Example


< Less than x<3
> Greater than x>3
<= Less than or equal to x <= 3
>= Greater than or equal to x >= 3

Object Type comparison is done with the help of the instanceof Operator

This is the operator, which tests the class of an object at runtime. The left-hand argument can be
any object reference expression, usually a variable, while the right hand operand must be a class,
interface or array type. You cannot use a java.lang.Class object or its string name as the right
hand operands.
The instanceof operator returns true if the class of a left hand argument is the same or is some
subclass of the class specified by the right hand operand. The right hand operand may equally
well be an interface. In such a case, the test determines if the object at the left hand argument
implements the specified interface.

Note: If the left hand argument is a null type, the instanceof test simply returns false – it does not
cause an exception.

Code

class Test13
{
public static void main(String[] args)
{
A x = new A();
B y = new B();
C z = new C();

boolean k = x instanceof B;
boolean l = y instanceof A;
// boolean m = z instanceof B;

System.out.println(k);
System.out.println(l);

}
}

class A
{
};

class B extends A
{
};

class C extends A
{
};

Output: It would be false and true.

Over here we have class A which has 2 subclasses. Now we have introduced a new keyword
called extends. It is this keyword which makes possible inheritance possible in Java.

Then we create 3 instances of each of the classes. Since all comparison operators return a
boolean value, we are capturing the same in a boolean variable. First we check whether x is a
instanceof B and it return false because a superclass instance cannot be a instance of the
subclass.

Then we check whether y is a instance of A and it returns true because a subclass variable is a
instance of the subclass and also of the super class since the subclass extends the super class.
incase we remove the comment and printout the variable m also, it would result into a compilation
error because there cannot be a relationship between two unrelated classes. It will not give false
also, but a compilation error.

Equality comparison operators: == and != and equals()

The Equality comparison can be on two grounds:

a) Checking the Memory location equality (whether both the variables being checked
belong to the same memory location or not).

b) The content Equality. (checking the contents of the String)

The operators == and != test for equality and inequality, respectively returning a boolean value.
For primitive type, the concept of equality is quite straightforward and is subject to promotion
rules so that for example a float value of 10.0 is considered equal to a byte value of 10.

For variables of object type, the “value” is taken as the reference to the object; typically this is the
memory address. You should not use these operators to compare the contents of objects, such
as Strings because they will return true if two reference refer to the same object, rather than if the
two objects have an equivalent meaning.

Code

class Test14
{
public static void main(String[] args)
{
String s = "Hello";
String s1 = "Hello";
String s2 = new String ("Hello");
String s3 = new String ("Hello");

boolean a = s == s1;
boolean b = s1 == s2;
boolean c = s2 == s3;

System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}

Output: It would be true, false and false.

Now before we go to the result, we need to understand what do one mean by memory location.
There are two parts of a computer memory, a stack and a heap.

In the earlier programming languages, String was a primitive data type, but in java, they wanted it
to be an object and also as a data type and hence String is the only class which can be created
without the new keyword.

When String is initialized without the new keyword it is taken as a primitive data type and when it
is initialized with the new keyword it is taken as a proper object. Hence we cannot call the
methods of a String object on the primitive data type.
The rules for Stack and Heap are as under:-

a) primitive data types are always stored in the stack.

b) The rule in the stack is that, once we have a particular value, a memory location is
allotted to it and when another variable is initialized to the same value, a different
memory location is not created, but the same memory location now points to both the
variables.

c) Objects are always stored in the heap.

d) Whenever a object is created with a new keyword a new memory location is created
irrespective of the contents of the Object.

Now based on the above rules, we can analyze the above code as under:-

a) Both the String values of s and s1 would be stored in the stack.

b) Since both the values of s and s1 are the same, it would have the same memory
location and hence s == s1 returns true.

c) Now s2 and s3 are created with the new keyword and hence they would be allotted
separate memory locations, in the help although they have the same contents.

d) Hence s2 == s3 would return false.

e) s1 == s2 would definitely give false, because they are in separated areas of memory.

To achieve a in-depth comparison, so that two different String objects containing the text “Hello”
are considered equal, you must see the equals() rather than the == method.

IMP: We have a equals method in the Object class, which is similar to the == method which
checks for the equality on the basis of the memory location.

However in the String class the equals method have been overridden to check for the equality on
the basis of contents. Check the following code

Code

class Test15
{
public static void main(String[] args)
{
String s = new String ("Hello");
String s1 = new String ("Hello");

StringBuffer sb1 = new StringBuffer("Hello");


StringBuffer sb2 = new StringBuffer("Hello");

boolean a = s.equals(s1);
boolean b = sb1.equals(sb2);

System.out.println(a);
System.out.println(b);
}
}

Output The answer would be true and false. This is because as said earlier, the equals method
have been overridden in the String class to check for the contents whereas in the StringBuffer
class the same have not been overridden and hence it checks like the normal equals method
which is the memory location and since both are object created with the new keyword, they would
have different memory locations and hence false.

Bitwise Operators

The Bitwise Operators &, ^ and | provide AND, Exclusive-OR (XOR) and OR Operations
respectively. They are applicable to internal types.

The bitwise operations calculate each bit of their results by comparing the corresponding bits of
the two operands on the basis of these 3 rules:

a) For AND Operations, 1 and 1 produces 1 and any other combination produces 0

b) For XOR Operations, 1 XOR 0 produces 1 as does 0 XOR 1 and any other combination
produces 0

c) For OR Operation 0 OR 0 produces 0 and any other combination produces 1

The names AND, XOR and OR are intended to be mnemonic for these operations. You get 1
result from an AND operation if both the first operand and second operand are 1. An XOR gives 1
result if one or the other operand, but not both (the exclusivity part) is 1. In the OR Operation, you
get 1 result if either the first operand or the second operand (or both) is 1

Code

class Test16
{
public static void main(String[] args)
{
int a = 10;
int b = 15;

int c = a & b;
int d = a | b;
int e = a ^ b;

System.out.println(c);
System.out.println(d);
System.out.println(e);

}
}

Output The answer would be 10, 15 and 5

To check this let us first take a scientific calculator and out the bit pattern of 10 and 15.

The bit pattern of 10 is = 1010


The bit pattern of 15 is = 1111
(please remember that int is of 32 bits and since there are zeros in the beginning it is not coming
the calculator, but for calculation purpose we need to work out the 28 initial zeros also. Now each
bit in the first value will be calculated with the first bit of the second value and similarly all the 32
bits are calculated and then finally whatever bit number comes it is converted in to a integer
comes and that is how the values of 10, 15 and 5 came in the above example.

Bitwise on Boolean Operations

The &, ^ and | operators behave in fundamental the same way when applied to arguments of
boolean rather than integral types. However instead of calculating the result on a bit by bit basis
the boolean values are treated as single bits, with true corresponding to a 1 bit and false to a 0
bit. The general rules discussed in the previous section may be modified like this when applied to
boolean values

a) For AND Operations, true AND true produces true and any other combination produces
false.

b) For XOR Operations, true XOR false produces true or false XOR true produces true and
any other combination produces false.

For OR Operation, false OR false produces false and for any other combination produces true.

Operator Meaning
~ Bitwise complement
<<= Left shift assignment (x = x << y)
>>= Right shift assignment (x = x >> y)
>>>= Zero fill right shift assignment (x = x >>> y)
x&=y AND assignment (x = x & y)
x|=y OR assignment (x = x | y)
x^=y XOR assignment (x = x ^ y)

Short Circuit Logical Operators

The short circuit logical operators && and || provides logical AND and OR operations on boolean
types. Note that there is no XOR operation provided. Superficially this is similar to the & and |
operators with the limitation of only being applicable to boolean values and not integral types.

However the && and || operators have a valuable additional feature: the ability to short-circuit a
calculation if the result is definitely known. This feature makes these operators central to a
popular null-reference-handling idiom in java programming.

The main difference between the & and && and the | and || operators is that the right hand side
operand might not be evaluated at all. This behavior is based on two mathematical rules that
define conditions under which the result of a boolean AND or OR operations is entirely
determined by one operand without regard for the value of the other:

a) For a AND operation, if the Left Hand operand is false, the result is false, without regard
to the other operand.

b) For an OR operation, if the Left Hand is true, the result is true, without regard to the other
operand.
Given these rules, if the left hand operand of a boolean AND operation is false, the result is
definitely false whatever the right hand operand may be. It is therefore unnecessary to evaluate
the right hand operand. Similarly, if the left hand operand of a boolean OR operation is true, the
result is true and the right hand operand need not be evaluated.

For Example

if ((s != null) && (s.length() > 20))


{
System.out.println(s);
}

Now here if the String reference is null, then calling the s.length() method would raise a
NullPointerException. If we use the short-circuit && then that situation would not arise, because if
(s != null) returns false, then the whole test expression is guaranteed to be false. Where the first
operand is false then in && the second operand is not evaluated at all and the s.length () is not
evaluated at all.

The Ternary Operator:

The ternary operator provides a way to code simple situations (if/else) into a single expression.
The syntax for a ternary operator is

(boolean condition) ? true : false.

Here the boolean condition is evaluated and if the result is true then the value of the expression
after the ? is evaluated (here true) otherwise it is the value after the colon will be evaluated ( here
false). The sub expressions (true and false) on either side of the colon must have the same type.

Example:

int a = 10;
int b = 20;

inc c = (a>b)?40:50. This will give the value of c as 50, since (a>b) returns false and hence the
right hand side of the colon will be evaluated.

Assignment Operators

The assignment operators set the value of a variable or expression to a new value. Simple
assignment uses =. Besides simple assignments, compound “calculate and assign” is provided
by operators such as += and *=. These operators do the calculation and then assigns. The point
to be noted here with the right hand operand must be a type that is assignment compatible with
the left hand operand.

Expression Meaning
x += y x=x+y
x -= y x=x-y
x *= y x=x*y
x /= y x=x/y
Loops in Java

The Flow Controls in java is broken in to 3 modules which are as under:

b) Loops
c) Selection statements
d) Jump statements

The loops in java are

a) The for loop


b) The while loop
c) The do-while loop

The for Loop

A common requirement in programming is to perform a loop so that a single variable is


incremented over a range of values between two limits. This is frequently provided for by a loop
that uses the keyword for. The primary purpose of the for loop is to execute a block of statements
a given number of time. The for loop syntax is

for (initialization ; loop condition ; increment expression)


{
body of the loop;
}

The control for the for loop appears in parentheses followed by the keyword for. It has three parts
separated by semi-colons.

1. The first part, initialization is executed before the execution of the loop starts. This is
typically used to initialize a counter for the number of loop iterations, for example i = 0.
With a loop controlled by a counter, you can count up or doing using a integer or a
floating point variable. It is only used to set up a starting conditions.

2. The second part is the loop condition, which means the execution of the loop continues
as long as the condition you have specified in this is true. That means the loop conditions
should be a boolean conditions which will either return a true or false. This loop
conditions is checked at the beginning of each loop iteration and when it is false the
execution stops and the program continues with the statement after the loop. A simple
example of loop conditions is i < 10, which would mean that the loop would execute as
long as the variable has a value less than 10 and the moment it increases the value of
10, the loop conditions will retune false the loop stops.

3. The third part the increment expression, is executed immediately after the body of the
loop, just before the test is performed again. Commonly this is used to increment the loop
counted. This could be i++, which will increment the loop counter by one. Of course you
might want to increment the loop counter in steps other than one and in that case you
can write i +=2, in which case the loop counter gets increment by 2.

Example

for (int i = 0 ; i<5 ; i++)


{
System.out.println(“The value is now “ + i);
}

System.out.println(Out of the loop now);

The above code prints The value is now 0 till The value is now 5 and then Out of the loop now.
The execution is done in the following way

a) First of all the loop is initialized to 0, then it check whether the boolean condition is true
and in this case it is true since 0 is less then 5, then it goes into the body and the
statement” The value is now 0 is printed..

b) Then it goes to the Iteration statement and this increments the value of the loop counter
to 1

c) Then it again check the boolean condition and this continues till the boolean condition is
false and once it is false, it comes out of the loop.

d) Then the statements after the loop are executed.

Note: The for () loop allows the use of comma operators in a special way. For example

for (int i = 0, j = 0 ; j <10 ; i++, j++)


{
}

The above code initialize int i and int j to 0, the checks the boolean condition or conditions and
then increments both the variables.

IMP: The loop condition should always return a boolean value, otherwise the compiler will throw
an error.

The while Loop

The while loop executes as long as the given logical expression in the parentheses is true and
stop when the conditions becomes false. The syntax for the while loop is;

while (boolean condition)


{
Statement;
}

It is important to note here that the condition is checked at the beginning of the loop and hence if
the condition is false initially, then the loop will not execute at all.

Note here that in java the conditions can only be a boolean condition, while in C and C++ it can
be a variety of types.

The statement or statements will be executed again and again until the boolean condition
becomes false. If the condition will never become false, then it will be a infinite loop.

Code

class While
{
public static void main(String[] args)
{
int a = 0;
while (a < 10)
{
System.out.println(a);
a++;
}

}
}

The do – while Loop

The do – while loop is similar to the while loop and the only difference is that the boolean
condition is after the body of the loop, which means that even if the condition is false, the loop will
be executed atleast one. In programming, this loop is very important where we want a particular
statement to execute atleast once. The syntax for the do loop is;

do
{
statement;
}
while (boolean condition)

Each iteration of the loop first executes the body and then evaluates the conditional expression. If
this expression is true, then it will execute the body again and then checks for the condition and
this goes on till the condition becomes false.

IMP: In general programming all of the above loops is used together and all the
above loops can be nested also.

The main difference between the while and do-while loop is that incase the condition is false, the
do-while loop will be executed atleast once, whereas the while loop will not be executed at all.

Code

class DoWhile
{
public static void main(String[] args)
{
do
{
System.out.println("Hello");
}
while (false);
}
}

Output

Hello
Selection statements in Java

Java supports if – else and switch as its selection statements and we will discuss both of them in
this section

if Statement

The if statement is used to route programs execution to different paths depending on a particular
condition and the syntax for the same is;

if (condition)
{
Statement;
}

else
{
Statement;
}

As in the earlier cases, the condition checking the flow of control is a boolean condition and if the
condition is true, then the if part body will be executed or the else part of the body will be
executed.

Example

int a ;
int b ;

if (a>b)
{
int c = a;
}

else
{
int c = b;
}

In the above example we want the value of int c to be the higher value amount a and b and this
we do not know and hence we will use the if loop and if (a>b) then the value of int c will be the
value of a and if int b is higher then the value of int c will be the value of int b as stated in the else
part of the body.

Nested ifs

A nested if is an if statement that is the target of another if or else. Nested ifs are very common in
programming and when you nest a if, the important point to remember is that an else statement
always refer to the nearest if statement that is within the same block as the else.
It is very important that you use block of codes, when using the nested ifs or otherwise you will
find a result other than what you were expecting.

if-else-if ladder

The if-else-if ladder syntax looks like this

if (condition)
{
Statement;
}

else if (condition)
{
Statement;
}

else if (condition)
{
Statement;
}

else
{
Statement;
}

The if condition in the first if will be considered and like the normal if-else will not go to the else
part, but it will check the else if condition and like this it goes down the ladder. After the last else if
is encountered and then also the condition is not true then the else statement at the end of the
ladder will be executed.

Remember, if the last else statement is not there and if all the else if condition returns false then
nothing will be executed.

switch Statement

If you need to make a choice between multiple alternative execution paths and the choice can be
based on a non-boolean value, then you should use the switch () construct as we cannot use the
if-else loop. The syntax is as under:

switch (expression)
{
case value1:
{
Statement;
}

case value2:
{
Statement;
}

case value3:
{
Statement;
}

default:
{
Statement;
}

IMP: It is very important to note here that the expression must be of type byte, short, int or char
and each of the values in the cases (e.g. case value1 ....) must be type compatible with the
expression and each case should be a unique (e.g. it should not be a constant or a variable).
Duplicate case values are also not allowed.

IMP: There is a fundamental difference between the switch in C++ and java wherein we need to
mandatorily use the break statement to jump out once the case have been matched, otherwise
the control will enter all the cases and then reach the end of the loop. To understand the meaning
of the above statement, please have a look at the following code.

Code

class Test17
{
public static void main(String[] args)
{
for (int i = 0;i<3 ;i++ )
{
switch (i)
{
case 0:
{
System.out.println("Zero");
}
case 1:
{
System.out.println("One");
}
case 2:
{
System.out.println("Two");
}
default:
{
System.out.println("Default");
}

} // end of switch cases


} // end of for loop
} // end of main method.
}
Output :
Zero
One
Two
Default
One
Two
Default
Two
Default

The above output is because of the lack of break statements after the cases and hence once the
case is matched, the code enters all the subsequent cases and printout out the same (including
the default). To ensure only one case is matched and the code to exit the switch block, we will
see the following code where there is a break statement after the cases.

Code

class Test17
{
public static void main(String[] args)
{
for (int i = 0;i<3 ;i++ )
{
switch (i)
{
case 0:
{
System.out.println("Zero");
}
break;
case 1:
{
System.out.println("One");
}
break;
case 2:
{
System.out.println("Two");
}
break;
default:
{
System.out.println("Default");
}

} // end of switch cases


} // end of for loop
} // end of main method.
}

Output:

Zero
One
Two

We will see later on what is the significance of the break keyword.

The switch starts off with a expression and the value is compared with each of the literal values in
the case statements and if a match is found then the body of that case value is executed and if
none of the case values are matched the default block is always executed. The default is optional
here and if no matching case if found and there is no default then nothing will be executed.
One can use the break statement inside a switch to terminate a statement sequence. When a
break statement is encountered, the execution branches to the first line of code that follows the
entire switch statement.

The switch statement differs from the other loops in that the switch can only test for equality,
where as the other loops test for boolean condition. That is the switch looks only for a match
between the value of the expression and one in its case and has nothing to do with the boolean
conditions.

Jump statements in Java

The three jump statements in java is the break statement, the continue statement and the return
statement. The java’s jump statements help in transferring control to another part of the program.

Using break statements

Break can be used for 3 reasons

a) breaking out of the switch statements


b) breaking out of a loop
c) Labeled break to enable transfer to a particular point in the code.

We have seen how to break out of a switch statement in the earlier code.

Using Break to exit out of a loop

We can use break to force immediate termination of a loop and thereby bypassing the conditional
expression and any remaining code in the body of the loop. When break statement is
encountered inside a loop, the loop is terminated and the program control resumes at the next
statement following the loop. Let’s see a example

Code

class Test
{
public static void main(String args[])
{
for (int i=0 ; i<100 ; i++)
{
if (i==10)
{
break;
}
System.out.println(“The value of loop is “ + i);
}
System.out.println(“ The loop is complete”);
}
}
Output: The above program is to print the numbers from one to hundred, but we are having a if
condition which states that if i is equal to 10, then it should break out of the loop and then it will
print the statement that loop is complete.

The above program generates numbers till “The value of i is 9” and then will exit out of the loop
and then the next statement that “The loop is complete” will be printed out. The following points
are also important regarding the break statement:

a) The break statement is used to exit out of infinite loops.

b) When used inside nested loops, the break statement will come out of the innermost loop
and the execution of the outer loops will continue.

Using Labeled Break

Java also makes a labeled break available to you, by which you can exit out of any block with the
respective block name. It is not necessary that it have to be a loop or switch. The labeled break
enables you to break out to the statement following an enclosing block that has a label regardless
of how many levels there are. You might have nested blocks and you can exit out of any nested
block or blocks by using the respective block name (label) and the only important point here is
that you will have to name the block with the name. For Example

Block 1
{
Block 2
{
Block 3
{
if (true)
{
break Block 2 (here i can break out of any block, either 3,2 or 1)
}
}
}
The break statement inside block 3, tells to break out of block 2 and hence the point of execution
will be switched here and any statement after the break will not be executed.
}

Code

class Test19
{
public static void main(String[] args)
{
one:{
Two:{
Three:{
System.out.println("Before Break");
if (true)
{
break Two;
}
System.out.println("After Break");
}
System.out.println("After Three");
}
System.out.println("After Two");
}
System.out.println("After One");
} // end of main
} // end of class

Output: The output would be

Before Break
After Two
After One

This is because; any statement after the break within a block of codes is never executed and we
are specifically telling the compiler to break out of the block named as Two and the cursor would
be positioned outside the block Two and then all the statements would be executed.

Points to remember

a) Whenever we are having labeled block of codes, and we want to break outside, we
always need to give the block name from which to break and a simple break
statement would not work. Let us remove the block Two from the break and it would
throw the following exception.

Test19.java:11: break outside switch or loop


break ;
^
1 error

b) We need to put the break inside the if (true) block or otherwise the following error
would be generated. (comment the if block and just give break Two; inside the block
Three)

Test19.java:13: unreachable statement


System.out.println("After Break");
^
1 error

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.

For example, Incase we need to print out the values from 1 to 10 in a for loop but print only the
odd numbers, we will be using the continue statement.

Code

class Test20
{
public static void main(String[] args)
{
for(int i =1 ; i <= 10 ; i++)
{
if (i % 2 == 0 )
{
continue;
}
System.out.println(i);
}
}
}

Output
1
3
5
7
9

In the above example we are checking in the if loop incase the remainder is equal to 0 to go to
the next iteration and not complete the block of the for loop. This will ensure that it does not print
out the System.out.println() statement.

The continue statement can appear anywhere within a block of loop statements.

New Keyword

We have already seen the use of the new keyword earlier, when we created a instance of a class
and also we used the same in arrays. Now let us see in depth what does the new keyword means
and what it does.

If we have to create an object for a particular class, the same can be done with the help of a new
keyword. For example

class Test
{
int a;
int b;
double c;
}

The above class is just a template for any object creation and a new object is created with the
help of the following syntax:

Test a = new Test();

Here a is just a handle for the Test and is an instance of Test. When you create an object of class
Test, it will have its own copy of the instance variables defined by the class. Thus every Test
object will have its own copies of int a, int b and double c. Over here it is important to note that a
is a variable that refer to an object.

The following examples create new instances of the classes String, Random and store those new
instances in variables of the appropriate types:

String str = new String ();


Random r = new Random();

The parentheses are important; don't leave them off. The parentheses can be empty (as in these
examples), in which case the most simple, basic object is created; or the parentheses can contain
arguments that determine the initial values of instance variables or other initial qualities of that
object:

Date dt = new Date (90, 4, 1, 4, 30);


Point pt = new Point (0,0);

The number and type of arguments you can use inside the parentheses with new are defined by
the class itself using a special method called a constructor (you'll learn more about constructors
later). If you try and create a new instance of a class with the wrong number or type of arguments
(or if you give it no arguments and it needs some), then you'll get an error when you try to
compile your Java program.

Memory allocation and layout

When variables of any primitive type - that is boolean, int, etc - are declared, the memory space
is allocated as part of the operation. The declaration of a variable using a non-primitive type – that
is an object does not allocate space for the object.

It is the new keyword that implies allocation and initialization of storage.


Getting Values

To get to the value of an instance variable, you use an expression in what's called dot notation.
With dot notation, the reference to an instance or class variable has two parts: the object on the
left side of the dot and the variable on the right side of the dot.

IMP: Dot notation is an expression used to get at instance variables and methods inside a given
object

For example, if you have an object assigned to the variable myObject, and that object has a
variable called var, you refer to that variable's value like this:

myObject.var;

This form for accessing variables is an expression (it returns a value), and both sides of the dot
can also be expressions.

This means that you can nest instance variable access. If that var instance variable itself holds an
object and that object has its own instance variable called state, you could refer to it like this:

myObject.var.state;

Dot expressions are evaluated left to right, so you start with myObject's variable var, which points
to another object with the variable state. You end up with the value of that state variable after the
entire expression is done evaluating.

Changing Values

Assigning a value to that variable is equally easy-just tack an assignment operator on the right
side of the expression:

myObject.var.state = true;
Constructor

As already stated the new keyword dynamically allocated memory for an object. We can create
an object of a class with the new keyword and the class name is followed by parentheses
specifies the constructor for the class.

Constructor’s basic purpose is to initialize the class variables of a class when an object of the
class is created. Most of the real world classes define their own constructors and incase there is
no explicit constructor defined in a class, java provided its own constructor.

A constructor always has the same name as the class in which it is defined, has no return type
specified, and must not include a return statement. You can always specify a constructor with any
parameters as the arguments and anything in the body, which will be guaranteed to be initialized
when we use the new keyword. A default constructor has nothing in its body and has no
arguments in it.

The constructor is an unusual type of method because it has no return value. This is
distinctly different from a void return value, in which the method returns nothing
but you still have the option to make it return something else. Constructors return
nothing and you don’t have an option. If there were a return value, and if you could
select your own, the compiler would somehow need to know what to do with that
return value.

Example using constructor:

class Test
{
int a,b,c;

Test()
{

System.out.println(“This is inside the constructor”);

a = 10;

b = 5;

c = 5;
}

int met1()
{
return int d = a x b x c;
}

public static void main (String arg[])


{

Test t = new Test();

Test s = new Test();

int z = t.met1();

int y = s.met1();

System.out.println(z);

System.out.println(y);

}
}

Result: The result will be

This is inside the constructor


This is inside the constructor
250
250

As you will see both the object variables z and y were initialized with the
constructor Test, when they were created. Since the constructor gives all the object
the same dimensions, the volumes with both the object are 250.

With the new keyword a constructor is called, if available and if not a default
constructor is called. The default constructor initializes all instance variables to
zero. But it is important to note that once you define your own constructor, the
default constructor will not be called.

Points to note:

1) Constructor is like a method but without a return type, whereas the methods always
need a return type.

2) The basic purpose of the constructor is to initialize the class variables.

3) Constructor of a class is classed dynamically when a instance of a class is created,


whereas needs need to be explicitly called.

4) Constructor of a class should have the same name as the class name, whereas the
method can have any name.
Constructors make like easy for us and we will now consider two examples to prove this point
further. Now consider we have two class variables a and b which should take different values for
calculation and a method met1() which multiplies the class variables and give the output.

Code

class Test25
{
int a,b;
public static void main(String[] args)
{
Test25 x = new Test25();
x.a = 10;
x.b = 20;
x.met1();

Test25 y = new Test25();


y.a = 40;
y.b = 50;
y.met1();
}

void met1()
{
int c = a * b;
System.out.println(c);
}
}

Output

200
2000

Without a constructor we need to mandatorily create instance of the class and then with the class
instance initialize the class variables. For separate set of values for the class variables, we need
separate instances. They with the instances we call the method met1().

Code

class Test26
{
int a, b;

Test26(int x, int y)
{
a = x;
b = y;
}
public static void main(String[] args)
{
Test26 x = new Test26(10,20);
x.met1();

Test26 y = new Test26(40,50);


y.met1();
}

void met1()
{
int c = a * b;
System.out.println(c);
}
}

Output

200
2000

The output would be the same, but we saw how life is made easier for us with the use of the
constructor to initialize the class variables and we pass values to the parameters of the
constructors.

Parameter: This specifies what values can be passed inside a method or a constructor. for
example Test26 (int x, int y), we specify that the constructor should take two int values.

Arguments: This is the actual values passed in to the parameter of a method or a constructor. for
example Test26 (10,20), over here we pass the values of 10 and 20 which will call the constructor
and the values of 10 will be passed to int x and 20 will be passed to int y and inside the
constructor we initialize the class variables with the two values passed in the constructor.

Default Constructor: Until now we have created instances, without knowing the concept of
constructors at all. This would mean incase we do not have a constructor within our class then
the JVM will provide us with a default constructor which is a constructor with no parameters.

Incase we define our own parameterized constructor, then the system will no longer provide us
with the default constructor and we need to specifically create a no parameter constructor
ourselves.

Code

class Test27
{
int x;
public static void main(String[] args)
{
Test27 x = new Test27();
}

Test27(int a)
{
x = a;
System.out.println("class variable initialised");
}
}

Output

Test27.java:6: cannot resolve symbol


symbol : constructor Test27 ()
location: class Test27
Test27 x = new Test27();
^
1 error

This above code would prove our point. Now to ensure that our code functions, create a default
constructor (constructor with no parameter) and our code will function properly.
Determining the class of an Object

Want to find out the class of an object? Here's the way to do it for an object assigned to the
variable obj:

String name = obj.getClass().getName();

What does this do? The getClass() method is defined in the Object class, and as such is available
for all objects. The result of that method is a Class object (where Class is itself a class), which
has a method called getName(). getName() returns a string representing the name of the class.

Now over here we would like to bring to your notice that the superclass of all objects in java is the
class Object which is there in the java.lang package. As said earlier the java.lang package is
imported by default and incase we need to use any other class which is not there in the lang
package we would need to import the package specifically otherwise the compiler will cry.

IMP: All classes by default extend the Object package.

Code

class Test24
{
public static void main(String[] args)
{
Test24 x = new Test24();
Class c = x.getClass();
String s = c.getName();

System.out.println(s);
}
}

Output

Test24

Whenever we need to find out the class name of an object we would be using the getClass() and
the getName() methods.
this keyword

Every instance method has a variable with the name, this which refers to the
current object for which the method is being called. This is used implicitly when
your method refers to an instance variable of the class.

In the body of a method definition, you may want to refer to the current object-the object in which
the method is contained in the first place-to refer to that object's instance variables or to pass the
current object as an argument to another method. To refer to the current object in these cases,
you can use the this keyword. this keyword can be used anywhere the current object might
appear-in dot notation to refer to the object's instance variables, as an argument to a method, as
the return value for the current method, and so on.

In many cases you may be able to omit the this keyword entirely. You can refer to both instance
variables and method calls defined in the current class simply by name; the this is implicit in those
references.

Note
Omitting the ‘this’ keyword for instance variables depends on whether there are no variables of
the same name declared in the local scope.

Keep in mind that because this is a reference to the current instance of a class, you should only
use it inside the body of an instance method definition.

IMP: Class methods-that is, methods declared with the static keyword-cannot use this.

Code

class Test28
{

int x, y;
public static void main(String[] args)
{
Test28 z = new Test28(10,20);
z.met1();
}

Test28(int x, int y)
{
this.x = x;
this.y = y;
}

void met1()
{
System.out.println("The value of x is = "+x+" The value of y is = "+y);
}
}
Output

The value of x is = 10 The value of y is = 20

In the above example, we have a parameter x and a class variable whose name is also x. So we
cannot say x = x. So over here we need to tell the compiler that the parameterized x should be
passed into the class variable x and for this we do this.x = x, where this.x refers to the class
variable.

Remember that incase there is a name conflict (a class variable has the same name and the
local variable has the same name) when we just the variable, we are calling the local variable,
because the local variable hides the class variable inside the method.

The second use of this is to call another constructor of the same class within a constructor as in
this example. This concept is explained in the topic “Overloaded Constructors”.

Introducing Methods

We have already seen what a method is and how it functions etc in our examples till now.

We know that all methods need to have a mandatory return type and incase the method is not
returning anything then void keyword should be prefixed to the method name.

Methods that you define for a class provide the actions that can be carried out using the variables
specified in the class definition. Method is a self-contained block of code that has a name and has
some property that it is reusable – the same method can be executed from as many different
points in a program as you require.

A method is executed by calling the method using its name, as will see and a method may or may
not return a value, but the return type is mandatory before the method name.

The general form of a method is:

<modifier> <any other key word> turn-type> <name> (<argument list>) throws <exception (if
any)>
{
block of code;
}

There are 6 parts of the method and they should appear in the following order from left to right.

a) Access Modifier (public, private, protected or nothing which amounts to default). This
determines the accessibility of the method. We will at a later stage go into each of the
different modifiers

b) Any other keyword (like static, final, abstract) and within this it can appear in any
order.

c) Return type of the method.

d) Name of the method. The name is the name of the method, by which it will be
referenced later on in the source codes
e) Parameters of the method. The argument list allows argument values to be passed
into a method. Elements of the list are separated by a comma, while each element
consists of a type and an identifier.

f) throws statement, incase a method throws any exception (this will be dealt with in the
next module). The throws (exception) clause cause a runtime error (exception) to be
reported to the calling method so as to handle it in a suitable manner

Incase a method returns anything, then the respective data type of the return should be prefixed
before the method name and there should be a mandatory return statement as the last line in the
method. What the method return type is declared in the signature of the method (the data type
the method is declaring that it will return) should be within the conversion rules of primitive data
types.

If the method returns anything it must be specified before the modifiers name and if not so the
compiler will give a compile time error. Java is very particular about what the method returns. If
we write that the method returns int and incase it returns any other data type, the compiler again
will complain. Use the return command within a method to pass back a value.

For example, incase a method declares in the signature that it would return a int data type, then
the actual return type can be byte, short or int, but not any other data type which is larger than int
(more than 32 bits).

Code

class Test30
{
public static void main(String[] args)
{
Test30 x = new Test30();
x.met1();
}

int met1()
{
System.out.println("Inside met1");
}

Output

Test30.java:10: missing return statement


{
^
1 error

The compiler will cry here. So to make the above code run, we should have a mandatory return
statement at the end of the method like return 0 (zero).

The following points are just revision to the points that we have already mentioned earlier.

a) Similar to the variables, there are also two methods known as instance
methods and class or static methods.
b) One can execute class methods without any object of the class also,
whereas for instance methods, an object of the class should be there.
Since the class methods are declared using the static keyword, they are
also called as static methods.

c) Since class methods are executed when there are no objects in existence,
they cannot refer to instance variables. This is quite sensible – if you
think about it - trying to operate with variables that might not exist
would be bound to cause trouble. Java will not allow you to try and will
give a compile time error.

d) The best example of a class / static method is the main method and you
declare the same with the keyword static. This is because the main() is the
method from where the execution starts in an application and before an
application can start no objects will exist and hence the main() will have
to be declared as static.
Accessing Variables and methods

In many circumstance, you would want to refer to a constant or a variable or a


method of a particular class in another class. There are two rules for it

a) A static member of a class can be accessed using the class name, followed by a
period, followed by the member name. With a class method, you also need to supply
the parentheses enclosing any arguments to the method after the method name. The
period here is called the dot operator. So if you want to calculate the square root of
PI you could access the class method sqrt() and class variable PI that is defined in
the Math class as follows: double a = Math.sqrt (Math.PI);

b) Instance variables and method can only be called using an object reference, as by
definition they relate to a particular object. The syntax is exactly the same as we have
outlined for static members.

Overloading of Methods

As already discussed earlier overloading is the important concept in OOPs which allows the
feature of polymorphism in java. Overloading of methods means having the same method name,
but different type and order or parameters and depending on the values passed, the program
would know to call which method.

Code

class Test31
{
public static void main(String[] args)
{
Test31 x = new Test31();
x.met1(10);
x.met1("Hello",20);
}

void met1(int a)
{
System.out.println("Method with one parameter");
}

void met1(String s, int a)


{
System.out.println("Method with two parameters");
}

Output

Method with one parameter


Method with two parameters

So here we can conclude that the program knows how to call a method inspite of having the
same name on the basis of the parameters passed into the method.

IMP: Overloading cannot be done on the basis of different return types. Return Type itself is not
sufficient for overloading of methods. It can only be done on the basis of different type and order
of parameters. To explain the above point, have a look at the following code.

Code

class Test32
{
public static void main(String[] args)
{
Test32 x = new Test32();
x.met1(10);
x.met1(20);
}

int met1(int a)
{
System.out.println("Method with return type as int");
}

void met1(int a)
{
System.out.println("Method with return type as void");
}

Output

Test32.java:15: met1(int) is already defined in Test32


void met1(int a)
^
1 error

Since overloading cannot be done on the basis of the return type and also the parameters are
the same, the compiler is complaining that we already have a method with the same name, as
we cannot have the same identifier used twice.

Overloaded Constructors

Overloading is the basic feature of OOPs wherein you have the same method / constructor name
but different type and order of parameters.

Let us take the example of a website where in you need the users to input their name and salary.
There are 4 possibilities in this case

a) User inputs his name but not his salary


b) User inputs his salary but his name
c) User input both salary and name
d) User inputs neither salary nor name.

Now let us see how to we code this. We also want the above data to be there in the table wherein
incase there is no name, “unknown” should be there and where no salary is there, 0 should be
the amount value.

Code

public class Test29


{
String name;
int salary;

public Test29 (String n, int s)


{
name = n;
salary = s;
System.out.println("The name entered is = "+name+" and the salary is = "+salary);
}
public Test29(String n)
{
this(n,0);
}
public Test29(int s)
{
this("unknown",0);
}
public Test29()
{
this ("unknown");
}
public static void main(String arg[])
{
Test29 a = new Test29("ABC"); // user inputting only name
Test29 b = new Test29(1000); // user inputting only salary
Test29 c = new Test29("XYZ",20000); // user both name and salary
Test29 d = new Test29(); // user inputting neither name nor salary
}
}

Output

The name entered is = ABC and the salary is = 0


The name entered is = unknown and the salary is = 0
The name entered is = XYZ and the salary is = 20000
The name entered is = unknown and the salary is = 0

IMP: Any call to this, if present, must be the first statement in any constructor.

How argument values are passed.

This is one of the most important and the most confusing part of java fundamentals. The
fundamental rule for understanding how argument values are passed is:-

a) Primitive Data Types are always passed by value

b) Objects are always passed by reference.

Now what do one mean by how values are passed? This would mean when we declare
something in the parameter of a method and when actual argument is given to that method,
depending on the whether the argument value is a primitive or a object, the values are actually
passed in the method.

In java, all arguments values that belong to one of the basic primitive types are transferred to a
method using what is called the pass-by-value mechanism.

All this means is that for each argument value that you pass to a method, a copy is made and it is
the copy that is passed and referenced through the parameter name and not the original value.
This implies that if you use a variable of any of the basic primitive types as an argument, the
method cannot modify the value of the main variable in the calling program. For example;

Code

class Test33
{
public static void main (String arg[])
{
int i = 10;

Test33 t = new Test33();

int z = t.met1(i);

System.out.println("The value of the variable captured from the method is "+z);


System.out.println("The value of the actual method variable is " + i);
}

int met1(int a)
{
++a;
return a;
}
}

Output

The value of the variable captured from the method is 11


The value of the actual method variable is 10

So we can finalize the concept over here that whenever we pass a primitive data type as the
argument to the method, it would always be passed by value and the original value remains
unchanged. In the above example, what is passed as an argument to the met1() is a copy (value)
of i and not the actual i and hence what is returned is 11, caught by int z, while the value of i
remains contact at 10.

Passing objects to a method.

Until now we have seen that only simple types are parameters to methods. However it is very
common and correct to pass objects to methods. One of the most common use of object
parameters involves constructors. Frequently you will want to construct a new object so that it is
initially the same as some existing object. To do this, you must define a constructor that takes an
object of its class as a parameter.

Passing objects to the parameter is known as call-by-reference. In this method, a reference to an


argument (and not the value of the argument) is passed to the parameter. Inside the method, this
reference is used to access the actual argument specified in the call. This means that changes
made to the parameter will affect the argument used to call.

Code
class TestTemp
{
int a,b;

TestTemp (int i, int j)


{
a = i;
b = j;
}

void met1( TestTemp o)


{
o.a *= 2;
o.b /= 2;
}
}

class Test34
{
public static void main (String arg[])
{
TestTemp z = new TestTemp(15,20);
System.out.println("Value before call " + z.a+ " " + z.b);
z.met1(z);
System.out.println("Value after first call " + z.a+ " " + z.b);
z.met1(z);
System.out.println("Value after second call " + z.a+ " " + z.b);
}
}

So we see here that when we pass an object as an argument to a method, then it is passed by
reference, which means what is passed is the memory location of the address and any changes
made in the method also gets reflected in the original also.

Access Modifiers

We have already studied about encapsulation, which links data with the code that manipulates it.
Encapsulation also provides another important feature and that is Access Control. It is through
encapsulation that you can control what parts of the code (that is variables and methods) can be
accessed by members of other classes which call upon code from your class.

There are 4 types of access control modifiers which can be used to control the visibility of the
methods and class variables.

a) public
b) private
c) default (when we do not write any modifier also called as friendly)
d) protected

We will explain over here the first two modifiers and the other two modifiers are associated with
the concept of packages and hence we will be covering the same in the other sub-module.

Public Access Modifier

When a member of a class is having a public access modifier then that member can be accessed
by any other code in your program. Remember our original program whether we had used public
access modifier in our main (). This is done so to enable the code outside the program – that is
the Java run-time system to call it.

Private Access Modifier

There are many situations when we want some data members or methods which access those
data members to be accessed by that class and not to be accessed by any other class either by
way of inheritance or by way of creation of objects. This can be done by prefixing the members of
the class with the keyword private.

The variables / methods prefixed with the private access modifier can be used only within that
particular class. Other classes, which extend this class, also cannot access these variables. This
keyword provides the maximum security.

For Example
class Test
{
public static void main (String arg[])
{
int i = 10
private int j = 10
}
}

class Test1 extends Test


{
public static void main (String arg [])
{
System.out.println (j); // it is not possible to access j since it is private.
}
}

With the help of the above code we can generalize that the private keyword class variable is
accessible only with the class in which it was created and not even in the sub-class of that
method.

Protected Access Modifier

If a variable or a method is prefixed with this modifier then it will be accessible to all classes in the
same package as well as in another class in another package provided the following two
conditions are met:-

a) The class in the other package extends the original class


b) An instance of sub class is created.

Default Access Modifier

If a class or a method or a variable do not have any access modifier, then it is called as default or
friendly access modifier. The visibility of this modifier is in all classes in the same package, either
by creating an instance or by virtue of inheritance.

Example:

Now we are going to create two packages and two classes in each of the packages and show the
usage of all the above modifiers.

package one;

public class Pack1


{
static private int x=10;
static int y;
static protected int z=30;
}

package one;

public class Pack2 extends Pack1


{
public static void main(String[] args)
{
System.out.println(y);
System.out.println(z);
}
}

package one;

public class Pack3


{
public static void main(String[] args)
{
Pack1 p=new Pack1();
//System.out.println(p.x);
System.out.println(p.y);
System.out.println(p.z);
}
}

package two;
import one.*;
public class Pack4 extends Pack1
{
public static void main(String[] args)
{
Pack4 a=new Pack4();
System.out.println(a.z);
Pack1 x = new Pack1()// will give an error
System.out.println(x.z); // will give an error
}
}

Note: For further explanation, you need to call Prof. Venkat Krishnan on 98214-22745

static Initializing block

As we already know a block is a code which is enclosed in a set of braces so that it is executed
together.

A initialization block is a block of code between braces that is executed before an object of the
class is created. This is normally used with the static keyword and this block is executed once
when the class is loaded.
The main purpose of the static initialization block is:
a) To initialize static data members of the class.
b) To load the library files of other languages so that the same can be used within the
java using native keyword. (this is not a part of the java certification).

All the other methods are initialized after the static initialization block. If you want your variables to
be started with a particular values, then you can put the same in the static initialization block and
can then use the variables in the other methods.
Incase there are multiple static initializing block, then they are executed in the order of their
appearance and the static class variables take the value as present in the last block.

Code

class Test35
{
static int a;
static {
a = 10;
}
public static void main(String[] args)
{
System.out.println(a);
}
static {
a = 50;
}
}

Output
50

This would be 50 because, initially in the first static block it got initialized to 10 and then it again
got initialized to 50 before entering the main block. Pls remember that all static blocks would be
executed before entering the main method.

Please remember that inside the static blocks do not again declare the variable and incase you
do that, then it would be taken as another variable and not the class variable. See the following
code for this purpose.

Code

class Test35
{
static int a;
static {
a = 10;
}
public static void main(String[] args)
{
System.out.println(a);
}
static {
int a = 50;
}
}

Output
10

The output is 10 because in the second static block we are again saying int a = 10 and this a and
the class variable a are two different entities.
How Constructors are called

When there is multi level hierarchy, in what order are constructors called. The constructors are
called in the order of derivation from superclass to subclass. It is important to note here that this
order is followed irrespective of whether super () is used or not. If super () is not used, then the
default or parameter less constructor is used. ( we will study about the super keyword in the next
sub-module).

Code

class Test36
{
public static void main(String[] args)
{
Three x = new Three();
}
}

class One
{
One()
{
System.out.println("Constructor in One class");
}
};

class Two extends One


{
Two()
{
System.out.println("Constructor in Two class");
}
};

class Three extends Two


{
Three()
{
System.out.println("Constructor in Three class");
}
};

Output

Constructor in One class


Constructor in Two class
Constructor in Three class

This would prove that the original constructor of the super most class is loaded first and then it
goes down the hierarchy. This is logical since the methods of the super class can be called with
the sub class instance variable and hence the super class should be loaded in the memory. By
calling the constructor of the super class that class is loaded in the memory.
Please note that the sub-most class would call its super class default constructor which in turn will
call the constructor of its super class and this process will go on till the super most classes’
constructor is loaded.

Now incase if there is no default constructor anywhere in the hierarchy then the loading of the
classes would stop and a compilation error would be generated. This is why we had insisted
earlier that when we define our own constructors, it is our duty to also provide for a default
constructor also.

Code

class Test36
{
public static void main(String[] args)
{
Three x = new Three();
}
}

class One
{
One()
{
System.out.println("Constructor in One class");
}
};

class Two extends One


{
Two(int a)
{
System.out.println("Constructor in Two class");
}
};

class Three extends Two


{
Three()
{
System.out.println("Constructor in Three class");
}
};

Output

Test36.java:28: cannot resolve symbol


symbol : constructor Two ()
location: class Two
{
^
1 error

What the compiler is trying to tell us by the above error is that it cannot find a default constructor
in class Two. We can make the code compile properly by provide for a default constructor.
is - a and has - a relationship

In programming language, one often creates a model of something (for example, an employee)
and then need a more specialized version of that original model. For example, you might want a
model for a manager, which only has more features but is still an employee. The Is-a relationship
in java is done with the help of extends keyword which creates a new class from an existing
class, by sub-classing it.

For Example:

class Employee
{
String name;
int salary;
Date hiredate;
}

class Manager extends Employee


{
String department;
}

In the above example, when we sub-class the class Manager, the Manager class will have all the
variable and methods that an Employee has. All these variables and methods are inherited from
the definition of the parent class. The class Manager then adds additional functionality to itself by
defining its own variables and methods.

The has-a relationship comes when a particular variable or method is inside a


particular class. For example in the above class Employee, we can safely say class
Employee has a name.

So we can safely finalize by saying that is-a relationship is for sub-class and super-class
relationship and is for variable inside the class.

super keyword

The super keyword refers to the superclass of the class in which the keyword is used. It only
refers to the immediate super class and not up the hierarchy. The super keyword has two general
forms:

a) The super keyword is also used to invoke the parent class’s constructor from the child
class’s constructor. For this one should use the super keyword in the first line of the child
class’s constructor.

IMP: If one uses the super with no argument in the child’s class’s constructor, then this will call
the default parent class constructor and if such a constructor is not available in the parent class,
then a compile error results.

For Example:

class Employee
{
String name;

pubic Employee (String s)


{
name = s;
}
}

class Manager extends Employee


{
String department;

public Manager (String s, string d)


{
super(); // this will cause a compile error, because there is no default
//constructor in Employee.

super(s) // this will work

department = d;
}
}

When a subclass calls super, it is calling the constructor of its immediate superclass and which
constructor to call would depend on the parameters being passed in the super keyword
argument.

IMP: We had seen earlier in the order in which constructors are called, the sub class
automatically calls the super class default constructor and this is possible because there is a
implicit super in the sub class which calls the super classes’ default constructor every time.

Code

class Test38 extends TestTem


{
int d;
public static void main(String[] args)
{
Test38 l = new Test38(10,20,30);
l.area();
l.volume();
}
Test38( int x, int y, int z)
{
super(x,y);
d = z;
}

void volume()
{
int e = a*b*d;
System.out.println("The volume is = "+e);
}
}
class TestTem
{
int a, b;

TestTem( int x, int y)


{
a = x;
b = y;
}

void area()
{
int c = a*b;
System.out.println("The area is = "+c);
}
};// end of class

Output

The area is = 200


The volume is = 6000

In the above code, we have two variables in one class and another variable in the sub-class. The
sub class constructor initializes all the 3 variables, by providing the values and the sub class
constructor call the super class constructor which will initialize the two variable in that class and
then calls the area and volume methods. We can call the area method also, because the Test38
class extends TestTem class.

The main purpose of the super keyword is to ensure that there is no duplication of efforts and
more over when we need to specifically call a super class constructor from inside the child
classes’ constructor

IMP: The super keyword incase is there in the constructor should be the first line in the sub
classes’ constructor or else the compiler would throw an error.

IMP: The super and this keyword cannot be accessed from inside a static method.

b) The second use of super is to refer to the member variables or methods of the superclass
that is hidden by the subclass.

This is also like this, except that it always refers to the superclass of the subclass in which it is
used. The syntax for the same is:

super.member. (Here the member can either be a variable or a method)

It is used more in those cases when the variable name of a subclass hides the members by the
same name of the superclass. For Example:

class First
{
int i;
}

class Second extends First


{
int i;

Second (int a, int b)// constructor


{
super.i = a;
i = b;
}

void method()
{
System.out.println( “ This is superclass i “ +super.i);
System.out.println( “ This is superclass i “ +i);
}

class Super
{
public static void main (String args [])
{

Second s = new Second(10,25);

s.method()
}
}

This example shows how to use the super keyword in the second context.

Method overriding

Overriding is one of the basic features of the Object Oriented Programming. If a method is
defined in a subclass that has the same name and return type exactly as that of the superclass
(or parent class), then the new method is said to override the old one. When an overridden
method is called from within a subclass, then it will always refer to the version of that method
defined by the subclass.

Note: Remember that methods with the same name, but with different argument lists that are in
the same class are simply overloaded and not overridden.

Overriding is fundamental to the OOPs principals because it allows for the subclasses through
the inheritance to add more specialized features which inheriting the generalized features of the
sub class.

For Example: The Source Code file name should be Tes.java

class One
{
void show()
{
int i = 10;
int j = 20;
System.out.println(" The value of i and j are " + i+""+j);
}
}

class Two extends One


{
void show()
{
int a = 50;
int b = 60;

System.out.println(" The value of a and b are " + a+""+b);


}
}

class Tes
{
public static void main(String arg[])
{
Two t = new Two();
t.show();
}
}

This will print out the show () of the object, which is created. If one has to use the show () of the
superclass then we can use the same as super.show (), which will use the show () of the super
class.

Rules about overriding methods

The following rules are mandatory and apply to overridden methods:

a) The return type of overriding method must be identical to the method it overrides. This
would mean that even if the arguments are the same, but return type is different, then it
would be neither overloading nor overriding and infact the compiler will think that one is
trying to over ride the method and give an error.

Code

class Test39 extends Temp


{
public static void main(String[] args)
{
Test39 x = new Test39();
x.met1();
}

int met1()
{
System.out.println("Inside Test39 class");
}
}

class Temp
{
void met1()
{
System.out.println("Inside Temp class");
}
};

Output

Test39.java:9: met1() in Test39 cannot override met1() in Temp; attempting to use incompatible
return type
found : int
required: void
int met1()
^
1 error

b) An Overriding method cannot be less accessible that the method it overrides. This would
mean that if a method has a particular access modifier then the overriding method
couldn’t have a modifier, which makes it less accessible.

Now the accessibility from the least accessible to the most accessible is in the following order:

private - default - protected - public (we will cover protected and default later on, but just
remember that this is the order).

Code

class Test40 extends Temp


{
public static void main(String[] args)
{
Test40 x = new Test40();
x.met1();
}

void met1()
{
System.out.println("Inside Test40 class");
}
}

class Temp
{
public void met1()
{
System.out.println("Inside Temp class");
}
};

Output

Test40.java:9: met1() in Test40 cannot override met1() in Temp; attempting to assign weaker
access privileges; was public
void met1()
^
1 error
The compiler is trying to tell us the overriding method (met1() in Test40) cannot be less
accessible that the method which it is trying to override (met1() in Temp). So to make the code
compile we need to have the access modifier of the overriding method in Test40 to have atleast
the same level of accessibility or more. This can be done by making the method met1() as public
in Test40.

c) An overriding method cannot throw higher class types of exception that the method it
overrides. It need not throw any exception or can throw subclasses of the exceptions
throws by the super class but not anything higher that already thrown by the superclass.

Code

The hierarchy in the following code is Throwable class is the superclass and Exception class is
the sub class.

class Test41 extends Temp


{
public static void main(String[] args)
{
Test41 x = new Test41();
x.met1();
}

public void met1() throws Throwable


{
System.out.println("Inside Test41 class");
}
}

class Temp
{
public void met1() throws Exception
{
System.out.println("Inside Temp class");
}
};

Output

Test41.java:9: met1() in Test41 cannot override met1() in Temp; overridden method does not
throw java.lang.Throwable
public void met1() throws Throwable
^
1 error

The compiler is trying to tell us that the overridden method is not throwing Throwable and hence
the overriding method cannot throw that kind of exception. This is important because Throwable
is the superclass of Exception.

We can check the same code in the following two ways:

a) Let the overriding method (met1() in Test40 class) not to throw any exception. The
code will compile finely because the rule is that the overriding method cannot throw
any superclass of the exceptions that what is already thrown by the superclass.
b) Let the overriding method (met1() in Test40 class) throw RuntimeException which the
subclass of Exception. Again the code would compile finely.

Why Overriding?

Overriding of methods allows java to support polymorphism, which allows a general class to
specify methods that will be common to all of its subclasses, while allowing each of the sub
classes to define the specific implementation of some or all of those methods.

Virtual Method Invocation / Dynamic Binding / Runtime Polymorphism / Late Binding

To understand the topic of Virtual Method Invocation or also called as Runtime Polymorphism, we
should understand when an object of a superclass is allowed to be assigned to the subclass and
vice versa.

It is possible to automatically allow a sub class instance to be assigned to a super class instance,
because the sub class would know all the methods that are there in the super class (because of
inheritance).

Code

class Test42
{
public static void main(String[] args)
{
T1 x = new T1();
T y = new T();
y = x; // subclass variable casted to super class automatically

y.met1();
// y.met2();

}
}

class T
{
void met1()
{
System.out.println("Inside met1 in class T");
}
void met3()
{
System.out.println("Inside met3 in class T");
}
};

class T1 extends T
{
void met2()
{
System.out.println("Inside met2 in class T1");
}
void met1()
{
System.out.println("Inside met1 in class T1");
}
};

Output

Inside met1 in class T1

The important points to be noted here are:

a) Here in the above code we see that the compiler automatically allows the sub class
instance to be assigned to the superclass instance. That means when we go up the
hierarchy there is no need for casting, but when we come down the hierarchy there is
a explicit need for casting to avoid compile time error.

b) An important point to note here is that after assignment, when we call a method
which is overridden in the sub class through the assigned instance, it would print the
overridden method as above. (e.g. y.met1() in the above example)

c) Comment the instance assignment ( y = x) and then when we call y.met1() it would
print

Inside met1 in class T, this is the method of the super class itself

d) When we do assignment ( y = x) and then try to call the specialized method in the
subclass (met2()), the compiler will complain, because when we do assignment (y =
x), we are explicitly agreeing that through the assigned instance we can all the
methods of the super class only and only the overridden methods in the subclass.
(Uncomment y.met2() in the above code and see the error).

Code

class Test43
{
public static void main(String[] args)
{
T1 x = new T1();
T y = new T();
x = y;
}
}

class T
{
void met1()
{
System.out.println("Inside met1 in class T");
}
};

class T1 extends T
{
void met2()
{
System.out.println("Inside met2 in class T1");
}

void met1()
{
System.out.println("Inside met1 in class T1");
}
};

Output

Test43.java:8: incompatible types


found : T
required: T1
x = y;
^
1 error

Now let us try by casting y to the subclass by typing

x = (T1)y;

There would not be any compile time error, but when we execute the code, the output would be
as under:-

java.lang.ClassCastException: T
at Test43.main(Test43.java:8)
Exception in thread "main"

This exception will be thrown to indicate that the code has attempted to cast an object to a
subclass of which it is not an instance. We are attempting to cast y in to T1 where it is actually an
instance of T.

Now let us try casting it to the original class to which it belongs by changing the assignment as
x = (T)y;.

Even then the output would be

Test43.java:8: incompatible types


found : T
required: T1
x = (T)y;
^
1 error

The Virtual Method invocation is a mechanism by which a call to an overridden function is


resolved at run time rather than compile time. How does this happen.

a) A superclass variable can access a subclass object. Java uses this fact to resolve calls to
overridden methods at runtime.

b) When a 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 when the call occurs. Thus this determination is done at runtime.
c) In other words, it is the type of the object being referred to and not the type of the
reference variable.

Code

class Test44 extends Temp


{
int a = 20;

void met1()
{
System.out.println("Inside met1 in class Test44");
}

public static void main(String[] args)


{
Temp x = new Test44();
x.met1();
System.out.println(x.a);
}
}

class Temp
{
int a = 10;

void met1()
{
System.out.println("Inside met1 in class Temp");
}
};

Output

Inside met1 in class Test44


10

Now when we are creating a instance till now we have been saying Test x = new Test() only, but
here were are saying Temp x = new Test44(), which means that through the instance of the super
class we are calling the constructor of the sub class.

IMP: We will have to understand that there is a variable a in the super class as well as in the sub
class. The variable a in the subclass will be hiding the variable a of the super class, as variables
in two classes related through inheritance can only be hidden, whereas the methods will be
overridden.

Now when we create the instance by saying Temp x = new Test44(), we are creating an instance
of the class Temp only and not of Test44 at all. Hence when we say x.a, it prints the value as 10
only. Now when we call x.met1(), it will check whether the method met1() is overridden in the
subclass and incase it is, it will call the overridden method of the subclass only and incase it is not
overridden, it will call the method of the super class since it is an instance of the super class only.

Please note that through the instance x we cannot access any method of the subclass at all. See
the revised code for this purpose.

Code
class Test45 extends Temp
{
int a = 20;

void met1()
{
System.out.println("Inside met1 in class Test44");
}

void met2();
{
System.out.println("Inside met2 in class Test44");
}

public static void main(String[] args)


{
Temp x = new Test44();
x.met1();
System.out.println(x.a);
x.met2();
// x.met3();
// will throw a compilation error and hence commented. Uncomment to check
}
}

class Temp
{
int a = 10;

void met1()
{
System.out.println("Inside met1 in class Temp");
}

void met3();
{
System.out.println("Inside met3 in class Temp");
}

};

Output

Inside met1 in class Test44


10
Inside met2 in class Temp

Here when we say x.met2(), it checks whether the method is overridden in the subclass and
incase not it just prints the super class version.

Abstract class
There are many situations when you want to define a super class that declares the structure of a
given abstraction without providing a complete implementation of every method.

That is one creates a superclass that only defines a completely general form that will be shares
by all of its subclasses leaving it to each of the subclass to fill in the details.

For Example, we have a class called Figure which has a method called area () which does
nothing, but lets the subclasses like Circle, Triangle, Square to override it and give specific
implementation to the same. In this case you should call the area () as abstract.

The other example can be a Drawing class. The class contains methods for variety of drawing
facilities, but these must be implemented in a platform independent way. You cannot access the
video hardware of a machine and still be platform independent. The intention is that the drawing
class defines which method should exist, but special platform independent subclasses actually
implement that behavior.

The syntax of an abstract method is

abstract method ();

It is important to note here that the abstract method does not have a body.

The points to be remember here are:

a) Any class, which has one or more abstract method, should be declared as abstract. To
declare a class as abstract, simply use the abstract keyword in front of the class.

b) There can be no objects of the abstract class. That is an abstract class cannot be directly
instantiated with the new keyword. This is so because the class is not complete.

c) Any subclass of an abstract class must override all the abstract methods, or the subclass
must also be declared as abstract. That means any subclass must override all of the
abstract methods.

d) An abstract class can have a non-abstract method also.

e) An abstract class can have member variables also, which can be used by the subclass
after it overrides the abstract methods.

f) An abstract class need not have any abstract methods, but incase a class has an
abstract method, it should mandatorily be declared as abstract class.

Code

class Test46 extends Temp


{
public static void main(String[] args)
{
Test46 x = new Test46();
x.met1();
x.met2();
x.met3();
}

void met1()
{
System.out.println("Overridden met1 in Test46");
}

void met3()
{
System.out.println("Overridden met3 in Test46");
}

abstract class Temp


{
abstract void met1();

void met2()
{
System.out.println("Hello World!");
}

abstract void met3();


};

Output

Overridden met1 in Test46


Hello World!
Overridden met3 in Test46

Over here, the class Temp should be declared as abstract class since it has abstract methods. (
try to remove the abstract keyword from the class and then compile the same).

Any class (Test46) extending the abstract class should override all the abstract methods or else
that class should be declared as abstract since it would have a abstract method by way of
inheritance and rule 1 is any class having an abstract method should be declared abstract. (Try
commenting the whole method met3() from Test46 and then compile).

Try creating an instance of Temp class and compile

An abstract class can have non abstract methods also, like met2() in Temp class.

An abstract class need not have any abstract methods. We would need a class to be declared as
abstract and still not have any abstract methods only in the scenario when we do not want any
one to create an instance of our class.

Code

class Test47 extends Temp


{
public static void main(String[] args)
{
Test47 x = new Test47();
x.met1();
}
}

abstract class Temp


{
void met1()
{
System.out.println("Hello World!");
}
};

Output

Hello World!

See in the above class although we are extending the abstract class, since there is no abstract
method, we need not override any method and can directly call any other non-abstract methods.

final Keyword

The final keyword can be used for a class, variable or a method.

a) When a class is pre-fixed with a final keyword, then that class cannot be extended
further. For example, the java.lang.String is a final class. This is done for security
reasons, because it ensures that if a method has a reference to a string, it is definitely a
string of class String and not a string of a class that is a modified subclass of String that
might have been maliciously changed.

b) When a variable is pre-fixed with the final keyword, then it cannot take any other variable
than the variable with which it was initialized. That would mean that it will act like a
constant.

c) When a method is pre-fixed with the final keyword, then it cannot be overridden to
provide any additional functionality. This is also done for security reasons. You should
make a method final if the method has a implementation that should not be changed and
is critical to the consistent state of the object. The methods declared final are sometimes
used for optimization. The compiler can generate code that causes direct call to the
method rather than the usual virtual method invocation that involves a runtime lookup.

It is a common coding convention to choose all uppercase identifier for final variables. Variables
declared as final do not occupy memory on a per instance basis. Thus the final variable is
essentially a constant.

Thus final keyword is often used to prevent overriding and also to prevent inheritance.

Example of final Keyword for a class

Code

class Test48 extends String


{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

Output
Test48.java:1: cannot inherit from final java.lang.String
class Test48 extends String
^
1 error

The above output confirms that we cannot extend classes which are declared as final and all the
Wrapper classes and String classes are declared as final in the java API.

Examples of final keyword for variables

final variables should be initialized when they are declared, which is different from normal class
variables which take default value even when they are not initialized.

Code

class Test50
{
final int a;
public static void main(String[] args)
{
Test50 x = new Test50();
x.met1();
}

void met1()
{
System.out.println(a);
}
}

Output

Test50.java:1: variable a might not have been initialized


class Test50
^
1 error

This proves the point that final variables should be initialized when they are declared.

Code

The final variables can be initialized in the constructor of a class also when an instance of the
class is created and different instances can take different values of the final variables

class Test51
{
final int a;

Test51(int x)
{
a = x;
}

public static void main(String[] args)


{
Test51 l = new Test51(10);
Test51 k = new Test51(20);

System.out.println(l.a);
System.out.println(k.a);

// l.a = 40;
}
}

Output

10
20

So here we see that a final variable is initialized in the constructor and can take a single value for
different instance. Try removing the comment and then the compiler complains that we cannot
change the value of a final variable.

Example of final keyword for methods

Code

class Test49 extends Temp1


{
public static void main(String[] args)
{
System.out.println("Hello World!");
}

void met1()
{
System.out.println("Overridden met1");
}
}

class Temp1
{
final void met1()
{
System.out.println("final met1");
}
};

Output

Test49.java:8: met1() in Test49 cannot override met1() in Temp1; overridden method is final
void met1()
^
1 error

Here the compiler is complaining that the overridden method is final and final methods cannot be
overridden

Inner classes
Until now we have seen classes defined so far separate from each other. In previous releases,
Java supported only top-level classes, which must be members of packages. In the 1.1 release,
the Java 1.1 programmer can now define inner classes as members of other classes, locally
within a block of statements, or (anonymously) within an expression.

Here are some of the properties that make inner classes useful:

1. The inner class's name is not usable outside its scope, except perhaps in a qualified
name. This helps in structuring the classes within a package.

2. The code of an inner class can use simple names from enclosing scopes, including both
class and instance members of enclosing classes, and local variables of enclosing
blocks.

It is possible to define a class within another class and such classes are known as nested
classes. The scope of the nested class is within the boundary of the outer class.

The nested class can access all the variables, including private (since the inner class is within the
boundary of the outer class), but the outer class does not have access to the members of the
nested class.

There are 3 types of inner classes and they are:-

a) Normal Inner Class

b) static Inner Class

c) Inner class inside a method.

Normal Inner Class

In this case we simply have an inner class declared before closing the final brace of the outer
class. The inner class is declared outside any methods but within the outer class

Code

class Test52
{
int a = 10;
private int b = 20;
public static void main(String[] args)
{
Test52 x = new Test52();
Test52.Inner y = x.new Inner();
y.met1();
}

class Inner
{
void met1()
{
System.out.println(a + " "+b);
}
};
}

Output

10 20

Over here we should remember that to create a instance of the inner class, we mandatorily
require an instance of the outer class and then create a instance of the inner class referenced
with the outclass class

Once the instance of the outer class is created, then we simply call the inner class method.

Static Inner Class

Inner classes cannot have static declarations of any sort, neither static class variables nor static
methods.

Code

class Test52
{
int a = 10;
private int b = 20;
public static void main(String[] args)
{
Test52 x = new Test52();
Test52.Inner y = x.new Inner();
y.met1();
}

class Inner
{
static int c = 30;
void met1()
{
System.out.println(a + " "+b+" "+c);
}
};
}

Output

Test52.java:14: inner classes cannot have static declarations


static int c = 30;
^
1 error

We just changed the code to include a static class variable of the inner class and the compiler
complains.

To ensure that the inner class shall have static declarations, the whole inner class shall be
declared as a static inner class. Remember only inner classes can be static and not outer
classes.

A major limitation of the static inner classes is that it cannot refer to non-static variables of the
outer class
Code

class Test52
{
int a = 10;
private int b = 20;
public static void main(String[] args)
{
Test52 x = new Test52();
Test52.Inner y = x.new Inner();
y.met1();
}

static class Inner


{
static int c = 30;
void met1()
{
System.out.println(a + " "+b+" "+c);
}
};
}

Output

Test52.java:17: non-static variable a cannot be referenced from a static context


System.out.println(a + " "+b+" "+c);
^
Test52.java:17: non-static variable b cannot be referenced from a static context
System.out.println(a + " "+b+" "+c);
^
2 errors

Hence to compile the above code, either we should remove the variables a and b from the inner
class or should declared int a and int b as static in Test52.

Another way to create an instance of the inner class is in the following way

Test52.Inner y = new Test52().new Inner();

IMP: The class file of Inner will be Test52$Inner.class. Since the system internally uses the $
word, hence we had requested that the $ word to used in a limited way in an identifier.

Inner Class inside a method

We can also have a inner class inside a method also, but the only condition is that incase the
inner class accesses any variable that is inside the method, then that method should be declared
as final, or otherwise the compiler will complain.

Code

class Test53
{
public static void main(String[] args)
{
Test x = new Test();
x.met1();
}
}

class Test
{
int a = 10;

void met1()
{
int b = 20;

class Inner
{
void met2()
{
System.out.println("Inside met2"+a+" "+b);
}
}; // end of inner class

Inner x = new Inner();


x.met2();
}// end of met1()
};// end of main class

Output

Test53.java:22: local variable b is accessed from within inner class; needs to be declared final
System.out.println("Inside met2"+a+" "+b);
^
1 error

To remove the error , we should make the variable int b as final, since it is accessed inside the
Inner class.

In the above code we see that we have a inner class inside a method and to call a method of the
inner class, we should create a instance of the class and call the method, before getting out of the
method itself. Also remember in java forward instantiation is not possible. That is we cannot
create an instance before declaring the class itself.

Concept of Packages

A package is a collection of class and is often used to keep the class name compartmentalized.
The package has both a naming and visibility control mechanism.

One can define classes inside a package that is not accessible to others outside the package.
Essentially a package is a named collection of classes.

To use a package, just use package command as the first statement in the source file. Any
classes declared within that file will belong to the specified package.
If you omit the package statement, the class names are put into the default package with no
name.

The syntax for the package statement is:

package abc // abc is the name of the package

IMP: If you want the classes in a package to be accessible outside the package, you must
declare the class using the public keyword. The class definitions that aren’t preceded by the
public keyword are only accessible from methods in classes that belong to the same package.

More than one file can include the same package statement. The package statement simply
specifies to which package the classes defined in a file belong.

The package mechanism is for two main purposes:

a) Reduce the problems with name conflicts.

b) Control the visibility of classes, interfaces and the methods and data defined within them.

One can also have a hierarchy of packages. To do so, simply separate each package name from
the one above it by the use of the period. For Example:

package abc.xyz.nmq

Java uses file systems directories to store packages. For example, a class file for the above class
you declare will be a part of the abc package and in a directory called as abc. Remember java is
case-sensitive.

Accessing a package

How do you access a package when you are compiling a program that uses the package
depends on where you have put it. There are a couple of options here.

The first but not the best is to leave the .class file for the classes in the package in the directory
with the package name. Let’s look at that before we go into to the second option.

With the .class file in the original package directly, either the path to your package must appear in
the string set for the CLASSPATH environment variable or you must use the classpath option on
the command line when you invoke the compiler or the interpreter.

This overrides the CLASSPATH environment variable if it happens to be set. Note that it is up to
you to make sure that the classes in your package are in the right directory. Java will not prevent
you from saving a file in a directory that is quite different from that appearing the package
statement.

Of the two options here, using the –classpath option on the command line is preferable because it
sets the class paths transiently each time and can’t interfere with anything you do subsequently.

This has the advantage that it only applies for the current compilation or execution so you can
easily set it to suit each run. The command to compile Test.java defining the class path would be:

javac –classpath ,; c:\MySource\Test.java


If you do not set the class path in one of the above two ways or do it incorrectly, then java will not
be able to find the classes in any new package you might create.

Also we can directly tell the compiler to create a directory with whatever is the package name with
the -d option when compiling. This will make the compiler create the directory with the package
name and put the .class file inside the created directory.

This option is better than manually creating the directory and putting the .class inside the
directory as the chances of manual error is there.

The Important java packages are:

a) java.applet - Classes for implementing Graphics.

b) java.awt - Classes for text, windows and GUIs.

c) java.io - Classes for all kinds of input and output

d) java.net - Classes for networking.

e) java.math - Classes for calculations.

Protected and Default Access Modifiers

We had learnt about private and public access modifier and now we will see the other two access
modifiers now. Package adds a complete new dimension to access control. Package is a
container for classes and other subordinate packages.

Default Modifier

A Default Access Modifier means, when we do not specify anything to the class, method or
variable it is said to have default access modifier.

The default access modifier means it is available to any class inside the package, irrespective of
whether it is sub class or not and is not available to any sub class outside the package also.

The access modifier from the most restrictive to the least restrictive is

private --> default --> protected --> public

Importing packages

All of java classes are stored in packages and one would not find a single class just hanging in
open air. Since classes within packages must be fully qualified with their package name or
names, it would be tedious to type in the long dot-separated package name for every class you
want to us.

For this java has a special statement called import statements, which will certain class or the
entire packages into visibility? The import statement tells the compiler where to find the particular
classes.3
Once imported, a class can be referred to directly, using only its name. The import statement is a
convenience to the programmer and is not technically needed to write a complete java program.

In a normal java source code, the import statement occurs immediately after the package
statement. The general form of a import statement is:

import package1.package2.*;

This would mean that all the classes in package1.package2 would be imported. But remember it
would also take for the basic source java file to compile, as all the classes will have to be
imported. If one know a file which is to be specifically imported then it should be written as:

import package1.package2.Test;

All the standard java classes are included in a basic package called java. The basic language
functions are stored in a package inside the java package called java.lang.

Normally one will have to import every package or class that you want to use, but since java is
useless without much of the functionalities in java.lang, the compiler for all programs implicitly
imports it.

protected keyword

A Protected Access Modifier is actually a misnomer and is often confusing. By general


understanding of the term is seems to be more restrictive that private, but is not actually so.

When we declare a member of a class as protected, and then it is available to all members inside
the package and also to classes, which is a subclass in a different package.

Remember that the protected modifier can be for variables and method only and we cannot
declare the class as protected.

Now as already learnt there are the two ways in which any variable in one class be accessed in
another class

a) by creating an instance and calling the variable with the instance

b) by way of inheritance. (the sub class automatically gets all the variables other than
the private one’s)

Recap of Access Modifiers

a) private keyword variables and methods are accessible only in the class in which they
are declared and not even in the subclasses.

b) default keyword is accessible in the package in which they are declared either by way
of inheritance (in subclass) or (in any other class) by way of creating an instance of
the class in which the variable is there.

c) protected modifier is accessible in the package in which they are declared like the
default modifier (by way of inheritance or by creating instance of the class) and also
in another package in a class which is a subclass of the class which contains the
protected keyword.
Remember protected keywords are accessible in another packages only in the
subclasses, by creating an instance of the subclass and not by creating an instance
of the class which contains the protected keyword.

Also protected keywords cannot be accessible in other classes in another package


by creating an instance of the class in which the protected keyword is there.

Also the class which contains the protected keyword should be declared as public.

d) The public keyword variables / methods are accessible everywhere by creating of the
class which contains the public keyword items

Now let us have two classes which we will store in two different packages and also try out the
protected keyword

Code

package one;

public class Test54


{
protected int a = 10;
}

Now to compile this code we should use the -d option so that the compiler will automatically
create a directory by the name of the package (i.e. one) and put Test54.class inside that.

Assuming Test54.java is there in c:\java directory, we will go to that directory and type the
following command

javac -d c:\java Test54.java

Over here c:\java specifies that the new directory called as one will be created below c:\java
directory.

Now to check whether the compiler has done the job we can go the c:\java\one directory and type
dir to check the contents of the directory.

Now we will create another source code file in another package to access this class variable a.

Code

package two;

import one.*;

class Test55 extends Test54


{
public static void main(String arg[])
{
Test55 x = new Test55();
System.out.println(x.a);
}
}

We will compile the above code also with the -d option as explained earlier.
Now we need to run the interpreter and we will have to go a directory one above which contains
the .class file that is c:\java and type java two.Test55.

Output

10

This will print out the value of the class variable in Test54 since Test55 extends Test54.

interfaces

We have discussed about the concept of inheritance and have understood that java has simple
inheritance only. There are many cases when a particular method will be used by a lot of classes
and this can be done by defining them in an interface and all the classes which needs that
method will be implementing the interface to provide body to the abstract method.

An interface is also like a normal class, but it has only public static and final variable (constants)
and public and abstract methods.

That would mean that it is similar to abstract classes, but since the interface is by abstract and all
the methods are abstract (remember abstract classes can also have non-abstract methods) there
is no need to write abstract before the interface.

Similarly, all the data members declared in an interface are by default constants, there is no need
to explicitly insert a final, static or final modifier before them.

But we need to prefix the class name with interface instead of class. For example, the general
syntax of an interface is:

interface Test
{
met1();
}

implements clause

A class declares all of the interfaces it is implementing using the implements clause. The
implements clause consists of the keyword implements followed by the list of interfaces
separated by commas and it must be put after the extends keyword (if any).

This would mean that a class can implement more than one interface. An interface gives the
illusion of bending the java technology single inheritance rule, while a class can extend only a
single class, it can implement as many interfaces as needed, but it is the duty of that class to
mandatorily override all the methods otherwise it should be declared as a abstract class. (since
the class has a abstract method which is not overridden).

Code

interface Temp
{
int a;
void met1();
}
Output

Temp.java:3: = expected
int a;
^
1 error

This is because final variable need to be initialized when they are declared. Not to properly run
the code have the int a initialized to a value of 10.

Code

class Test56 implements Temp


{
public static void main(String[] args)
{
Test56 x = new Test56();
x.met1();
}
public void met1()
{
a = 20;
System.out.println("Inside met1");
}
}

Output

Test56.java:10: cannot assign a value to final variable a


a = 20;
^
1 error

The above error proves that all the values in the interfaces are final. Now to properly run the
code, remove the line a = 10 and insert a System.out.println (Temp.a) line.

The output would be

Inside met1
10

This would prove that the variable in the method are static also.

Now incase we do not override the method in the interface let us see what happens (for this
comment the overriding part) and the output would be

Test56.java:1: Test56 should be declared abstract; it does not define met1 () in Test56
class Test56 implements Temp
^
1 error

Interfaces are useful for:

a) Declaring methods that one or more classes are expected to implement.


b) Determining an object’s programming interface without revealing the actual body of the
class.

c) Capturing the similarities between unrelated classes without forcing a class relationship.
Variables in Interfaces

One can also use interfaces to import shared constants into multiple classes by simply declaring
an interface that contains variables, which are initialized to the desired values. When you then
implement the interface all those variable names will be in scope as constants.

Interfaces can be extended

One interface can inherit another with the help of the usual extends keyword. When a class
implements an interface that inherits another interface, it must provide implementation for all
methods defined within the interface inheritance chain.

Partial Implementation

It is very much possible that a class will implement an interface, but does not want to override all
the abstract method, but will override some abstract methods and leave the further
implementation to its own subclasses. In this case we should declare the class as abstract,
because there is some abstract method in the class.

Code

interface Two extends One


{
void met2();
}

interface One
{
void met1();
}

abstract class PartialImplementation implements Two


{
public void met2()
{
System.out.println("This is inside met2()");
}
}

class FullImplementation extends PartialImplementation


{
public static void main(String[] args)
{
System.out.println("Hello World!");
}

public void met1()


{
System.out.println("This is inside met1");
}
}

Output

class FullImplementation extends PartialImplementation


{
public static void main(String[] args)
{
FullImplementation x = new FullImplementation();
x.met1();
x.met2();
}

public void met1()


{
System.out.println("This is inside met1");
}
}

In the above classes, the PartialImplementation class should be declared as abstract, since it is
implementing Interface Two, but does not override all the methods of the interface, that is
specifically it does not override met1(). Although met1() is not specifically in Interface Two, it is
there in Interface One which Interface Two is extending.

Garbage Collection

In the earlier programming languages, it was the duty of the programmer to allocate the memory
and also to de-allocate the memory. One of the most frequent reasons for the programs crashes
was the lack of the memory, since memory was not released by the objects once their work was
finished.

In java we do not have that problem at all, since we have a Garbage Collector which always runs
in the background when the interpreter is called and automatically re-claims the memory. The
only problem is that we cannot force the garage collector nor can we predict at a particular point
of time, a object will be definitely garbage collected, since Garbage Collector is a low priority
thread.

The points to be considered in this sub-module can be summarized as under:-

1. A System Level Thread, which is automatically created by the JVM.

2. Low Priority Thread

3. One cannot predict when the garbage collection of any particular object will be done.

4. One cannot force garbage collection even by using the System.gc() method which will
only request the Garbage Collector to run.

5. By using the finalize() method, there is no guarantee that the object will be immediately
collected.
6. Also we can be sure that when a object is garbage collected, it will definitely call the
finalize () method before the object is garbage collected.

finalize method

We have already learnt about the concept of Garbage Collection, which is done by a system level
thread, which will collect an object, which is of no use. But sometimes an object will need to
perform some action when it is destroyed. In many cases a particular java object may be holding
some non-java resource such as a window character font etc and we must make it sure that
these resources are freed before an object is destroyed. To handle such cases, java has a
mechanism called finalization. By using finalization, one can define specific actions that will occur,
before the garbage collector reclaims the object.

To add a finalize to a class, one needs to just define the finalize method. The Java environment
calls that method whenever it is about recycle an object of that class. Inside the finalize () method
you specify those actions which must be performed before the object is destroyed. The general
form of a finalize () is:

protected void finalize()


{
finalization code;
}

Here the keyword protected is a specifier that prevents access to finalize () by code defined
outside its class. It is important to note here that the method is not called when an object goes
out-of-scope.

The finalize () method is a member of the Object class. Since all classes inherit from the Object
class, your classes also contain the default finalize () method. This gives you an opportunity to
execute your special cleanup code on each object before the memory is reclaimed.

native Keyword

The native keyword is used to declare native code method. Once declared, these methods can
be called from inside your java programs just as you do any other java method.

After you declare a native method, you must write the native method and follow a rather complex
series of steps to link it with your code. The mechanism used to integrate C code with java
programs is called JNI. This methodology was created in 1.1 and then expanded and enhanced
in 1.2

The precise steps that you need to follow will vary between different java environments and
versions. This also depends on the language that you are using to implement the native method.

Native methods seem to offer great promise, because they enable you to gain access to your
exiting base of library routines, and they offer the possibility of faster runtime execution.

The problems with native methods are:-


a) Potential security risk: Because a native method executes actual machine
code, it can gain access to any part of the hose system. That is native code
is not confined to the JVM and this could allow a virus infection. Applets
cannot use native methods.

b) Loss of portability: Because the native code is contained in a DLL, it must


be present on the machine that is executing the java program. Further
because each native method is CPU and OS dependent, each DLL is
inherently non portable. Thus a java application that uses native methods will
be able to run only on a machine for which a compatible DLL has been
installed.

Thus the use of native methods should be restricted, because they render you java programs non
portable and pose significant security risks.

Methods returning Objects

As we know the return type of java method should be some primitive data type or should be
specifically declared as void. However methods can also returns object, but care should be taken
that there is mandatorily a return statement at the end of the method and the object specified and
object returns should be the same.

The following example returns a String object, which we capture and print in our program.

class ObjectReturn
{
public static void main(String[] args)
{
ObjectReturn x = new ObjectReturn();
String s = x.met1();
System.out.println(s);
}

String met1()
{
return "Hello";
}
}

The output would be Hello.

String class

A String is a series of characters treated as a single unit. A string may include letters, digits and
other various special characters like +,-,@, # etc.
A white space has no meaning in a java source code, but if included in a String, it is also taken as
a character. String is the only object in Java which can be created with out the new keyword and
incase it is done so, it is treated as a primitive data type, however when we create String with the
new keyword, then it becomes a proper object.

Hence the different ways of creating a String are:

String s = “Hello”, in which case it is taken as a primitive and stored in the stack,

String s1 = new String (“Hello”);, in which case it is taken as a Object properly initialized with the
new keyword and stored in the Heap.

The 4 Important Constructors of the String class are:-

a) String (String s) – creates an object of the character item passed in the parameters.

b) String () – creates an instance of String with no characters in it.

c) String (char c[]) – creates an object of the char array passed into it

d) String (char c[], int startindex, int numberofchars) – This creates an object of the c
array starting from the position in the 2nd parameter till the number of characters as
specified in the 3rd parameter.

Code

class String1
{
public static void main(String[] args)
{
String s = new String();

String s1 = new String("Hello friends");

char c [] = {'h','e','l','l','o'};
String s2 = new String (c);

String s3 = new String(c,0,4);

System.out.println(s);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}

Output

(This is actually a space)


Hello friends
hello
hell

The String objects are immutable - their character contents cannot be changed after they
are created. A String reference cannot be used to modify a String object to delete or modify a
String object from the memory as in other programming languages such as C or C++.
The Important Methods are:

1. int length () – This returns the number of characters that it contains.

2. char charAt (int index) – To extract a single character at the specified index.

3. boolean equals () – actual contents of the String, which included the case sensitiveness
also.

Code

class String2
{
public static void main(String[] args)
{
String s = new String("Hello");
String s1 = new String("Hello");

int a = s.length();

char c = s.charAt(1);

boolean b = s.equals(s1);

System.out.println("The number of characters in s is = "+a);


System.out.println("The character at position 1 in s is = "+c);
System.out.println("The contents of S and S1 are equal = "+b);

}
}

Output

The number of characters in s is = 5


The character at position 1 in s is = e
The contents of S and S1 are equal = true

4. boolean equalsIgnoreCase () – checks without the case sensitiveness.

5. boolean startsWith (String s) – Determines if the String starts with the String specified in
the parameter.

6. overloaded version. boolean startsWith (String s, int index) – This allows you to specify a
starting point.

Code

class String3
{
public static void main(String[] args)
{
String s = new String("hello");
String s1 = new String("HELLO");

boolean a = s.equals(s1);
boolean b = s.equalsIgnoreCase(s1);

boolean c = s1.startsWith("H");
boolean d = s.startsWith("ll",2);

System.out.println("Whether s and s1 contents are similar = "+a);


System.out.println("Whether s and s1 contents are similar ignoring case = "+b);
System.out.println("Whether s starts with h = "+c);
System.out.println("Whether s starts with ll from position 2 = "+d);

}
}

Output

Whether s and s1 contents are similar = false


Whether s and s1 contents are similar ignoring case = true
Whether s starts with h = true
Whether s starts with ll from position 2 = true

7. int indexOf (int c or String s) – checks for the first occurrence of the character or the
string.

8. int lastIndexOf(int c or String s) –

9. overloaded version – int indexOf (int c, int position) – This enables u to start searching
from the specified position.

10. String substring(int startindex) – copies all the characters till the end from the start
position in this string to another string.

11. String substring (int start, int end (exclusive)) – copies the characters form the start till the
end into another string.

Code

class String5
{
public static void main(String[] args)
{
String s = new String ("Hello lilly");

int a = s.indexOf('l');
System.out.println("The first occurence of l in String s is = "+a);

int b = s.lastIndexOf('l');
System.out.println("The last occurence of l in String s is = "+b);

int c = s.indexOf('l',4);
System.out.println("The first occurence of l in String s from position 4 is = "+c);

String s1 = s.substring(5);
System.out.println("The substring of String s from position 5 is = "+s1);

String s2 = s.substring(5,9);
System.out.println("The substring of String s from position 5 till 9 is = "+s2);
}
}

Output

The first occurence of l in String s is = 2


The last occurence of l in String s is = 9
The first occurence of l in String s from position 4 is = 6
The substring of String s from position 5 is = lilly
The substring of String s from position 5 till 9 is = lil

12. String replace (char original, char replacement) – replaces the original character with the
replacement character in the whole string and returns a new String.

13. String trim () – removes the white space in the beginning and in the end.

14. String toUpperCase () – converts all the characters to Upper Case

15. String toLowerCase() –

16. static String valueOf (any datatype) – returns the String object of any primitive data type.

Code

class String6
{
public static void main(String[] args)
{
String s = new String ("Hello");
String s1 = s.replace('l','m');

System.out.println("The new String s1 is = "+s1);

String s2 = s1.toUpperCase();
System.out.println("The new String s2 is = "+s2);

s2 = s1.toLowerCase();
System.out.println("The String s2 is now = "+s2);

String s3 = String.valueOf(10);
System.out.println("The new String s3 is = "+s3);
}
}

Output

The new String s1 is = Hemmo


The new String s2 is = HEMMO
The String s2 is now = hemmo
The new String s3 is = 10

17. char [] toCharArray() – To convert all the characters in a String to a character array.
18. boolean regionMatches (int startindex, String 2, int String2start index, int no of
characters) – This compares a specific region in a string with another specific region in
another String

Code

class String7
{
public static void main(String[] args)
{
String s = new String("Gurukul");
char c[] = s.toCharArray();

for (int a = 0;a<c.length;a++ )


{
System.out.println(c[a]);
}
}
}

Output

G
u
r
u
k
u
l

Code

class String8
{
public static void main(String[] args)
{
String s = new String ("Hello Guys");
String s1 = new String("Girls Hello");

boolean c = s.regionMatches(0,s1,6,4);

System.out.println("Whether the position of Hello in s1 and s2 is same = "+c);


}
}

Output

Whether the position of Hello in s1 and s2 is same = true

Code

public class Test83


{
public static void main(String args[])
{
String s1 = new String("Hello");
String s2 = new String("There");
System.out.println(s1);
s1=s2;
System.out.println(s1);
}
}

Output

Hello
There

This is because when we say s1 = s2, the earlier value of s1 is lost and now it points to s2 and
hence the output.

StringBuffer Class

StringBuffer is a class which is the mutable version for string concatenation. All the methods of
the String class return a new string object, as once a string object is created, it cannot be
changed.

However most of the methods of the StringBuffer class return the same object and changes are
made in the same memory location.
Constructors

a) StringBuffer () – creates space for 16 characters.

b) StringBuffer (int size) – creates a SB with the size specified in the parameter.

c) StringBuffer (String s) – creates a SB with the string specified and additional 16


character spaces.

Important Methods

1) int length () – This returns the current length of the SB.

2) int capacity () – This returns the total capacity of the SB.

Code

class SB1
{
public static void main(String[] args)
{
StringBuffer s = new StringBuffer();
System.out.println("The length of s is = "+s.length());
System.out.println("The total capacity of s is = "+s.capacity());

StringBuffer s1 = new StringBuffer("Hello");


System.out.println("The length of s1 is = "+s1.length());
System.out.println("The total capacity of s1 is = "+s1.capacity());

StringBuffer s2 = new StringBuffer(4);


System.out.println("The length of s2 is = "+s2.length());
System.out.println("The total capacity of s2 is = "+s2.capacity());
}
}

Output

The length of s is = 0
The total capacity of s is = 16
The length of s1 is = 5
The total capacity of s1 is = 21
The length of s2 is = 0
The total capacity of s2 is = 4

3) StringBuffer append (String s): adds to the end of the String Buffer. Is overloaded.

4) StringBuffer insert (int position, String s) – inserts at the specified int position.

5) StringBuffer reverse () – reverses the contents of the String.

Code

class SB2
{
public static void main(String[] args)
{
StringBuffer s1 = new StringBuffer("Hello");
s1 = s1.append(" Gurukul");
System.out.println("s1 after appending looks like = "+s1);

s1 = s1.insert(5," guys from");


System.out.println("s1 after inserting looks like = "+s1);
}
}

Output

s1 after appending looks like = Hello Gurukul


s1 after inserting looks like = Hello guys from Gurukul

6) StringBuffer delete ( int start , int end ) – Deletes a range of characters.

7) StringBuffer deleteCharAt(int position) – Deletes the character at the specified position.

8) New - StringBuffer replace( int start, int end, String s) – replaces the set of characters
specified between start and end with the String s.

9) New – String substring (int start) – this returns the substring from the StringBuffer object.

Code

class SB3

{
public static void main(String[] args)
{
StringBuffer s1 = new StringBuffer("Hello");
s1.delete(1,3);
System.out.println("After deleting characters from 1 to 3 in s1 = "+s1);

s1.deleteCharAt(1);
System.out.println("After further deleting characters at position 1 in s1 = "+s1);

StringBuffer s2 = new StringBuffer("lilly");

s2.replace(1,4,"Hello");
System.out.println("After replacing s2 looks like = "+s2);

}
}

Output

After deleting characters from 1 to 3 in s1 = Hlo


After further deleting characters at position 1 in s1 = Ho
After replacing s2 looks like = lHelloy

IMP: Also please note that the equals method is not overridden in the StringBuffer class and
hence when we call the equals () method on two String objects, it would return false, although the
contents of the same would be true.

The same if done with String class would return true, since the equals method is overridden in the
String class to check the contents of the String and not the memory location of the objects.

Code

class Test84
{
public static void main(String[] args)
{
StringBuffer sb = new StringBuffer("One");
StringBuffer sb1= new StringBuffer("One");

boolean a = (sb== sb1);


boolean b = sb.equals(sb1);
System.out.println(a);
System.out.println(b);
}
}

Output

false
false

What is a Java Exception?

Programmers in any language try to always write error and bug free codes, which would execute
properly under any circumstances and programs which should never crash. Unfortunately it is not
only difficult but many times impossible for a code to execute under any circumstances. Any
program at a given point of time would execute normally under normal circumstances.

In real programs, errors or abnormal conditions occur, either because the programmer didn't
anticipate every situation your code would get into (or didn't have the time to test the program
enough), or because of situations which are out of the programmer's control - bad input data from
users, corrupt files that don't have the right data in them, network connections that don't connect,
hardware devices that don't respond.

In Java, these sorts of strange events that may cause a program to fail are called Exceptions in
general.

The term exception is shorthand for the phrase "exceptional event". It can be defined as follows:

Definition: An exception is an event that occurs during the execution of a program that disrupts
the normal flow of instructions.

Many kinds of errors can cause exceptions - problems ranging from serious hardware errors,
such as a hard disk crash, to simple programming errors, such as trying to access an out-of-
bounds array element. When such an error occurs within a Java method, the method creates an
exception object and hands it off to the runtime system.

The exception object contains information about the exception, including its type and the state of
the program when the error occurred. The runtime system is then responsible for finding some
code to handle the error.

In Java terminology, 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 checks incase there is so one who can
handle that type of exception and incase there is indeed a catch block then the exception is
handled properly.

The runtime system searches backwards through the call stack, beginning with the method in
which the error occurred, until it finds a block that contains an appropriate exception handler or
called as the catch block.

An exception handler is considered appropriate if the type of the exception thrown is the same as
the type of exception handled by the handler. Thus the exception bubbles up (goes up) through
the call stack until an appropriate handler is found and one of the calling methods handles the
exception. The exception handler chosen is said to catch the exception.

If the runtime system exhaustively searches all of the methods on the call stack without finding an
appropriate exception handler, the runtime system (and consequently the Java program)
terminates.

Java defines a number of language features to deal with exceptions, including

1. How to handle exceptions in the code and recover gracefully from potential problems

2. How to tell users of the methods that you're expecting a potential exception

3. How to create an exception if one is necessary.

In other languages that do not support exception handling, errors must be checked and handled
manually – typically through the use of error codes and so on.
This approach is as cumbersome as it is troublesome. Java’s exception handling avoids these
problems and in the process brings run time error management into the object oriented world.

Java exception handling is managed via five keywords: try, catch, throw, throws and finally.

1. The try statement contains the program statements that you want to monitor for
exceptions contained within that block

2. The catch statement handles this exception or throws back the same. The System
generated exceptions are automatically thrown by the java run-time environment.

3. To manually throw an exception we should use the keyword throw

4. Any exception that is thrown out of a method must be specified as such by a throws
clause
5. Any code that must be executed before a method returns is put in a finally block

Exception Class Hierarchy

All exception types are sub classes of the built in class Throwable. Throwable is at the
top of the exception class hierarchy. The Throwable class has two subclasses namely
Exception and Error.

The logic behind this partition is why such abnormal conditions happen. Error in
programs happens normally not due to any error in programming logic but more due to
factors which are outside the programmer control.

The Error subclasses are not expected to be caught under normal circumstance by the
program. These abnormal conditions are used by the Java runtime system to indicate
errors having to do with the run-time environmental, itself. Error class has subclasses
which are serious problems which are not normally associated with the code and which
the programmer should not try to catch, like for example ClassFormatError (when the
.class file has been tampered with). We should let the JVM handle the Error as the way it
wants to.

Exception happens more generally due to factors which are within the programmers
control and programmer should properly handle the same. Since the Exception class
contains exception sub classes which are within the programmer’s control, the
programmer should catch the same (but not all sub classes as explained later on).

The Exception class is again classified into two sections called as the Compile Time Exception
and Runtime Exception.
It is the programmer’s duty to properly handle the Compile Time Exceptions whereas like Errors
they can let the JVM handle the Runtime Exception. The RuntimeException automatically defines
for the programs that you will write and include things such as division by zero and invalid array
indexing.

The other main branch is topped by Error, which defines exceptions that are not expected
to be caught under normal circumstances by your program.

Generating Exceptions

Whenever there is an exception, it must be caught by an exception handler and dealt with
immediately. But incase the same is not caught, and then it 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 following is
the code which automatically generates an exception and on the basis of the output, we
will analyze the code

Code

class Test57
{
public static void main (String args [])
{
System.out.println("Before Exception");
int a = 42/0;
System.out.println("After Exception");
}
}

Output

Before Exception
java.lang.ArithmeticException: / by zero
at Test57.main(Test57.java:6)
Exception in thread "main"

When we compile the above code, it compiles properly, but at runtime it generates the following
output, which means that ArithmeticException which is generated is a Runtime Exception.
IMP: Any statement after the exception object in the same block of code will not be printed.

When the exception object is raised by the JVM at line number 6 of the above code, it looks for
an exception handler immediately and does not find the same and the program crashes.

Notice how the class name, Test; the method name, main, the filename, Test.java and the line
number 6, are all included in the simple stack trace. Also, notice that the type of the exception
thrown is a subclass of Exception called ArithmeticException, which more specifically describes
what type of error happened.

IMP: The stack trace will always show the sequence of method invocations that led up to the
error. Let us see this with the example of a Code

Code

class Extra3
{
public static void main(String[] args)
{
Extra3 y = new Extra3();
y.met1();
}

void met1()
{
met2();
}

void met2()
{
int a [] = {10,29};

int x = a[3];

System.out.println(x);
}
}

Output

java.lang.ArrayIndexOutOfBoundsException
at Extra3.met2(Extra3.java:18)
at Extra3.met1(Extra3.java:11)
at Extra3.main(Extra3.java:6)
Exception in thread "main"

try and catch blocks

All though the default exception handler provided by the Java runtime system is useful for
debugging, you will usually want to handle an exception yourself. Doing so will be advantageous
in two ways:-
a) It allows one to fix the error and allows program to continue

b) It prevents the program from terminating automatically. Most users would be confused if
the program stopped running and printed a stack trace whenever an error occurred!.
They need to be told in a softer manner and in plain words what caused the above
abnormal condition.

try is keyword in java and the block that follows the try should have the codes which the
programmer feels that might generate an exception.

catch is also keyword in java. The catch block will have in its parameter the type of exception
which that particular catch block can handle.

Incase if any exception is generated in the try block, the program immediately comes out of the
try block and looks for the catch block within the method and incase it does not find the same, it
will look for it in the method which called the method in which the abnormal condition happened
and this continues till it reaches the topmost method.

If the program finds a catch block at any position, then it would continue the normal executed of
the program, in the method in which the catch block was found and the program would terminate
normally.

Code

class Extra4
{
public static void main(String[] args)
{
Extra4 y = new Extra4();
y.met1();
System.out.println("last Line in main method");
}

void met1()
{
met2();
System.out.println("last Line in met1()");
}

void met2()
{
int a [] = {10,29};
try
{
int x = a[3];
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("caught in met2 ");
}
System.out.println("last Line in met2()");
}
}

Output
caught in met2
last Line in met2()
last Line in met1()
last Line in main method

Now instead of having the catch block at the point of generation of the error, let have the catch
block in the main method and now let us see the output.

Code

class Extra5
{
public static void main(String[] args)
{
Extra5 y = new Extra5();
try
{
y.met1();
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("caught in met2 ");
}
System.out.println("last Line in main method");
}

void met1()
{
met2();
System.out.println("last Line in met1()");
}

void met2()
{
int a [] = {10,29};
// try
// {
int x = a[3];
// }
/* catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("caught in met2 ");
}*/
System.out.println("last Line in met2()");
}
}

Output

caught in met2
last Line in main method

We saw that incase the exception is not caught, it would not print any line further after the
generation of the exception and the program would continue further in the method in which it was
caught and hence the last lines in met1 and met2 methods were not printed.
The important points to be noted here is that:

a) Once an exception is thrown, the program control transfers out of the try block into the
relevant catch block and any statement after the try block does not execute. We saw that
the println statement “In Try Block” did not get executed.

b) Incase a exception is generated in a method, then the program will look for the catch
statement in that method and incase it does not find one, then it will look for the catch
statement in the method which called this method and incase again there is no catch
block there also, then the program will crash and properly generate the stack records.
(We will see this possibility in the next code).

c) Both the try and catch blocks are blocks of code and once the program control shifts out
of the try block, it will not come back into the try block like methods do.

d) A try block must be accompanied by at least one catch statement or finally statement. It
is not mandatory that try should always be accompanied with the catch block, it can be
with the finally block also, but in that case remember that the exception would not be
caught.

e) There can be no intervening statement between the end of a try block and the beginning
of a catch block.

f) A catch statement requires a single formal statement. The argument to a catch statement
looks like an argument declaration for a method. The argument type declares the type of
exception that the handler can handle and must be the name of a class that inherits from
the Throwable class. When a java programs throw an exception they are really just
throwing an object and only objects that derive from Throwable can be thrown.

Displaying a Description of an Exception

The Throwable class overrides the toString () defined in the object, so that it returns a string
containing a description of the exception. You can display this description in a println statement
by simply passing the exception as an argument. For Example

catch (ArithmeticException e)
{
System.out.println(“Exception : “ + e);
}

wherein e gives u the description of the exception that occurred

Now there are 4 ways in which to describe an exception in the catch block and they are:-

a) A simple println() method which would say “Exception caught” or some other plain
lines, which does not use the exception object e.

b) A printStackTrace () method which uses the exception object and which generated
the complete stack trace as if the exception actually occurred. The printStackTrace()
method actually informs us about 5 important things and they are:-

1) The name of the exception. }


2) Message of the exception } Both the above are in the 1st line
3) Method in which exception was generated
4) Source Code file name in which the exception was generated
5) Line Number in which the exception was generated.

The last 3 points are there in the 2nd line. and incase there is no exception handler
(catch statement) in a method, they it will go up the stack trace and give details of the
same also. (as we saw in the earlier code).

c) Simply printout the exception objects (e). This will give the description of the
exception and the message of the exception ( Line No 1 of the printStackTrace()
method) only.

d) Incase we need only the message of the exception, we can use the method
getMessage() on the exception object and get only the message of the exception.
Remember that e.getMessage() should be in the println() method.

Code

class Extra2
{
public static void main(String[] args)
{
try
{
int a = 10 / 0;
}
catch (ArithmeticException e)
{
System.out.println("Exception caught");
System.out.println("----------------------------------------------");
e.printStackTrace();
System.out.println("---------------------------------");
System.out.println(e);
System.out.println("---------------------------------");
System.out.println(e.getMessage());
}
}
}

Output

Exception caught
----------------------------------------------
java.lang.ArithmeticException: / by zero
at Extra2.main(Extra2.java:7)
---------------------------------
java.lang.ArithmeticException: / by zero
---------------------------------
/ by zero

finally keyword

When exceptions are throws, execution in a method takes a rather abrupt, nonlinear path that
alters the normal flow through the method. Depending on how the method is coded, it is even
possible for an exception to cause the method to return prematurely.
This could be a problem in some method. For example, if a method opens a file upon entry and
closes it upon exit, then you will not want the code that closes the file to be bypassed by the
exception-handling mechanism.

The finally block provides the means to clean up at the end of executing a try block.

You use a finally block when you need to be sure that some particular code is run before a
method returns, no matter what exceptions are thrown within the previous try block.

A finally block is always executed, regardless of what happened during the execution of the
method. If a file needs to be closed or a critical resource released, you can guarantee that it will
be done if the code to do it put in a finally block.

If an exception is thrown, the finally block will execute even if no catch statement matches the
exception. For a try block, either a catch statement or a finally statement has to be present.

Code

class Test61
{
public static void main(String[] args)
{
int a = 0;
int b = 0;

try
{
a = args.length;
b = 10/a;
System.out.println("The value of b is ="+b);
}
catch (ArithmeticException e)
{
e.printStackTrace();
}
finally
{
System.out.println("Finally block");
}

System.out.println("After all execution");

}
}

Output

Possibility One

Incase we do pass parameters as we did earlier (assume we passed two parameters) then the
output would be

The value of b is =5
Finally block
After all execution
Possibility Two

Incase we do not pass any parameters, then the output would be

java.lang.ArithmeticException: / by zero
at Test61.main(Test61.java:11)
Finally block
After all execution

In both the possibilities we saw that the finally block was always executed. In the second
possibility, we saw that since an exception was generated, it went into the catch block and then
into the finally block and the program went on properly.

Now let us see what would be the output incase we comment the catch block and the output
would be

Finally block
java.lang.ArithmeticException: / by zero
at Test61.main(Test61.java:11)
Exception in thread "main"

We saw that the finally block gets executed whether the exception is caught or not caught. Over
here before the exception stack trace is printed since there is no catch statement, the finally block
gets a chance to execute itself and then the error is thrown out. Since there is no catch block, the
program gets crashed the final println() statement is not executed.

throws keyword

In the previous examples you learned how to deal with methods that might possibly throw
exceptions by the Java Run-time system and protecting code (try block) and catching any
exceptions that occur. The Java compiler will check to make sure you've somehow dealt with a
method's exceptions-but how did it know which exceptions to tell you about in the first place?

The answer is that the original method indicated in its signature the exceptions that it might
possibly throw. You can use this mechanism in your own methods-in fact; it's good style to do so
to make sure that other users of your classes are alerted to the errors your methods may come
across.

To indicate that a method may possibly throw an exception, you use a special clause in the
method definition called throws.

The throws Clause

To indicate that some code in the body of your method may throw an exception, simply add the
throws keyword after the signature for the method (before the opening brace) with the name or
names of the exception that your method throws:

public boolean myMethod (int x, int y) throws AnException


{
...
}
If your method may possibly throw multiple kinds of exceptions, you can put all of them in the
throws clause, separated by commas:

public boolean myOtherMethod (int x, int y)


throws AnException, AnotherException, AThirdException
{
...
}

Note that as with catch you must use a superclass of a group of exceptions to indicate that your
method may throw any subclass of that exception:

public void YetAnotherMethod() throws IOException


{
...
}

Keep in mind that adding a throws method to your method definition simply means that the
method might throw an exception if something goes wrong, not that it actually will. The throws
clause simply provides extra information to your method definition about potential exceptions and
allows Java to make sure that your method is being used correctly by other people.

IMP: Pls remember that the exception which will be caught should be equal or higher in the
hierarchy than the exception thrown. Incase it is down in the hierarchy the compiler will complain.

Code

class Test62
{
public static void main(String[] args)
{
Test62 x = new Test62();
try
{
x.met1();
}
catch (Exception e)
{
System.out.println("Following Exception caught in main method" + e);
}
System.out.println("After all exceptions in the main method");
}

void met1() throws Exception


{
try
{
int a = 10 / 0;
}
catch (ArithmeticException e)
{
System.out.println(e.getMessage());
}
}
}
Output

/ by zero
After all exceptions in the main method

Points to be noted:

1) We are putting int a = 10/0 in a try block within met1() and hence the exception is
caught inside met1() itself and no exception is pending and hence it did not go into
the catch block in the main method and also printed out the final println () statement.

2) Try removing the try block in met1() method so that an exception object will be
pending and which will be caught in the main method and then the output would be.

Following Exception caught in main method java.lang.ArithmeticException: / by zero


After all exceptions in the main method

3) Now in the 1st point, there was no exception, but we still put x.met1() code in the try
block as said earlier. We will see now what happens when we remove the try and
catch block in the main method and simply put x.met1() in the main method.

Test62.java:8: unreported exception java.lang.Exception; must be caught or declared


to be thrown
x.met1();
^
1 error

So here we saw that irrespective of whether an exception comes out the met1()
method or not (over here there is no exception since it is already caught in the met1()
method) we still have to put the calling code x.met1() in the calling method in try and
catch blocks.

4) Now we will change the exception type in the catch block of the main method from
Exception to Arithmetic exception and also remove the full try and catch blocks from
met1() so that an Arithmetic exception definitely gets generated and see what is the
output.

Test62.java:8: unreported exception java.lang.Exception; must be caught or declared


to be thrown
x.met1();
^
1 error

Again the compiler complains, this is because although Arithmetic Exception is


coming out, it is declaring to the world that it throws Exception object and all methods
which call this method should mandatorily should catch Exception only.

throw keyword

Until now we have been depending on the JVM to generate the system defined exception, but in
many situations in our code we would want to generate a exception ourselves depending on
some conditions.
Declaring that your method throws an exception is useful only to users of your method and to the
Java compiler, which checks to make sure all your exceptions are being dealt with. But the
declaration itself doesn't do anything to actually throw that exception should it occur; you have to
do that yourself in the body of the method.

Remember that exceptions are all instances of some exception class, of which there are many
defined in the standard Java class libraries. In order to throw an exception, therefore, you'll need
to create a new instance of an exception class. Once you have that instance, use the throw
statement to throw it (could this be any easier?). The simplest way to throw an exception is simply
like this:

throw new ServiceNotAvailableException();

IMP: You can only throw objects that are instances of subclasses of Throwable. This is different
from C++ exceptions, which allow you to throw objects of any type.

Depending on the exception class you're using, the exception may also have arguments to its
constructor that you can use. The most common of these is a string argument, which lets you
describe the actual problem in greater detail (which can be very useful for debugging purposes).
Here's an example:

throw new ServiceNotAvailableException("Exception:


service not available, database is offline.");

Once an exception is thrown, the method exits immediately, without executing any other code
(other than the code inside finally, if that clause exists) and without returning a value. If the calling
method does not have a try or catch surrounding the call to your method, the program may very
well exit based on the exception you threw.

IMP: Whenever a method has a throw keyword inside its body, the signature of the method
should mandatorily have the throws keyword. This is but obvious, since throws keyword tell the
callers of its method, that a exception might or might not occur from its body and with the throw
keyword there is definitely an exception and hence throws is required in the signature of the
method.

IMP: Like any other case, when an exception object is generated, it would look for the catch block
otherwise the program would crash. Also once the exception object is generated, no further
statement in the block would be executed. Also the throw keyword can be there in any part of the
methods, in the catch block or outside the catch block etc.

Code

class Test64
{
public static void main(String[] args)
{
Test64 x = new Test64();

try
{
x.met1();
}
catch (Exception e)
{
System.out.println(e);
}
System.out.println("In the main method");
}

void met1() throws Exception


{
try
{
int a = 10 / 0;
}
catch (ArithmeticException e)
{
System.out.println(e);

throw new Exception("This is a user generated exception");


}
System.out.println("After the throw keyword");
}
}

Output

java.lang.ArithmeticException: / by zero
java.lang.Exception: This is a user generated exception
In the main method

So here we saw that the first line is because of the catch block in the met1() and there again it
uses the throw keyword to generate another Exception object and give it a message. Remember
that the println() "After the throw keyword" does not print since there is no catch block for this new
exception object and it goes back to the caller, where there is a catch block and the programs
continues.

IMP: The exception object in the throws cause of the method which has a throw keyword should
be higher in the hierarchy always. Incase we swap the exceptions that is the throws keyword
would have the ArithmeticException e and the catch block in met1() would have the Exception
object, then the following error would be generated

Test64.java:28: unreported exception java.lang.Exception; must be caught or declared to be


thrown
throw new Exception("This is a user generated exception");
^
1 error

Checked and Unchecked Exceptions

Since exceptional conditions throw objects, objects are instances of classes, and classes may be
inherited in Java, a natural hierarchy can be created which causes exceptions to be grouped in
logical ways.

1. Checked Exceptions - The checked exceptions are the exceptions which the java
compiler will check and incase not properly done would not compile. The checked
exceptions are those classes which are sub-classes of the Exception class other than the
RuntimeException class.
This would mean that for all these subclasses the compiler would check, which would
mean that we have to mandatorily write any methods which throw these types of
exceptions in try - catch block or the method should have the throws signature. Unless
this is done, the compiler will not allow the code to compile

2. Un-checked exceptions- These types of exception are not checked by the compiler and
hence it is not mandatory to write these methods in try / catch block. However to ensure
that the program continues smoothly, we should properly handle these exceptions also,
but the compiler does not force us, like in the case of Checked Exceptions.All the
subclasses of the RuntimeException and Error classes fall under this category.

Exceptions of all Exception classes and subclasses other than RuntimeException which is a
subclass of Exception (approximately seventeen different classes plus any that you may add) are
checked by the compiler and will result in compiler errors if they are not either caught or specified.

Later, we will learn how you can create your own exception classes. Whether your exception
objects become non-checked or checked depends on which class you choose as your superclass
in defining your exception class.

Code

import java.io.*;
class Test65
{
public static void main(String[] args)
{
try
{
FileInputStream fis = new FileInputStream("c:/one.txt");
}
catch (IOException e)
{
System.out.println(e);
}
System.out.println("Hello World!");
}
}

Output
Hello World!

The rule is that all checked exceptions should be mandatorily should be put in an exception
handling mechanism whether they throw an exception or not. Now in the above code we have put
the FileInputStream which throws a FileNotFoundException which is a subclass of the
IOException which is a checked exception.

We are trying to open a file called one.txt which is there in the C: root directory. For all IO we
should use the system independent way of handling the files that is the “/” slash and not the
windows type of “\” slash.

Now if the file is not there, it would throw an exception and the output would be

java.io.FileNotFoundException: c:/one.txt (The system cannot find the file specified)


Hello World!
Normal Termination
and if the file is indeed there it would not enter the catch block. Now the argument would be if the
file is indeed there then should we put the code in a try - catch block. So let us comment the try
and catch statements and directly put the line FileInputStream fis = new
FileInputStream("c:/one.txt"); in the main method and the output would be:

Test65.java:9: unreported exception java.io.FileNotFoundException; must be caught or declared


to be thrown
FileInputStream fis = new FileInputStream("c:/one.txt");
^
1 error

So this confirms that whether in a Checked Exception we should mandatorily put the code in a try
- catch block because the compiler checks for the same.

Creating own Exceptions

Exceptions are simply classes, just like any other classes in the Java hierarchy. Although there
are a fair number of exceptions in the Java class library that you can use in your own methods,
there is a strong possibility that you may want to create your own exceptions to handle different
kinds of errors your programs might run into.

Fortunately, creating new exceptions is easy. Your new exception should inherit from some other
exception in the Java hierarchy. Look for an exception that's close to the one you're creating; for
example, an exception for a bad file format would logically be an IOException.

If you can't find a closely related exception for your new exception, consider inheriting from
Exception, which forms the "top" of the exception hierarchy for explicit exceptions (remember that
implicit exceptions, which include subclasses of Error and RuntimeException, inherit from
Throwable).

Exception classes typically have two constructors: The first takes no arguments and the second
takes a single string as an argument. In the latter case you'll want to call super() in that
constructor to make sure the string is applied to the right place in the exception.

Beyond those three rules, exception classes look just like other classes. You can put them in their
own source files and compile them just as you would other classes:

IMP: Also the convention is to have the Exception word as the last in the class name of user
defined exceptions. Also whether the user defined exception would be a checked exception or
unchecked exception would depend on which class we are extending.

Code

class UserDefinedException1 extends RuntimeException


{
UserDefinedException1()
{
}

UserDefinedException1(String s)
{
super(s);
}
}
class UserDefinedException extends Exception
{
UserDefinedException()
{
}

UserDefinedException(String s)
{
super(s);
}
}

class Test66
{
public static void main(String[] args)
{
Test66 x = new Test66();
try
{
x.met1();
}
catch (Exception e)
{
System.out.println(e);
}
} // end of main

void met1() throws Exception


{
if (true)
{
throw new UserDefinedException1("This is Exception");
}
else
{
throw new UserDefinedException1("This is Exception1");
}
} // end of met1
}

Output

UserDefinedException1: This is Exception

In the above code we created two user defined exception and simply tried the same in Test66.
Change the if condition to false you will fine that it will throw UserDefinedException1 and the
output would be

UserDefinedException: This is Exception1

The super statement in the String parameter constructor of the user defined constructor is very
important as without that whatever message that we print in the throw statement parameter would
not go the getMessage() and hence nothing would be printed. To test the same comment the
super() statement from both the user defined exceptions and then compile and run Test66. We
will find that whatever message we give the throw statement would not be printed.
Structure of the IO Package

Java input and output is based on the use of streams.

Streams are sequences of bytes that travel from a source to a destination over a
communication path. If your program is writing to a stream, it is the stream's source. If it
is reading from a stream, it is the stream's destination.

The communication path is dependent on the type of I/O being performed. It can consist
of memory-to-memory transfers, file system, network, and other forms of I/O.

A Stream is an abstract representation of an input or output device that is a source of or


destination for data. The java.io package supports two types of streams, Binary Streams,
which contain binary data, and character streams, which contain character data.

When you write data to a stream as a series of bytes, that is binary data, it is written to the
stream exactly as it appears in memory. No transformation of the data takes place. Numerical
values are just written as a series of bytes.

Character streams are used for storing and retrieving text. You can also use character streams
to read a text file not written by a java program.

All numeric values are converted to a textual representation before written to the stream. This
involves formatting the data to generate a character representation of the data value.

All Unicode Characters are automatically converted to the local representation of the characters
as used by the host machine and then these are written to the file.

Unicode uses 16 bits to represent each character. If the high-order 9 bits are all zeros, then the
encoding is simply standard ASCII, otherwise the bits represents a character that is not
represented in 7-bit ASCII. Java’s char datatype uses Unicode Encoding.

Unicode’s 16-bit is sufficient to encode most alphabets but pictographic Asian Languages like
Japanese, Vietnamese present a problem. The answer for this is UTF (UCS Transformation
format and UCS stands for Universal Character Set).

UTF encoding uses as many bits as needed to encode a character: fewer bits for smaller
alphabets and more bits for larger Asian alphabets.

The important classes in the io.package are

a) File – An object of this class represents a pathname either to a file that you will access for
input or output or to a directory.

b) RandomAccessFile – Random Access to a File.


c) Output Stream – Base class for Byte Stream output.

d) Input Stream – Base Class for Byte Stream Input.

e) Writer – Base class for Character stream Output.

f) Reader – Base class for Character stream Input.

- Streams are powerful because they abstract away the details of the communication path
from input and output operations. This allows all I/O to be performed using a common set of
methods.

- Whenever we are using the classes of the java.io package, the package will have to be
imported and all the codes should be put in a try - catch block or the method should have
throws signature, because most of the methods in this package throw IOException which is a
Checked Exception.

File Class

File class represents the name of a file or directory that might exist on the hose machine’s file
system.

The constructors are

1. File (String file)

2. File(String dir, String subpath)

3. File(File dir, String subpath)

"File" class is a non-stream class because it just has methods to access the information about a
file or directory entry in the file system and not the file contents. To get information about a file
and perform standard operations on it, we should first have a valid File object.

The important methods are:

1. Boolean exists() – Where the file or directory exists or not

2. String getAbsolutePath() – This returns the absolute and not the relative path of file or
directory.

3. String getName()

4. String getParent() – This returns the name of the directory that contains the File.

5. Boolean isDirectory()

6. Boolean isFile()

7. String [ ] list() – This returns an array containing the name of files and directories within
the File (which should be a directory).

8. Boolean canRead()
9. Boolean canWrite()

10. long length()

11. Boolean mkdir(File f)

12. boolean renameTo (File newname)

Creating a file or directory

createNewFile() - Atomically creates a new, empty file if and only if a file with this name does not
yet exist.

createTempFile(String prefix, String suffix) - Creates an empty file in the default temporary-file
directory, using the given prefix and suffix to generate its name.

createTempFile(String prefix, String suffix, File directory) - Creates a new empty file in the
specified directory, using the given prefix and suffix strings to generate its name.

Creating a File object for a nonexistent file is not an error, so File constructors will not throw any
exceptions. You can use the exists() method to find out the file or directory existence.

We can create a directory with mkdir() or mkdirs().

mkdir() creates a single directory; mkdirs() creates the directory including any necessary but
nonexistent parent directories

renaming a file

renameTo(File dest) - Renames the file/directory denoted by this abstract pathname.

deleting a file or directory

delete() to delete a file or directory.

Although you can create and delete files and directories, there is no method that allows you to
change the current working directory. You have to just create a new "File" object with a different
directory for the constructor.

IMP: Deleting an instance of the File has no effect on the local file system

IMP: Please note that the File class objects created are of a directory present in the system
and for checking the same, please change it to a directory present in your system along
with the file.

Code (Simple methods of the File class)

import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class File1


{
File f;
public File1() throws IOException
{
f= new File("C:/Students-March","test.txt");
System.out.println("Chek for the file " +f.exists());
System.out.println("Chek for the file " +f.getName());
System.out.println("Chek for the file " +f.getParent());
System.out.println("Chek for the file " +f.isFile());
System.out.println("Chek for the file" +f.isDirectory());

}
public static void main(String args[]) throws IOException
{
new File1();
}
}

Code (Example of the list method of the File class)

import java.awt.*;
import java.io.*;
import java.awt.event.*;

public class File2 implements ActionListener


{
File f;
Frame f1;
TextArea ta;
TextField tf;
Button b;

public File2()
{
try
{
f1 = new Frame("F1");
f1.setLayout(new FlowLayout());
ta = new TextArea(10,20);
tf = new TextField(20);
b = new Button("Ok");

f1.add(tf);
f1.add(b);
f1.add(ta);

tf.addActionListener(this);
b.addActionListener(this);

f1.setSize(200,200);
f1.setVisible(true);
}
catch(Exception ie)
{
ie.printStackTrace();
}
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==b)
{
String s = tf.getText();
File f = new File(s);
if (f.isDirectory())
{
String arr[]= f.list();
for( int i=0;i<arr.length;i++)
{
ta.append(""+arr[i]+"\n");
}
}
else if(f.isFile())
{
ta.append("Please enter directory name");
}

}
}
public static void main(String[] args)
{
new File2();
}
}

RandomAccessFile Class

One way to ready or modify a file is to use the RandomAccessFile class. This class represents a
model of files that is incompatible with the Stream / Writer classes.

With a RandomAccessFile, you can seek a desired position within a file and then read or write a
desired amount of data. The RandomAccessFile provides method that support seeking, reading
and writing

Constructors

RandomAccessFile (String file, String mode // which can be ‘r’ or ‘rw’)

The rw refers to Read - Write over here.

The ‘rw” form of constructor is useful when you want to open some of the methods of the File
class before opening a RAF, so that a instance of File is in hand when calling the RAF
constructor.

Constructing a RAF is similar like constructing an instance of File.

After a random Access file is created, you can seek to any byte position within the file and then
read or write. Pre java systems have supported this seeing to a position relative to the beginning
of the file, end of the file or the current position of the file. The methods
long getFilePointer () throws IOException – This returns the current position within the file, in
bytes, Subsequent reading and writing will take place starting at this position.

long length() throws – length of file in bytes

void seek( long position) thro – This sets the current position within the file in bytes. Subsequent
reading and writing will take place at this position. Files start at position 0.

The common methods that support reading and writing are:

int read() - this returns the next byte from the file or –1 is end of file

int read(byte d[]) – attempts to read enough bytes t fill array d[]

int read(byte d[], int o, int n) – attempts to read n number of bytes into array d[] starting at o.

RandomAccessFile supports reading and writing of all primitive data types.

When RAF is no longer needed, it should be closed:

void close() throws IOException

Code

import java.awt.*;
import java.io.*;

public class Raf1


{
RandomAccessFile raf ;
public Raf1()
{
try
{
raf = new RandomAccessFile("1.txt","rw");
raf.writeBoolean(true);
raf.writeChar('a');
raf.writeInt(1234);
System.out.println("read1"+raf.length());

raf.seek(1);
System.out.println("read1"+raf.readChar());
System.out.println("read1"+raf.readInt());
raf.seek(0);
System.out.println("read1"+raf.readBoolean());
}
catch(Exception e)
{
e.printStackTrace();
}
}

public static void main(String[] args)


{
new Raf1();
}
}

Stream Classes

The superclass of the Stream Classes or called as the byte oriented classes are the abstract
class InputStream and OutputStream. We will be discussing each of the important classes
relevant from the certification point over here.

FileInputStream

This class will enable us to create a InputStream with which one can use to read bytes from a file.

The common Constructors are as under:

FileInputStream (String filename);


FileInputStream (File f);

Either of this will throw a checked exception and hence will have to be put in a try / catch block or
the method will have to throw this FileNotFoundException.

Code

import java.io.*;

public class Fis1


{
public static void main(String[] args)
{
try
{
File f =new File(args[0]);
FileInputStream fis = new FileInputStream(f);
int i = fis.available();

for(int j=0;j<i;j++)
{
System.out.print((char)fis.read());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

Code

import java.io.*;

public class Fis2


{
public static void main(String[] args)
{
try
{
File f =new File(args[0]);
FileInputStream fis = new FileInputStream(f);
int i;
while((i = fis.read())!=-1)
{
System.out.print((char)i);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

In the earlier two codes, we have seen how to use the while and the for loop for using the read ()
method and then printing out the contents of the file which we pass as argument to the code.

ByteArrayInputStream

This is an implementation of an InputStream that uses byte array as the source.

The two constructors for this are:

ByteArrayInputStream (byte b[])

ByteArrayInputStream (byte b[], int start, int noofbytes)

Code

import java.io.*;

public class BAIS


{
public static void main(String[] args)
{
try
{
String s = "hello is it done?";
byte b[] = s.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(b);
int i;
while((i=bais.read())!=-1)
{
System.out.print((char)i);
}
}
catch (Exception ie)
{
ie.printStackTrace();
}

}
}
SequenceInputStream

This class allows us to concatenate two Input Streams.

The two constructors for this are:

SequenceInputStream (IS one, IS two); Remember it can take only two Input Streams.

SequenceInputStream (Enumeration s)

In the case of the first constructor, the class reads requests from the first until it runs out and then
switches to the other and so on.

In the case of Enumeration, it will continue through all the IS until the end of the last one is
reached.

Code

import java.io.*;

public class SIS


{
public static void main(String[] args)
{
try
{
FileInputStream fis = new FileInputStream("1.txt");
FileInputStream fis1 = new FileInputStream("2.txt");
SequenceInputStream sis = new SequenceInputStream(fis,fis1);
int i;
while((i=sis.read())!=-1)
{
System.out.print((char)i);
}
}
catch (IOException ie)
{
ie.printStackTrace();
}

}
}

Filter Streams

The FilterInputStream and FilterOutputStream classes are subclasses of InputStream and


OutputStream that acts just like a regular stream, except that it performs some additional
processing on an underlying data stream.

Each of the subclasses of FilterInputStream works by wrapping an existing input stream, called
the underlying input stream, and providing additional functionality. The methods of
FilterInputStream simply override the methods of InputStream with versions that call the
corresponding methods of the underlying stream.

You won't much use these classes directly. Some of the filtered streams that are:
1. Buffered streams
2. Data streams
3. Print Stream

You connect filter streams to an underlying stream that supplies the actual bytes of data by
passing the original stream to the filter stream's constructor. For example, to create a new
DataOutputStream from a FileOutputStream,

FileOutputStream fos = new FileOutputStream("ln.txt");


DataOutputStream dos = new DataOutputStream(fos);

Buffered Streams

Buffering is usually used to increase the efficiency of a stream.

The BufferedInputStream is "wrapped" around the underlying stream, a FileInputStream. The first
time we call read() on the buffered stream, it fills an internal buffer from the underlying
FileInputStream.

Subsequent calls to read() return data directly from the buffer, which is faster than reading the file
again. The BufferedInputStream constructors let you specify whatever buffer size you want.

Data Streams

The Date Stream a type of filtered streams is for reading and writing primitive types and objects in
a portable way.

It gives you access to a range of methods such as readDouble, readInt that will work the same on
different platforms. In JDK1.0 this was one of the main ways to access Unicode text, but has
been superceded by the Reader classes since JDK 1.1. These classes take an instance of a
Stream as a constructor

These are conveniently named writeInt(), writeDouble(), writeBoolean(), and so forth. Data written
with a DataOutputStream can be read using a DataInputStream using the readInt(), readDouble()
and readBoolean() etc.

These classes read and write primitive Java data types and Strings in a machine-independent
way. (Big-endian for integer types, IEEE-754 for floats and doubles, UTF-8 for Unicode)

PrintStream

The print stream class is implemented by System.out and System.err. It allows very simple
printing of primitive values, objects, and string literals. It uses the platform's default character
encoding to convert characters into bytes. This class traps all IOException.

However you can test the error status with checkError(). This returns true if an error has occurred,
false otherwise. public boolean checkError() The main use of the class is the exceptionally
overloaded print() and println() methods. They differ in that println() adds an end-of-line character
to whatever it prints while print() does not.

Code

import java.io.*;

public class DIS


{
public static void main(String[] args)
{
try
{
FileOutputStream fos = new FileOutputStream("3.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(10) ;
dos.writeDouble(10.10);
dos.writeBoolean(true);
dos.close();
fos.close();
FileInputStream fis = new FileInputStream("3.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(""+dis.readInt());
System.out.println(""+dis.readDouble());
System.out.println(""+dis.readBoolean());
}
catch (IOException ie)
{
ie.printStackTrace();
}

}
}

FileOutputStream

The FileOutputStream is used to create an OutputStream that u can use to write bytes to a file.

The most common used constructors are:

FileOutputStream (String s)
FileOutputStream (File f)
FileOutputStream (String s, boolean append)

This class can throw IOException or SecurityException.

IMP: Creating of a file is not dependent on whether the file is already existing or not. This will
create another file and incase there is a existing file, the same will be overwritten.

Code

import java.io.*;

public class FOS1


{
public static void main(String[] args)
{
try
{
String s= "appending here";
byte b[] =s.getBytes();

FileOutputStream fos = new FileOutputStream("1.txt",true);


for(int i=0; i<b.length;i++)
{
fos.write(b[i]);

}
fos.close();
}
catch (IOException ie)
{
ie.printStackTrace();
}
}
}

Character Classes

The Streams basically was dealing with bytes and hence the Reader and Writer classes was
introduced which is also called as Character Oriented Streams.

The important Reader Classes from the Certification point of view are

a) File Reader
b) BufferedReader

Both the above classes are similar to the byte oriented streams.

Code

import java.io.*;

public class FReader


{

public static void main(String[] args)


{
try
{
FileReader fr= new FileReader("1.txt");
FileWriter fw = new FileWriter("5.txt");

int i;
while ((i=fr.read())!=-1)
{
System.out.print((char)i);
}

}
catch (IOException ie)
{
ie.printStackTrace();
}

}
}
Corresponding to the Reader classes, the important classes from the certification point of view
are

a) FileWriter
b) BufferedWriter

Code

import java.io.*;

public class FReader


{

public static void main(String[] args)


{
try
{
FileReader fr= new FileReader("1.txt");
FileWriter fw = new FileWriter("5.txt");

int i;
while ((i=fr.read())!=-1)
{
System.out.print((char)i);
}

}
catch (IOException ie)
{
ie.printStackTrace();
}

}
}

Code

import java.io.*;

public class ISReader


{
public static void main(String[] args)
{
try
{
System.out.println("Enter the first number ");
BufferedReader br= new BufferedReader(new
InputStreamReader(System.in));
String s = br.readLine();
int i =Integer.parseInt(s);
System.out.println("Enter the second number ");
s = br.readLine();
int j =Integer.parseInt(s);
int k = i + j;

System.out.println("The total is: "+k);


}
catch (IOException e)
{
e.printStackTrace();
}
}
}

The above code is important since we are using the System.in to take the input from the user and
for this we always have to wrap System.in in the InputStreamReader class.

Multi Threading

This is a concept wherein multiple threads within a single process gets executed. When we start
a simple program, the default main is a thread and we can also create threads within it.

There are two important methods in any thread, that is the run () in which one will put all
the codes that the thread will have to execute and another is the start () method, which
makes the thread ready to run. When the thread will start running (execute the run ()) will
depend on the Thread Scheduler. What the start () does is that it puts the thread in the
ready to run state. There are two types of thread schedulers-

Pre-emptive Scheduler: In this case a thread with will leave the running state in the
following three situations.

A thread of higher priority is there in the ready to run state.


A thread yields
A thread sleeps.

In Solaris, the scheduling is pre-emptive, that would mean that any thread should either
yield or sleep, or the other threads will never run.

Time Sliced Scheduler: In this scheduler any thread runs for a fixed amount of time and
then enter the ready to run state and allows another thread to run, again depending of its
priority. This scheduler ensure that all thread will run at some stage anyhow. The dis-
advantage of this is that it is non-deterministic – which thread executes at a particular
point of time or for how long it will execute.

In Windows 98, threads of equal priority are time sliced.


In java technology, threads are usually preemptive, but not necessarily time sliced (the
process of giving each thread an equal amount of CPU time).

The Thread Class and the Runnable Interface

There are two ways how to make a thread execute and that is by extending the Thread Class or
by implementing the Runnable Interface. Infact the whole of java’s multithreading system is built
upon the Thread class, its methods and its companion interface, Runnable.

The main Thread

When a java program starts up, one thread begins running simultaneously. This is usually
called the main thread of your program, because it is the one that is executed when your
program begins. The main thread is important for two reasons:

It is the thread from which other threads will be spawned. The main thread must be the
last thread to finish execution. When the main thread stop, the program stop.

Examples of creating Threads, by extending the Thread Class and by implementing


Runnable Interface

class Thread1 extends Thread


{
public static void main(String[] args)
{
Thread1 x= new Thread1();
x.start();
for (int i=0;i<500;i++)
{
System.out.println("Main="+i);
}
}

public void run()


{
for (int j=0;j<500;j++)
{
System.out.println("Run="+j);
}
}
}

class TestThread2 implements Runnable


{
public static void main(String[] args)
{
TestThread2 x2 = new TestThread2();
Thread t = new Thread(x2);

t.start();

for(int i=0;i<10;i++)
{
System.out.println("Main = "+i);
}

public void run()


{
for(int j=0;j<10;j++)
{
System.out.println("Run = "+j);
}
}
}

You might also like