You are on page 1of 295

Overview

Before we start with Object Oriented Features,


you should know...

 History of Java

 Features of Java

 J2SE, J2EE, J2ME

 Difference between Procedure oriented and Object


oriented languages (Also Object based language)

 JDK, JVM, JRE

 Java Bytecode
Things you should know...

 Octal and Hexadecimal representation of numbers.

 Unicode representation of characters (char).

 Naming conventions

 Arrays and its methods.

 Control statements and Iteration statements


- if - else (different forms)
- switch - case
- for loop
- while loop
- do while loop
- break, continue, label
- labeled break, labeled continue, return
Things you should know...
 Installing JDK, Setting path, compiling and running simple Java
Program.
 Whitespace, Comments
 Identifiers, keywords and Literals
 Data types
 Operators – (their precedence and associativity)
- Arithmetic
- Assignment
- Arithmetic-Assignment
- Relational
- Bitwise
- Boolean logical
- Short circuit logical
- Ternary
 Widening and narrowing conversions
Installing JDK

JDK stands for Java Development Kit.

A software development package from Sun Microsystems


that implements the basic set of tools needed to compile,
test and debug Java applications and applets.

It contains tools such as javac, java, appletviewer etc.

Set PATH in Environment Variable as -


<Drive-Name>\<JDK directory-name>\bin
e.g.: C:\Jdk1.4\bin
Execution cycle of ‘C’ Program

FirstProgram.c

FirstProgram.obj

FirstProgram.exe
Execution cycle of Java Program

Source file File in ByteCode format

Compiler (javac) converts


it into byteCode.
FirstProgram.java FirstProgram.class

JVM uses this for


execution.
Simplest Java Program

class FirstProgram
{
public static void main(String args[])
{
System.out.println("Hello World");
}
}

You can not write ‘C’ program without main().


Similarly, you can not write Java program without
“class”. We will study about “Class” in detail in
the subsequent lectures.
Compiling and running Java Program

Go to Command Prompt :
To compile the Java Program -
javac <FileName with Extension>
e.g:- javac FirstProgram.java

To run the Java Program -


java <ClassName>
e.g:- java FirstProgram

Initially keep FileName and ClassName same. Later


we will study about the correlation between
-FileName and ClassName.
Using EditPlus

You can use EditPlus to write and execute Java program.

You can also use EditPlus for programs in different


languages like – C, C++, HTML, JavaScript, VBScript, JSP,
Perl, PHP, CSS, XML, C#.

For this follow below instructions –

Tools --> Configure User Tools --> Add Tool

Initially always use Command Prompt to execute


Java programs. If you use EditPlus, then you tend
to forget syntax of javac and java commands.
Using EditPlus
Using EditPlus
WhiteSpace
ASCII space, horizontal tab or form feed and terminators are
considered as whitespaces.

Java is a free-form language. This means you need not follow


any indentation rules. You can even write an entire program on
one line, and still execute it successfully.

A Java program is a free-format sequence of characters that is


tokenized by the compiler (broken into a stream of tokens) for
further analysis.

White spaces help not only in separating tokens, but also in


formatting the program so that it is easy to read. The compiler
ignores the white spaces once the tokens are identified.

It is always a good practice to indent the program properly.


Identifiers
Identifiers are used for class names, method names and
variables names.

• It may be any descriptive sequence of characters (uppercase


and lowercase), numbers, _ (underscore) and dollar sign.

• They should not begin with numbers.


i.e.: A-Z, a-z, 0-9, _ , $

AvgTemp, count, a4, $test, _tmp Valid

2count, high-temp, Not/ok Invalid


Literals
A constant value in Java is created by using a literal
representation.

500 88.2 ‘S’ “Welcome”

Integer Floating-point Character String

Java also has escape sequences. Study various


characters escape sequences in Java.
Comments

/* This is traditional multi-line comment */


You can not have nested multi-line comments.

// Single line comment


These are single line comments.

/**
* This is JavaDoc comment.
*/
These comments are used for documentation purpose.
Keywords in Java

Apart from these 49 keywords, Java Language Specification


also has 3 reserved words - null, true, and false as literal
values (sometimes referred to as manifest constants) and not
keywords.
Remember: All the Java keywords are in lower-case.
You should know significance and usage of each of the keyword
in the above list.
You might be tempted to think - include, overload, unsigned,
virtual, friend - are Java keywords, but in fact they are not !!
Remember - "Java is not C / C++."

Will this compile?


class Foo
{
public int break(int b)
{
System.out.print(“break something”);
}
}
break is a reserved word and can not be
used as a method name.

class Foo
{
public int break(int b)
{
// code that appears to break something
}
}
Ranges of Primitive Data Type

Formula to determine data-type range: -2 (bits-1)


to +2 (bits-1)
-1
Default values of Primitive and Reference Data Types
Home Work

Study various Operators in Java, namely –

Arithmetic, Assignment, Arithmetic-Assignment, Relational,


Bitwise, Boolean logical, Short circuit logical, Ternary.
Look for numeric literals that include a comma, for example,
int x = 25,343; // Won't compile because of the comma

Remember this is Java and not C:


int x = 1; if (x) { } // Compiler error!
In Java, condition has to be boolean

int x =1;
while (x) { } // Won’t compile; x is not a boolean
while (x = 5) { }
//Won’t compile; resolves to 5 (result of assignment)
while (x == 5) { } // Legal, equality test
while (true) { } //Legal
Remember, characters are just 16-bit unsigned integers under the
hood. That means you can assign a number literal, assuming it will
fit into the unsigned 16-bit range (65535 or less).
For example, the following are all legal:
char a = 0x892; // octal literal
char b = 982; // int literal
char c = (char) 70000; // The cast is required; 70000 is out of
char range

char d = (char) -98; // Ridiculous, but legal 

And the following are not legal and produce compiler errors:
char e = -29; // Possible loss of precision; needs a cast
char f = 70000 // Possible loss of precision; needs a cast
Command Line Arguments
class TestMain
{
public static void main (String [] args)
{
System.out.println("First arg is :" + args[0]);
}
}

Unlike C++, + operator is overloaded by default, you need not write


any code for this.

When invoked at the command line as follows,


java TestMain Hello
the output is - First arg is : Hello
Command Line Arguments (continued...)

• args[0] is first argument supplied and not the program


name (Java is not ‘C’).

• The String array parameter does not have to be named args


or arg. It can be named anything (of course excluding
keywords and following variable declaration rules).
Remember that the main argument is just an array! There’s
nothing special about it, other than how it gets passed into
main (i.e. from the JVM).
What is wrong with this program?

int str = 2;
String i = “Hello”;
System.out.println(str);
System.out.println(i);
Arithmetic Operators

Operator Description
+ Addition
- Subtraction (also unary minus)
* Multiplication
/ Division
% Modulus
++ Increment (pre – post)
-- Decrement (pre - post)
+= Addition Assignment
-= Subtraction Assignment
*= Multiplication Assignment
/= Division Assignment
%= Modulus Assignment
Bitwise Operators
Operator Description
~ Unary NOT
& AND
| OR
^ X-OR
>> Right Shift
>>> Right Shift Zero fill
<< Left Shift
&= AND assignment
|= OR assignment
^= X-OR assignment
>>= Right Shift assignment
>>>= Right Shift Zero fill assignment
<<= Left Shift assignment
Relational Operators

Operator Description
== Equal to (Equality)
!= Not Equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
Boolean Logical Operators

Operator Description
& Logical AND
| Logical OR
^ Logical X-OR
|| Short-circuit OR
&& Short-circuit AND
! Logical NOT
?: Ternary
Coffee Cram

• Can we have different Java Source file name and Class Name ?
If yes, then how to compile and run the program?

• If we do not provide command-line arguments in main()


method, then will the String array args[] be empty or null ?

• What will be the output of: 5/0, -5/0, 5%0, 5.0/0,


5.0%0 ?

• What will be the output of –


System.out.println(1+2+“3”);
System.out.println(“1”+2+3);
System.out.println(“1”+2+“3”);
System.out.println(“ ”+2+3);
Coffee Cram

Find the Output -

byte b1 = 2;
byte b2 = 3;
byte b3 = b1+b2;
System.out.println(b3);

byte b1 = 2;
byte b2 = 3;
b1+=b2;
System.out.println(b1);
Widening and Narrowing Conversions

byte short int long


8 16 32 64

The compiler won’t let you put a value from a large cup into
a small one.

But what about the other way round - Pouring contents of


small cup into a big one? No Problem !!
Widening and Narrowing Conversions

• Converting from a broader data type to a narrower one is


called as narrowing primitive conversion.
• Explicit typecast is required.
• This can result in loss of precision.

• Converting from narrower data type to broader one is


called as widening primitive conversion.
• This is automatic.
• There is no loss of precision.
Automatic Widening Conversions

All the conversions between char, byte and short are


considered as narrowing conversions. So they can
result in loss of precision.
Unary and Binary Numeric Promotions

Unary numeric promotion


• If the single operand of the operator has a type narrower than
int, it is converted to int by an implicit widening primitive
conversion; otherwise, it is not converted.

Binary numeric promotion


Binary numeric promotion implicitly applies appropriate widening
primitive conversions so that a pair of operands have the broadest
numeric type of the two (which is always at least int).
Given T to be the broadest numeric type of the two operands, the
operands are promoted as follows :-
• If T is broader than int, both operands are converted to T;
otherwise, both operands are converted to int.
Object Oriented
Features
Object Oriented Features
1. Abstraction
• Essential element of an object oriented programming.

• You can manage complexity thorough an abstraction.

• Consider Car as an object. You do not think of a car as set


of thousand individual parts (or sub-systems - like brakes,
engine, clutch, gears etc…) rather it is well defined object
having unique behavior.

• With abstraction you can drive the car ignoring the details
of how the engine, transmission and braking system works.
Instead you are free to use the ‘Car’ object as a whole.
1. Encapsulation

• Mechanism that binds


together the code and
data it manipulates, and
keeps both safe from
outside interference and
misuse.

• In Java, basis of an encapsulation is the Class. It is a


protective wrapper around the code and data.

• Encapsulation can be achieved, using appropriate access


modifiers. Like private variables cannot be accessed from
outside the class.

• Encapsulation is necessary for Data Security and Integrity.


class Student
{
private int age;
private String name;

public int getAge() { return age; }


public void setAge (int a)
{ /* Validations here… */
age = a; }

public String getName() { return name; }


public void setName(String str)
{
/* Validations here… */
name = str; }
}
3. Inheritance Vehicle

IS – A 2 Wheeler 3 Wheeler 4 Wheeler


relationship

Bike Scooter

• Inheritance is the process by which one object acquires


the properties of another object. Thus in a class
hierarchy, two classes are formed - superclass and a
subclass.

• The class whose properties are inherited is known as


Superclass. And the class who does the inheritance is
known as subclass.
Containment Hierarchy - Aggregation

• In Has-A relationship, composite object is built from


other constituent objects that are its parts.

• One object contains reference to the other object.

Engine Chassis Steering Wheel

Has – A relationship
4. Polymorphism

• Polymorphism (In Greek – Poly means many and morphos


means forms) is the ability of different objects to respond
to the same message in different ways.

• Polymorphism helps us to design extensible software as


we can add new objects to the design without rewriting
existing procedures.

• Polymorphism in Java is achieved by Overloading and


Overriding.
Move ( )

Move ( )

Move ( )

Move ( )
Invoking move() method on
different objects, would
produce different results
differing in speed.
Polymorphism : How is it useful ?

name
Shape getName( )
calculateArea( )

radius Circle Square side


calculateArea( ) calculateArea( )

Adding new class becomes easy with inheritance and


polymorphism
name
Shape getName( )
calculateArea( )

base
Circle Square Triangle height
calculateArea( )
Benefits of Object Oriented Approach

Object oriented approach helps –

- To handle the complexity of software development


through Abstraction.

- In generation of Extensible Systems.

- To avoid duplicate code. Use of Inheritance allows us to


put common code in one place, and let the subclasses inherit
that code from a superclass. This allows us to define a
common protocol for a group of classes.
Classes & Objects
Classes & Objects
 Class forms the basis of object oriented programming.

 You can not write a Java program without Class.

 Class defines a new data type. Something similar to


structure in ‘C’.

 Class is a template (or blueprint) for an object and


Object is an instance of the Class.

 The words Object and Instance are often used


interchangeably.

 An object can be a tangible, intangible or a conceptual


entity.
Classes & Objects (continued…)

 A Class denotes a category of objects, and acts as a


blueprint for creating such objects.

 A class defines the properties and behaviors for the


objects.

 The properties are also called attributes, and are


defined by fields in a class.

 The behaviors are also known as operations, and are


defined using methods in a class.
Characteristics of an Object

 State
- The state of an object encompasses the current values
of all its attributes. An attribute can be static or
dynamic.

 Behavior
- Behavior is how an object acts or reacts, in terms of its
state changes and operations performed upon it.

 Identity
- Identity is that property of an object which uniquely
identifies the object.
State of an Object

Car Attributes

Color
Average
Make Static
Power
Fuel type

Values of all attributes


Speed
at any moment defines
Fuel level
Dynamic the state of the car object
Tyre pressure
Gear
Window Attributes Behavior of an Object
height
width
position
.
.
.

Window Operations

Open
Close
Maximize Total number of operations that can be
Minimize performed upon a window object and
Resize consequent changes in its state
Move defines behavior of an object
Identity of an Object

Bank Account
Account Number Identity
Balance
Interest Rate
Customer Name

Account number attribute uniquely identifies an account.

A single or group of attributes can be identity of an object.


General form of Class definition:
class classname
{
datatype instance-variable1;
datatype instance-variable2;
.
datatype methodname1(parameter-list)
{
// method body
}

datatype methodname2(parameter-list)
{
// method body
}
}
Data or variables, defined within a class are called instance
variables. Variables and methods are called as members of class.
Thus the structure and behavior of an object is defined in a class.
class Student
{
int rollNo;
String name; instance variables
String course;
}
The class declaration only creates a template; it does not
create the actual object.

To create the actual object(instance) of this class, you


need to write a statement like :

Student objStudent = new Student(); // Constructor


 Now objStudent is an object (instance) of the class
Student. Thus it will have some physical reality.

 Each time you create an instance of this class, you are


creating an object that contains its own copy of
instance variables namely - rollNo, name, course

 To access these variables you use . (Dot) operator


objStudent.rollNo = 001;
objStudent.name = “ABC”;
objStudent.course = “MCM”;
Declaring Objects
 Creating objects of the class is a two step process: -

Step 1 – You must declare a variable of the class type. This


is called as a reference variable and it is not the actual
object.

Step 2 – You must acquire a physical, actual copy of that


object. For this you use new operator.

 new operator dynamically (at run-time) allocates memory


for an object and returns a reference to it. This reference
has to be stored in the reference variable.

Student objStudent = new Student();


1. Student objStudent;

reference variable Actual Object


objStudent null

2. objStudent = new Student();

rollNo
objStudent name
course

Stack memory Heap memory


 There is nothing called Object Variable. There is only an
Object reference variable or simply – reference variable.

 Reference variable is not the object itself.

 Use of (.) DOT operator on this reference variable, is


similar to pressing a button on the remote control to access
the actual object (TV).

reference variable Actual Object


Structure of memory

Stack Area Local / reference variables

Movable Boundary
Dynamically allocated Area
Heap Area
(Objects)

Fixed Boundary Data Area Static And Global Variables

Code Section
Student objStudent1 = new Student();

Student objStudent2 = new Student();

rollNo
objStudent1 name
course

rollNo
objStudent2 name
course

reference variable Actual Object


Student objStudent1 = new Student();

Student objStudent2 = objStudent1;

objStudent1
rollNo
name
course
objStudent2

reference variable Actual Object


 Although objstudent1 and objstudent2 refer to the
same object, they are not linked to each other in anyway.

objstudent1 = null;

Here objstudent1 is set to null but objstudent2 still


refers to the actual object created previously.

objStudent1 null

rollNo

objStudent2 name
course

reference variable Actual Object


When you assign one object reference variable to
another object reference variable, you are not
creating a copy of the object; you are making a copy
of the reference.

You may see the words construct, create, and


instantiate used interchangeably. They all mean –
“An object has been built and placed on the heap.”
Classes & Objects
Methods
• Introduction of methods give Java power and flexibility.
datatype methodname1(parameter-list)
{
// method body
}

• datatype specifies the type of data returned by the method.


This can be any valid types including class types. If method
does not return any value, return type is void.
• methodname must be a legal identifier other than those
already declared for other items within the current scope.
• paramter-list is the sequence of type and identifier pairs
separated by commas. If no parameters are present, paramter-
list can be empty.
• Methods having return type other than void, must have a
return statement to return a value. (Can void method have a
return statement ?)
Actual Arguments / Formal Parameters

You might be using the words arguments and parameters


interchangeably, but formal Computer Science makes a
distinction between them.

Method uses parameters, A caller passes arguments.

Arguments are the things you pass into the methods. And
parameters are nothing but local variables for that method.

Actual arguments are the values you pass while invoking a


method.

Formal Parameters are local variables of that method.


A closer look at Argument passing
There are two ways in which, computer language can pass
an argument to a subroutine (function / method).
- Call by value :– This copies the value of an argument
into formal parameter of the subroutine. So changes
made to the parameters of the subroutine have no
effect on the arguments used to call it.
e.g. primitive data types as arguments.

- Call by reference :- Reference to an argument (not


the value of argument) is passed to the parameter.
Inside the subroutine, this reference is used to access
the actual argument. This means changes made to the
parameters will affect the arguments used to call it.
e.g. Object types as arguments.
Recursion

• Java supports recursion.

• Recursion is the process of defining something in terms


of itself.

• Recursion allows a method to call itself. Such a method


which calls itself is said to be a recursive method.

• Classic example of recursion is to compute factorial of a


number.
new operator
New operator dynamically allocates the memory for an object and
returns a reference to it.
Syntax: -

Student s = new Student( );


s = reference variable.
new Student( ) = Actual object.

It calls for the parameter-less constructor of the class Student,


if the constructor is explicitly created; otherwise Java creates
it’s own constructor, which is called as a default constructor.
new operator allocates memory for an object at run-time. This
allows a program to create as many as objects needed during its
execution. However, since memory is finite, it is possible that new
operator will not be able to allocate memory for an object because
of the insufficient memory. In such case, program will generate
run-time exception.
Constructor

• Constructor is used to initialize an object immediately


after it is created. (Before new operator completes)

• Constructor is used to, initialize the instance variables.

• It has the same name as that of the class in which it


resides.

• It is syntactically similar to a method.

• Constructor has no return type, not even void. Implicit


return type of constructor is the class type itself.
Constructor (continued…)
• If you do not define a constructor explicitly, the compiler
will create default, parameter-less constructor.

• The default constructor is the constructor provided by


the system in the absence of any constructor provided by
the programmer. Once a programmer supplies any
constructor whatsoever, the default constructor is no
longer supplied by the system.

• A no-argument (parameter-less) constructor, on the other


hand, is a constructor provided by the programmer which
takes no arguments.

The default constructor is always no-argument


(parameter-less) constructor.
Parameter-less Constructor
class Student
{
int rollNo;
String name; instance variables
String course;
Student()
{
rollNo = 001;
name = “ABC”;
course = “MCM”;
}
}
Parameterized Constructor
class Student
{
int rollNo;
String name;
String course;
Student(int rollNo, String name, String course)
{
rollNo = rollNo;
name = name;
course = course;
}
}
Student objStudent1 = new Student(1,“ABC”,“MCM”);
Student objStudent2 = new Student(2,“PQR”,“MCM”);

‘this’ keyword

• ‘this’ keyword can be used inside any method to refer to


the current object.
• ‘this’ is always reference to the object on which the
method was invoked.
• When local variable has the same name as that of the
instance variable, it hides the instance variable. But use of
‘this’ lets you resolve any “namespace collisions” that might
occur between instance and local variables.
class Student
{
int rollNo;
String name;
String course;
Student(int rollNo, String name, String course)
{
this.rollNo = rollNo;
this.name = name;
this.course = course;
}
}
Coffee Cram

• We studied - what is Class and what is an Object.


To confuse you even more, Java has 2 classes namely – Class
and Object   Find out more information about them.

• Can we have a same name for -


- Constructor and a method.
- Class and a method.
Will it cause any error in the program?

Continued…
Coffee Cram

• Can we define local variables (inside a method) with the same


name as an instance variables?

• Can we declare method with signature –


void MyMethod(void)
Inheritance
&
Polymorphism
Inheritance

• Inheritance is one of the important features of object


oriented programming.
• It allows creation of hierarchical classifications.
• It involves Generalization and Specialization.
• Generalization is creation of general class that defines
attributes that are common to set of related classes.
•This generalized class is then inherited by other, more
specific classes, each adding attributes unique to it.
• In Java terminology, class that is inherited is called as a
superclass (parent) and class that does the inheriting is
called as a subclass (child).
• Subclass is a specialized version of superclass, thus
inherits all of the instance variables and methods defined
in superclass and also adds its own unique variables and
methods.

UML notation for Inheritance


Keyword extends is used to specify use of inheritance –

class A
{
int i=10,j=20;
void printij()
{
System.out.println(“i=”+ i+ “j=”+ j);
}
}

class B extends A
{
int k=30;
void printk()
{
System.out.println(“k=”+ k);
}
}
Multilevel Inheritance

• Multilevel Inheritance – You can create an hierarchy


that can contain as many inheritance levels as you want.
e.g. Given classes – A, B, C, D, where D is subclass of C,
which is a subclass of B, which is a subclass of A.
• In such a situation each subclass inherits attributes of
all of its superclasses.
A

D
Multiple Inheritance

• Multiple Inheritance – Here a subclass inherits attributes


from more than 1 superclass.
• Java does not support multiple inheritance through classes.
It supports multiple inheritance through interfaces (we will
see this later)

Father Mother

Child
Superclass reference can refer to Subclass Object

• Superclass reference can refer to Subclass object.


• It is important to understand it is type of the reference
variable – not the type of the object it refers to - that
determines what members can be accessed.
• When a Superclass reference refers to the subclass
object, it can access only those parts of the object defined
by the superclass.
• This is because the superclass has no knowledge of what a
subclass adds to it.

Remember – Subclass reference can not refer to


Superclass object.
Using ‘Super’

• Super is used to invoke the super class constructor,


method or variable from sub class.

• Super must be the first statement in the sub class’


constructor or method.

• In the class hierarchy, the constructors are called in the


order of derivation, from super class to sub class.

• As super is the first statement during the class, the


order will be same whether or not super is used.

• If super is not used, then default parameter-less


constructor of each super class will be executed.
Second use of ‘Super’

• Second form of ‘Super’ is used to refer to superclass


members.

General form :
super.member
member could be a suerclass method or a variable.

• This form of super is most applicable to situations in


which member names of a subclass hide members by the
same name in superclass.
superclass
Inheritance
&
Polymorphism
Overloading

Method overloading is one of the ways in which Java


implements Static Polymorphism.

In Java, it is possible to overload two or more methods,


only if below statements are true: -
• The methods should have different parameters.
• The methods may or may not have different return
type.
• Methods should have same name.
• All the methods should be in the same scope (i.e.
Within the same class, or parent and child class.)
When an overloaded method is invoked, java uses the type
and / or number of arguments (parameters) to decide which
version of the overloaded method to call.

However, return type alone is insufficient to decide which


method is to be called.

If, parameters passed satisfy more than one overloaded


versions, then most specific method version is called.

Just like methods, Constructors can also be overloaded.


overloaded
this():

It can be used to call one constructor from the other. The


number of parameters, determines which constructor should
be called.
this() must be the first statement in the constructor.

Remember – this() and super() can not be in the


same constructor.
class MyClass
{
MyClass()
{
System.out.println(“Parameter-less”);
}
MyClass(int a, int b)
{
this(); // It will call parameter-less constructor
System.out.println(“2 Parameter”);
}
MyClass(int a, int b, int c)
{
this(a, b); // It will call 2 parameter constructor
System.out.println(“3 Parameter”);
}
}
Overriding

Method overriding is the way in which java implements


Dynamic Polymorphism.

• Method in a sub class should have same name and


signature (return type and arguments) as the method in the
super class.
• When an overridden method is called within the sub class,
it will always refer to the version of that method defined
by the subclass. The version of the method defined by the
super class will be hidden.
• Method overriding occurs only when names and type
signature of two methods are exactly identical otherwise
two methods are simply overloaded not overridden.
• Constructors can not be inherited or overridden.
More about Overriding...

• The new method which does the overridding, can not


narrow the accessibility of the method but can widen it.

• The new method which does the overridding, can only


specify all or none or subset of exception classes (checked
exceptions only) specified in the throws clause of the
overridden method in the superclass.

We shall study - ‘Accessibility’ and ‘Exceptions’ later,


but as of now just make a note of it.
class A // Super class
{
void disp( )
{
System.out.println(“U R in class A”)
}
}

class B extends A //Sub class


{

void disp( )
{
System.out.println(“U R in class B”) // output
}
}

class Main
{
public static void main(String args[])
{
B b = new B();
b.disp();
}
}
Call to an overridden method is resolved at run-time, rather
than at compile time.

This is known as Dynamic Method Dispatch (Dynamic


Polymorphism)

We will study Dynamic Method Dispatch in the next lecture.


Coffee Cram

1. You have two overloaded methods -


void print(long l) and
void print(int i)
and you pass a value 3 as a parameter.
Which method version will be executed? And Why?
Coffee Cram

Try out the same program with different method


combinations and pass arguments as – 3, 2.5 and number out
of range.
void print(byte b) and void print(int i)
void print(byte b) and void print(short s)
void print(long l) and void print(short s)
void print(long l) and void print(double d)
void print(float f) and void print(int i)
void print(float f) and void print(double d)

Try as many combinations as you can and


note down the results.
Inheritance
&
Polymorphism
Dynamic Method Dispatch

In dynamic method dispatch, call to an overridden method


is resolved at run-time, rather than at compile time.

It is also called as run-time polymorphism or late binding.

Super class reference variable can hold sub class object.


(Parent can hold child’s object).

When an overridden method is called through a super class


reference, Java determines which version of that method
to execute based upon the type of the object being
referred.

The type of object being referred to (Not the type of


reference variable) determines which version of method to
be called.
class Main
{
public static void main(String args[])
{
A obj = new B();
obj.disp();
}
}
A obj Type of reference variable.

new B( ) The type of actual object being referred to.


SuperType and SubType

• A subclass is a specialization of its superclass ⇒ every


instance of the subclass is an instance of the superclass

Shape Shape

Circle Square

Circle Square

• The type defined by the subclass is a subtype of the type


defined by its superclass.
Upcasting and Downcasting

Upcasting

A subclass reference can be assigned to superclass


reference because, subclass object can be used where a
superclass object is used. This is called as upcasting, as
references are assigned up the inheritance hierarchy.

Upcasting is automatic. You need not use explicit typecast.

A obj_a = new A();


B obj_b = new B();
A obj = obj_b;
Downcasting

Casting the references of superclass type to subclass type is


called as downcasting, as references are assigned down the
inheritance hierarchy.

Downcasting is not automatic. You should use explicit typecast.


Compiler verifies that an inheritance relationship exists
between the source and destination reference types.

However, cast can be invalid at runtime. In such a case,


ClassCastException is thrown.

A obj_a = new B(); A obj_a = new A();


B obj_b = new B(); B obj_b = new B();
B b = (B)obj_a; B b = (B)obj_a;
instanceof operator

instanceof operator has the following syntax :

<reference> instanceof <destination-type>

instanceof operator returns true if the left-hand operand


(reference) can be cast to right-hand operand (destination-
type), but always returns false if the left-hand operand is
null.
if instanceof operator returns true, then the corresponding
cast will always be valid.
if instanceof operator returns false, then the cast involving
the operands will throw ClassCastException.
Which makes sense and is Legal ?
Exam e; PracticeExam pe;
e = new PracticeExam(); pe = new Exam();
• Automatic Promotion
Cat c = new Cat();
Animal a = c;

• Explicit cast required:


Animal c = new Cat();
Cat c = (Cat) a;

• Will not compile:


Cat c = new Cat();
Dog d = (Dog) c;
Access Modifiers
Access modifiers

• static
• final

• abstract (we will see this later)


• synchronized (will see this when we study Threads)

• native

• transient
• volatile
Understanding Static

Instance members (methods or variables) are used in


conjunction with an object of the class. However, it is
possible to create a member that can be used by itself,
without reference to a specific instance.

When, member is declared as static, it can be accessed,


before any objects of that class are created.

Both methods and variables can be declared as static.

main () method is static because it is called before any


object exists.
Static Variables
• Variables are declared as static essentially global
variables.
• When objects of its class are declared, no copy of static
variables is made. Instead, all instances of the class share
the same static variables.
• All the static variables are initialized to their default
values.

Static Methods

• They can call only other static methods.


• They must access only static data.
• They cannot refer to super or this.
Static method can be invoked in two ways:
Thread t = new Thread();
1. Class.methodname (); e.g. Thread.sleep(100);
2. object.methodname (); e.g. t.sleep(100);

Non-Static method can be invoked only through the object


reference:
• object.methodname(); e.g. t.join();

Static methods cannot be overridden, although


they can be re-declared / redefined by a
subclass. So even though static methods can
sometimes appear to be overridden,
polymorphism rules do not apply. Type of a
reference variable decides the method call.
Understanding Final
The keyword final has 3 uses - final variable, final method
and final class
Final variable
• It is equivalent to a named constant.
• It must be initialized during the declaration.
• It cannot be re-initialized.
• According to the convention such variables are written in
capital letters.
• Blank final variable can be only declared and not initialized,
but should be assigned a value either in the constructor or
initializer block.
E.g.:
final int A=30; (Correct)

A=20; //Cannot be re-initialized


final int A; // Must be initialized during the declaration
Final method

• Final method cannot be overridden.


• Final method can be overloaded.
• Since final methods are not overridden, call to such
methods is resolved at compile time (Early binding)

Final class

• Final class cannot be inherited.


• Final class can be instantiated.
• Declaring a class as final implicitly declares all its
methods as final too.
native

• Native methods are also called as foreign methods.

• Their implementation is not defined in Java but in


another programming language, for example, C or C++.

• Since its implementation appears elsewhere, only the


method prototype is specified in the class definition. The
method prototype is prefixed with the keyword native.

• The Java Native Interface (JNI) is a special API that


allows Java methods to invoke native functions
implemented in C.

• Method should end with a semicolon. No opening-closing


braces.
class Native {
/*
* The static block ensures that the native method library
* is loaded before the native method is called. JNI calls this.
*/
static {
System.loadLibrary("NativeMethodLib");
// (1) Load native library.
}
native void nativeMethod(); // (2) Native method prototype.
// ...
}
class Client {
//...
public static void main(String[] args)
{
Native aNative = new Native();
aNative.nativeMethod(); // (3) Native method call.
}
//...
}
transient

• Objects can be stored using serialization.

• Serialization transforms objects into an output format


that is helpful for storing objects. Objects can later be
retrieved in the same state as when they were serialized,
meaning that all fields included in the serialization will
have the same values as at the time of serialization. Such
objects are said to be persistent.

• A field can be specified as transient in the class


declaration, indicating that its value should not be saved
when objects of the class are written to persistent
storage.
Why would you need to mark a variable as Transient?

• Object may not be serializable. Does not implement


Serializable interface.

• Object may be relying upon some run-time specific


information, so can not be saved.

• Though most of the things in Java are serializable; you


can not save things like - network connections, file objects
and threads. Because they all are instantiated in a way
that it unique to particular JVM.
volatile

• During execution, compiled code might cache the values of


fields for efficiency reasons.

• Since multiple threads can access the same field, it is vital


that caching is not allowed to cause inconsistencies when
reading and writing the value in the field.

• The volatile modifier can be used to inform the compiler


that it should not attempt to perform optimizations on the
field, which could cause unpredictable results when the
field is accessed by multiple threads.
Relax

You should only be aware of the modifiers namely –
native, transient and volatile.

Now as far MCM syllabus is concerned, you


may not need to try this out practically.

But understanding the significance of these modifiers


is important from exam point of view.
Coffee Cram

• Can we overload a main() method? Which version of main


method gets invoked?
• Can we declare main() method as final ?
• Can static methods be overridden?
• Can static methods be overloaded?
• Can we have local variables declared as static?
• What if static modifier is removed
from main() method?
Packages
Packages
• Packages are containers that allow compartmentalization
of classes.
• Packages are a named collection of classes grouped in a
directory.
• Packages are a way of grouping related classes &
interfaces.
• A package can contain any number of classes that are
related in purpose, in scope or by inheritance.
• Convenient for organizing your work & separating your
work from code libraries provided by others.
• You can create you own package and store classes inside it
without concern that it will collide with some other class
with the same name. (That is to avoid name space collision)
Java Source file structure

Part I – Package Statement


(Optional)

Part II – Import Statements


(Zero or More)

Part III – Definitions of


classes or interfaces
(Zero or More)
Steps for creating a package

• Use keyword package at the beginning of the file.

• Create a directory of that package name.

• Compile the file and keep the .class files in this directory.

• Set the classpath from the root up to the directory


created above.

• Use the import keyword whenever the class in the


particular package has to be used.
How compiler locates a Java File ?

• Check current directory.


• Compiler looks through all directories specified in the
classpath for
- The actual class file.
OR
- The subdirectory that has the name of the imported
package.
• Then, looks for the file in one of the imported packages.
• Finally looks for file in java.lang package.
• If compiler still does not locate the file, it gives an error.
ClassPath

• Specific location that Java compiler will consider as the


root of any package hierarchy is controlled by CLASSPATH.

• If you don’t specify package name, current working


directory (.) is taken by default in the CLASSPATH variable
defined by Java run-time environment.

• If you store a class named TestClass in a package named


testpack, you should access that class as testpack.TestClass.
Or, change CLASSPATH variable.

• If you are working on your source code in a directory named


C:\myjava then set your CLASSPATH to:

set CLASSPATH= “. ; C:\myjava ; C:\java\classes”


package p1;
Class A
{
...
}

package p1;
class B extends A
{
...
}

package p2;
Class C extends p1.B
{
...
}
Importing packages
• Java includes the import statement to bring certain classes,
or entire packages into visibility.

• Once imported a class can be referred directly, using only


its name.

• Either specified class from a particular package can be


accessed or asterisk (*) can be used to import all the classes
from that package. But this does not recursively import sub-
packages.
E.g:
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
If you use * notation for import, rather than importing
specific classes that are required, will that affect
compile-time and run-time performance of the program ?

When you use * notation, it increases the compilation


time, because it includes all the classes from that
package. Hence it is a good idea to mention specific class
names. However asterisk (*) notation, has absolutely no
effect on run-time performance.
Access Modifiers

Public Private No Protected


     
Modifier  
Same class

     
 
Same Package
Sub - class   
       
Same Package
Non - Sub class   
       
Different Package
Sub - class  
       
Different Package
Non - Sub class 

*** Never forget this chart !!


Method overriding and access modifiers

• The new method which does the overridding, can not


narrow the accessibility of the method but can widen it.

• The new method which does the overridding, can only


specify all or none or subset of exception classes (checked
exceptions only) specified in the throws clause of the
overridden method in the superclass.

We shall study ‘Exceptions’ later, but as of now just


make a note of it. 
You need to know the effect of different combinations of
class and member access (such as a default class with a
public variable).

To figure this out, first look at the access level of the


class. If the class itself will not be visible to another class,
then none of the members will be either, even if the
member is declared public.

Once you’ve confirmed that the class is visible, then it


makes sense to look at access levels on individual members.
Coffee Cram

• Can we declare main() method as private ?

2. What if main() method is written as


static public void main(String args[]) instead of
public static void main(String args[])

3. Can we import same package /class twice? Will


the JVM load that package / class twice?

4. Are the imports checked for validity at compile


time? E.g. Will the code containing an import such as
java.lang.ABCD compile?

Continued…
Coffee Cram

• Can we have more than one public class in Java source


file ?

• Can we apply these access modifiers (private,


protected, public) to Classes and constructors?

• Can we have multiple classes in the same Java source


file? Are package and import statements applicable to
all the classes in that source file?

• Would there be any situation where we need to use fully


qualified class names rather than importing packages
/classes?
Abstract Classes
and Interfaces
What does a new Animal() object look like?
Some classes should not be instantiated.
instantiated If you
instantiate new Animal() object, what does that mean?

Animal

Lion Elephant

What exactly is an animal object? What shape is it? What


color is it? What size is it?
Instantiating Animal class has virtually no use, no meaning,
no purpose, unless it is extended.
extended
Abstract methods

• Abstract methods have no implementation specified.

• These methods are declared with a prefix abstract.

• It is required that these methods must be overridden by a


sub class.

• Otherwise sub class must also be declared as an abstract.

Syntax:- abstract type-name (parameter-list);


// no body present.
Abstract class
• Any class that contains one or more abstract methods
must also be declared abstract.
• To declare a class abstract, abstract keyword is used
before the class keyword at the beginning of the class
declaration.
• Abstract class cannot be instantiated with the new
operator because an abstract class is not fully defined.
• Abstract class can be inherited.
• Abstract constructors or abstract static methods
cannot be declared.
• Abstract class can have abstract or fully implemented
methods.
It really sucks to be
an abstract method.
You don’t have a
body.

Remember : Abstract method has no


body. The method declaration ends
with a semicolon.
Can a class be declared as abstract and final ?

It is illegal to declare a class as both final and


abstract

An abstract class is incomplete by itself and relies upon


its sub classes to provide complete implementations. And
abstract class cannot be instantiated.

Where as, final class cannot be inherited but can be


instantiated.

The compiler, gives compile time error if an attempt is


made to declare a class as both abstract and final.
Interface

• Using Inheritance, subclass can inherit the code from its


superclass.

• But class can not extend more than once class. Java does
not support multiple class inheritance.

• The OO language like C++ supports multiple inheritance at


the cost of added complexity and ambiguity at times.

• Java supports a single chain of implementation inheritance.

• To overcome the lack of multiple inheritance Java uses


Multiple Inheritance using Interfaces.
Interface (continued…)

• An Interface is essentially a collection of constants &


abstract methods.

• Using an interface, you can specify what a class should do


but not how it does it. Interfaces are similar to abstract
classes but they do not have any instance variables.

• Interface methods are declared without any body.

• Once defined, any number of classes can implement that


interface. Also, a class can implement any number of
interfaces.

• Interface can not be instantiated. However, reference


variables of interface type can be created.
Interface (continued…)

Syntax:
access interface name
{
return-type method1 (paramter-list);
return-type method2 (paramter-list);
type final-varname1 = value;
type final-varname2 = value;
}

access: Either public or not used.


interface: Keyword to declare an interface.
name: Name of the interface.
Interface (continued…)

• Interface methods have no bodies. They end with a


semicolon.

• They are essentially abstract methods. Each class that


implements an interface i.e. subclass must override these
methods and add some functionality to it.

• Variables can be defined inside an interface, which are


implicitly final and static.

• In an interface, all the methods must be public and


abstract. (Never static)

• When class inherits an interface, the keyword


implements should be used. But when one interface inherits
the other, the keyword extends is used.
Interface Methods
• void bounce();
• public void bounce();
• abstract void bounce();
• public abstract void bounce();
• abstract public void bounce();

• final void bounce(); // final and abstract can never be used


• static void bounce(); // interfaces define instance methods
• private void bounce(); // interface methods are always public
• protected void bounce(); // (same as above)
• synchronized void bounce(); // can’t mix abstract and synchronized
• native void bounce(); // can’t mix abstract and native
Interface Variables

• public int x = 1; // Looks non-static and non-final, but isn’t!


• int x = 1; // Looks default, non-final, and non-static, but isn’t!
• static int x = 1; // Doesn’t show final or public
• final int x = 1; // Doesn’t show static or public
• public static int x = 1; // Doesn’t show final
• public final int x = 1; // Doesn’t show static
• static final int x = 1 // Doesn’t show public
• public static final int x = 1; // Exactly what you get implicitly
Classes & Interfaces

• class Foo { } // OK

• class Bar implements Foo { } // No! Can’t implement a class

• interface Baz { } // OK

• interface Fi { } // OK

• interface Fee implements Baz { }


// No! Interface can’t implement an interface

• interface Zee implements Foo { }


// No! Interface can’t implement a class
Classes & Interfaces

• interface Zoo extends Foo { }


// No! Interface can’t extend a class

• interface Boo extends Fi { }


// OK. Interface can extend an interface

• class Toon extends Foo, Button { }


// No! Class can’t extend multiple classes

• class Zoom implements Fi, Fee { }


// OK. class can implement multiple interfaces

• interface Vroom extends Fi, Fee { }


// OK. interface can extend multiple interfaces
Coffee Cram

• Can Abstract classes have constructors ? Can they be


called using super() ?

• Can an interface have constructors?

• Can an interface be defined as abstract?


e.g. abstract interface MyInterface{}

• Can abstract method be declared as private?

• Can an abstract class implement an interface?


Initializer
Blocks
Initializer blocks

Initializers means initialization of fields in the classes.


i.e. fields being assigned initial values.

These initializers are -

• field initializer expressions


• static initializer blocks
• instance initializer blocks
field initializer
• Initialization of fields can be explicitly specified in field
declaration statements using initializer expressions. The value of
the initializer expression must be assignment compatible to the
declared field.
class ConstantInitializers {
int minAge = 12; // Non-static
static double pensionPoints = 10.5; // (2) Static
// ...
}
• Since a class is always initialized before it can be instantiated,
an instance initializer expression can always refer to any static
member of a class, regardless of the member declaration order.
Forward reference in the following code is perfectly legal.
class MoreInitializers {
int noOfDays = 7 * NO_OF_WEEKS; // (1) Non-static
static int NO_OF_WEEKS = 52; // (2) Static
// ...
}
• Java requires that the declaration of a field must occur before
its usage in any initializer expression, if the field is used on the
right-hand side of an assignment in the initializer expression.

• This essentially means that the declaration of a field must occur


before the value of the field is read in an initializer expression.
Using the field on the left-hand side of an assignment in the
initializer expression does not violate the declaration-before-read
rule,
rule as this constitutes a write operation.
class NonStaticInitializers {
int length = 10;
double area = length * width;
// Not Ok. Illegal forward reference.

double area = length * this.width;


// Ok, but width has default value 0.

int width = 10;


int sqSide = height = 20; // OK. Legal forward reference.
int height;
}
Static initializer

• Java allows static initializer blocks to be defined in a class.


Although such blocks can include arbitrary code, they are
primarily used for initializing static fields. The code in a static
initializer block is executed once only when the class is
initialized.

• Note that the static initializer block is not contained in any


method. A class can have more than one static initializer block.
Initializer blocks are not members of a class, nor can they have
a return statement, as they cannot be called directly.

• When a class is initialized, the initializer expressions in static


field declarations and static initializer blocks are executed in
the order they are specified in the class.

• Executed before main() method.


class StaticForwardReferences {

static { // (1) Static initializer block


sf1 = 10; // (2) OK. Assignment to sf1 allowed
sf1 = if1; // (3) Not OK. Non-static field access in static context
int a = 2 * sf1; // (4) Not OK. Read operation before declaration
int b = sf1 = 20; // (5) OK. Assignment to sf1 allowed
int c = StaticForwardReferences.sf1;// (6) OK. Not accessed by simple name
}

static int sf1 = sf2 = 30; // (7) Static field. Assignment to sf2 allowed
static int sf2; // (8) Static field
int if1 = 5; // (9) Non-static field

static { // (10) Static initializer block


int d = 2 * sf1; // (11) OK. Read operation after declaration
int e = sf1 = 50; // (12)
}

public static void main(String[] args) {


System.out.println("sf1: " + StaticForwardReferences.sf1);
System.out.println("sf2: " + StaticForwardReferences.sf2);
}
}
Instance initializer

• The code in the local block is executed every time an instance


of the class is created.

• instance initializer block is not contained in any method. A


class can have more than one instance initializer block, and
these (and any instance initializer expressions in instance field
declarations) are executed in the order they are specified in
the class.

• instance initializer block cannot make a forward reference to


a field that violates the declaration-before-read rule.
class NonStaticForwardReferences {

{ // (1) Instance initializer block


nsf1 = 10; // (2) OK. Assignment to nsf1 allowed
nsf1 = sf1; // (3) OK. Static field access in non-static context
int a = 2 * nsf1; // (4) Not OK. Read operation before declaration
int b = nsf1 = 20; // (5) OK. Assignment to nsf1 allowed
int c = this.nsf1; // (6) OK. Not accessed by simple name
}

int nsf1 = nsf2 = 30; // (7) Non-static field. Assignment to nsf2 allowed
int nsf2; // (8) Non-static field
static int sf1 = 5; // (9) Static field

{ // (10) Instance initializer block


int d = 2 * nsf1; // (11) OK. Read operation after declaration
int e = nsf1 = 50; // (12)
}

public static void main(String[] args) {


NonStaticForwardReferences objRef = new NonStaticForwardReferences();
System.out.println("nsf1: " + objRef.nsf1);
System.out.println("nsf2: " + objRef.nsf2);
}
}
Order of Execution

• Static variable initialization

• Static initializer blocks execution (in the order of


declaration if multiple blocks are present)

• Constructor header (super – implicit / explicit)

• Instance variables initialization / instance initializer blocks


execution.

• Rest of the code in the constructor.


Coffee Cram

1. Can we print some message on the console without writing


a main() method? If yes, how ?
Garbage Collection
Garbage Collection
• Efficient memory management is essential in a runtime
system.
• Storage for objects is allocated in a designated part of
memory called the heap. The size of the heap is finite.
• Garbage collection is a process of managing the heap
efficiently; that is, reclaiming memory occupied by objects that
are no longer needed and making the heap memory available for
new objects.
objects
• Java provides automatic garbage collection, meaning that the
runtime environment can take care of memory management
concerning objects, without the program having to take any
special action.
• Unlike C++, Java does not have destructors.
Structure of memory

Stack Area Local Variables

Movable Boundary
Dynamically allocated Area
Heap Area
(Objects)

Fixed Boundary Data Area Static And Global Variables

Code Section
Garbage Collection (continued…)

• Storage allocated on the heap through the new operator is


administered by the automatic garbage collector.

• The automatic garbage collection scheme guarantees that a


reference to an object is always valid while the object is
needed in the program. The object will not be reclaimed,
leaving the reference dangling.

• Having an automatic garbage collector frees the programmer


from the responsibility of providing code for deleting objects.
(but this does not mean, you can create as many objects as you
want and then just forget about them )

• Automatic garbage collector runs as a background task and


may prove detrimental to the program performance.
Garbage Collection (continued…)

• It is not possible to force GC.

• An automatic garbage collector essentially performs two


tasks:
- Decide if and when memory needs to be reclaimed.
- Find objects that are no longer needed by the program
and reclaim their storage.

• A program has no guarantees that the automatic garbage


collector will be run during its execution. A program should not
rely on the scheduling of the automatic garbage collector for
its behavior.
behavior
Reachable references

• An object in the heap is said to be reachable if it is denoted


by any local reference in a runtime stack. Additionally, any
object that is denoted by a reference in a reachable object is
also said to be reachable.

• Reachability is a transitive relation. Thus, a reachable object


has at least one chain of reachable references from the
runtime stack. Any reference that makes an object reachable
is called a reachable reference.

• A reachable object is alive. It is accessible by the live


thread that owns the runtime stack.
Unreachable references

• An object that is not reachable is said to be unreachable.

• When an object becomes unreachable and is waiting for its


memory to be reclaimed, it is said to be eligible for garbage
collection.

• When the garbage collector runs, it finds and reclaims the


storage of eligible objects.

• However, garbage collection does not necessarily occur as


soon as an object becomes unreachable.
unreachable

• The lifetime of an object is the time from when it is created


to the time till it is garbage collected.
How GC works…

• The automatic garbage collector figures out which objects


are not reachable and, therefore, eligible for garbage
collection.
• Automatic garbage collection should not be perceived as a
license for creation of objects and forgetting about them.
• Certain objects, such as files and net and DB connections,
can tie up other resources and should be disposed of properly
when they are no longer needed.
• Objects that are created and accessed by local references
in a method are eligible for garbage collection when that
method terminates, unless reference values to these objects
are exported out of the method. This can occur if a reference
value is returned from the method, passed as an argument to
another method that records the reference.
Garbage Collection Scenario #1

void go()
{
Life z = new Life();
}

When go() is pushed onto the Stack, it declares a reference


variable ‘z’, and creates a new object assigned to that
reference. This object is created on Heap. Reference is alive
and in scope.

When go() method completes, it gets popped off the Stack,


so now z is dead and gone. So Life() object is now eligible for
GC.
Garbage Collection Scenario #2

Life z = new Life();


void go()
{
z = new Life();
}

A new object Life() is created on Heap. Since ‘z’ is an


instance variable, the Life() will live as long as Class object
that instantiated it, is alive.

When method go() is called, this Life() is abandoned. Now ‘z’


refers to newly created Life() object.

So in such case, first Life() object is eligible for GC.


Garbage Collection Scenario #3

Life z = new Life();


void go()
{
z = null;
}

A new object Life() is created on Heap. Since ‘z’ is an


instance variable, the Life() will live as long as Class object
that instantiated it, is alive.

When someone calls method go(), ‘z’ is set to null. The only
reference (i.e. ‘z’) to Life() object has been set to null.

So now Life() object is eligible for GC.


Finalization

• Object finalization provides an object a last resort to


undertake any action before its storage is reclaimed.

• The automatic garbage collector calls the finalize() method


in an object that is eligible for garbage collection before
actually destroying the object.

• The finalize() method is defined in the Object class.

protected void finalize() throws Throwable

• Since there is no guarantee that the garbage collector will


ever run, there is also no guarantee that the finalizer will ever
be called.
Invoking GC

• Although Java provides facilities to invoke the garbage


collection explicitly, there are no guarantees that it will run.

• The program can only request that garbage collection be


performed, but there is no way that garbage collection can be
forced.

• The System.gc() method can be used to request garbage


collection.

• System.runFinalization() method can be called to suggest that


any pending finalizers be run for objects eligible for garbage
collection.
static Runtime getRuntime()
Returns the Runtime object associated with the current
application.

void gc()
Requests the garbage collection to run. However, it is
recommended to use the more convenient static method
System.gc().

void runFinalization()
Requests that any pending finalizers to run for objects
eligible for garbage collection. Again, it is more convenient to
use the static method System.runFinalization().
long freeMemory()
Returns the amount of free memory (bytes) in the JVM, that
is available for new objects.

long totalMemory()
Returns the total amount of memory (bytes) available in the
JVM. This includes both memory occupied by current objects
and free memory (that is available for new objects).
Always Remember …
• There are no guarantees that objects that are eligible for
garbage collection will have their finalizers executed. GC
might not even run if the program execution does not warrant
it. Thus, any memory allocated during program execution might
remain allocated after program termination, but will be
reclaimed by the operating system.

• There are also no guarantees about the order in which the


objects will be garbage collected, or the order in which their
finalizers will be executed. Therefore, the program should not
make any assumptions based on these aspects.

• Garbage collection does not guarantee that there is enough


memory for the program to run. A program can rely on the
garbage collector to run when memory gets very low and it can
expect an OutOfMemoryException to be thrown if its memory
demands cannot be met.
Coffee Cram

1. Can we overload finalize() method? Which version of that


method gets invoked?
2. Can we call finalize() method explicitly? Will that garbage
collect the objects?
Nested Classes
& Interfaces
Nested classes and interfaces
• A class that is declared within another class or interface,
is called a nested class. Similarly, an interface that is
declared within another class or interface, is called a
nested interface.
• A top-level class or a top-level interface is one that is not
nested.
• There are four categories of nested classes and one of
nested interfaces, defined by the context these classes
and interfaces are declared in:
- static member classes and interfaces
- non-static member classes
- local classes
- anonymous classes
• The last three categories are collectively known as inner
classes.

• They differ from non-inner classes in one important


aspect: that an instance of an nested class may be
associated with an instance of the enclosing class.

• The instance of the enclosing class is called the


immediately enclosing instance. An instance of an inner
class can access the members of its immediately enclosing
instance by their simple name.
Static member class / interface

• A static member class or interface is defined as a static


member in a class or an interface.

• Such a nested class can be instantiated like any ordinary


top-level class, using its full name.

• No enclosing instance is required to instantiate a static


member class.

• Note that there are no non-static member, local, or


anonymous interfaces. Interfaces are always defined
either at the top level or as static members.
Non-static member classes

Non-static member classes are defined as instance


members of other classes, just like fields and instance
methods are defined in a class.

An instance of a non-static member class always has an


enclosing instance associated with it.

Local Classes

Local classes can be defined in the context of a block as


in a method body or a local block, just as local variables
can be defined in a method body or a local block.
Anonymous Classes

Anonymous classes can be defined as expressions and


instantiated on the fly.

An instance of a local (or an anonymous) class has an enclosing


instance associated with it, if the local (or anonymous) class
is declared in a non-static context
class TLC { // (1) Top level class

static class SMC {/*...*/} // (2) Static member class

interface SMI {/*...*/} // (3) Static member interface

class NSMC {/*...*/} // (4) Non-static member (inner) class

void nsm() {
class NSLC {/*...*/}
// (5) Local (inner) class in non-static context
}

static void sm() {


class SLC {/*...*/}
// (6) Local (inner) class in static context
}

SMC nsf = new SMC(){/*...*/};


// (7) Anonymous (inner) class in non-static context

static SMI sf = new SMI(){/*...*/};


// (8) Anonymous (inner) class in static context
}
Entity Declaration Accessibility Enclosing Direct Declarations
Context Modifiers Instance Access to in Entity
Enclosing Body
Context
Top-level Package public or No N/A All that are
Class (or default valid in a
Interface) class (or
interface)
body
Static As static All No Static All that are
Member member of members in valid in a
Class (or enclosing enclosing class (or
Interface) class or context interface)
interface body
Non-static As non- All Yes All members Only non-
Member static in enclosing static
Class member of context declarations
enclosing + final static
class or fields
interface
Entity Declaration Accessibility Enclosing Direct Declarations
Context Modifiers Instance Access to in Entity
Enclosing Body
Context
In block with None Yes All members Only non-
non-static in enclosing static
context context + declarations +
final local final static
variables fields
Local Class In block with None No Static
Only non-
static members in
static
context enclosing
declarations +
context +
final static
final local
fields
variables
As expression None Yes All members Only non-
in non-static in enclosing static
context context + declarations +
final local final static
variables fields
Anonymous
Class As expression None No Static Only non-
in static members in static
context enclosing declarations +
context + final static
final local fields
variables
Static member class / interface
• A static member class or a static member interface
comprises the same declarations as those allowed in an
ordinary top-level class or interface.

• A static member class must be declared as a static


member of an enclosing class or interface. Nested
interfaces are considered implicitly static, the keyword
static can, therefore, be omitted.

• Since static member classes and interfaces are members


of an enclosing class or interface, they can have any
member accessibility.

• Static member classes and interfaces can only be nested


within other static member or top-level classes and
interfaces.
Non-Static member class

• Non-static member classes are inner classes that are


defined without the keyword static, as members of an
enclosing class or interface. Non-static member classes are
on par with other non-static members defined in a class.

• An instance of a non-static member class can only exist


with an instance of its enclosing class. This means that an
instance of a non-static member class must be created in
the context of an instance of the enclosing class. This also
means that a non-static member class cannot have static
members. In other words, the non-static member class
does not provide any services, only instances of the class
do. However, final static variables are allowed, as these are
constants.
Non-Static member class (continued…)

• Code in a non-static member class can directly refer to


any member (including nested) of any enclosing class or
interface, including private members. No explicit reference
is required.

• Since a non-static member class is a member of an


enclosing class, it can have any accessibility: public,
package/default, protected, or private.

• A special form of the new operator is used to instantiate


a non-static member class.

<enclosing object reference>.new <non-static member


class constructor call>
Non-Static member class (continued…)

• The <enclosing object reference> in the object creation


expression evaluates to an instance of the enclosing class in
which the designated non-static member class is defined. A
new instance of the non-static member class is created and
associated with the indicated instance of the enclosing
class.

•Note that the expression returns a reference value that


denotes a new instance of the non-static member class. It
is illegal to specify the full name of the non-static member
class in the constructor call, as the enclosing context is
already given by the <enclosing object reference>.
Non-Static member class (continued…)

• In order to access members of the enclosing Context,


Syntax is :

public NonStaticMemberClass()
{ this.banner = ToplevelClass.this.headlines; }

The expression

<enclosing class name>.this

evaluates to a reference that denotes the enclosing object


(of class <enclosing class name>) of the current instance of a
non-static member class.
Local class
• A local class is an inner class that is defined in a block.
This could be a method body, a constructor, a local block, a
static initializer, or an instance initializer.

• Blocks in a non-static context have a this reference


available, which denotes an instance of the class containing
the block. An instance of a local class, which is declared in
such a non-static block, has an instance of the enclosing
class associated with it. This gives such a non-static local
class much of the same capability as a non-static member
class.

•A local class is an inner class that is defined in a block.


This could be a method body, a constructor, a local block, a
static initializer, or an instance initializer.
Local class (continued…)

• Blocks in a non-static context have a this reference


available, which denotes an instance of the class containing
the block. An instance of a local class, which is declared in
such a non-static block, has an instance of the enclosing class
associated with it. This gives such a non-static local class
much of the same capability as a non-static member class.

• However, if the block containing a local class declaration is


defined in a static context (i.e., a static method or a static
initializer), then the local class is implicitly static in the
sense that its instantiation does not require any outer
object. This aspect of local classes is reminiscent of static
member classes. However, note that a local class cannot be
specified with the keyword static.
Local class (continued…)

Some restrictions that apply to local classes are -


• Local classes cannot have static members, as they cannot
provide class-specific services. However, final static fields
are allowed, as these are constants.

• Local classes cannot have any accessibility modifier. The


declaration of the class is only accessible in the context of
the block in which it is defined, subject to the same scope
rules as for local variable declarations.

• Local class can access final local variables, final methods


parameters in the scope of the local context.

• Access to non-final variable in the enclosing block, is not


permitted from local classes.
Local class (continued…)

• Non-static local class can access both static and non-static


member defined in the enclosing class.

• Static local class can only directly access member defined in


the enclosing class that are static.

• Local class can be instantiated in the block in which it is


defined. Obviously, it must be declared before being used in
the block.
Anonymous class

• Classes are usually first defined and then instantiated


using the new operator. Anonymous classes combine the
process of definition and instantiation into a single step.

• Anonymous classes are defined at the location they are


instantiated, using additional syntax with the new operator.
As these classes do not have a name, an instance of the class
can only be created together with the definition.

• An anonymous class can be defined and instantiated in


contexts where a reference can be used (i.e., as expressions
that evaluate to a reference denoting an object).
Anonymous class (continued…)

• Anonymous classes are typically used for creating objects


on the fly in contexts such as the value in a return
statement, an argument in a method call, or in initialization
of variables. Anonymous classes are heavily used to
implement event listeners in GUI-based applications.

• Like local classes, anonymous classes can be defined in


static or non-static context.

• The keyword static is never used.

• Anonymous class can either extend a class or implement an


interface but not both at the same time.
Anonymous class (continued…)
• The following syntax can be used for defining and instantiating
an anonymous class that extends an existing class specified by
<superclass name>:
new <superclass name>(<optional arg list>)
{<member declarations> }

• Optional arguments can be specified, which are passed to the


superclass constructor. Thus, the superclass must provide a
constructor corresponding to the arguments passed.

• No extends clause is used in the construct. Since an anonymous


class cannot define constructors (as it does not have a name), an
instance initializer can be used to achieve the same effect as a
constructor.

• Only non-static members and final static fields can be declared


in the class body.
Anonymous class (continued…)

• The following syntax can be used for defining and


instantiating an anonymous class that implements an
interface specified by <interface name>:

new <interface name>() { <member declarations> }

• An anonymous class provides a single interface


implementation, and no arguments are passed.

• The anonymous class implicitly extends the Object class.


Note that no implements clause is used in the construct.
Fundamental
Classes
String Class

• String is a class in Java and not a data-type. (Note ‘S’ is


capital)

• Most of the programming languages treat String as array


of characters but in Java, Strings are objects.

• Defined in java.lang package so that they are easily


available to all the programs automatically.

• String objects are immutable.

• If you create a new String without assigning it, it will be


lost in your program.

• If you redirect a String reference to a new String, the old


String can be lost.
String Class (continued…)

• String methods use zero-based index, except for the


second argument of substring().

• The String class is final – It can not be extended and its


methods can’t be overridden.

• When a String literal is encountered by the JVM, it is


added to the pool. Thus JVM maintains a pool of Strings.

• Strings have a method named length(), arrays have an


attribute named length.
StringBuffer Class

• It is a peer class of String and provides much of the


functionality of Strings.

• Like String, StringBuffer is also final class.

• It provides some additional methods for string operations,


which are not present in String class.

• StringBuffers are mutable - they can change without


creating a new object.

• StringBuffer methods act on the invoking object, but


objects can change without an explicit assignment in the
statement.

• In StringBuffer class, equals() is not overridden; it doesn’t


compare values.
Significance of StringBuffer Class

• Java uses StringBuffer class heavily.

• Java supports operator overloading implicitly.


E.g. + operator is overloaded implicitly in Java.
• When + Operator is used for String concatenation, Java
internally uses StringBuffer class behind the scenes.

Study various overloaded constructors and methods of


String and StringBuffer classes.
Object Class

• Object class is the ultimate ancestor of all the Java


classes. Object class is at the top of class hierarchy.

• All classes extend the Object class, either directly or


indirectly.

• A class declaration, without the extends clause,


implicitly extends the Object class.

• Thus Object class defines the basic functionality that


all objects exhibit and all classes inherit.

• This applies to even arrays. Arrays in Java are genuine


objects.
Important methods in Object Class

• int hashCode() - HomeWork

• boolean equals(Object obj)

• final Class getClass() - HomeWork

• protected Object clone() – returns new objects that are


exactly the same (i.e. have identical states) as the current
object.

• String toString() - HomeWork

• protected void finalize() – We have seen this in “GC”.

• wait(), notify(), notifyAll() – Will see this during “Threads”.


boolean equals(Object obj)

• The equals() method in the Object class returns true only


if the two references compared denote the same object.
• The equals() method is usually overridden to provide the
semantics of object value equality, as is the case for the
wrapper classes and the String class.
• Use == to determine if two reference variables refer to
the same object.
• Use equals() to determine if two objects are meaningfully
equivalent.
• If you don’t override equals(), two different objects can’t
be considered the same.
• When overriding equals(), use the instanceof operator to
be sure you’re evaluating an appropriate class.
Highlights of the equals() method:
• Reflexive: x.equals(x) is always true.

• Symmetric: If x.equals(y) is true, then y.equals(x) must


be true.

• Transitive: If x.equals(y) is true, and y.equals(z) is true,


then z.equals(x) is true.

• Consistent: Multiple calls to x.equals(y) will always return


the same result.

• Null: If x is not null, then x.equals(null) is always false.

Understand the difference between == operator


and equals() method. Do not get confused
between them.
Reference Type V/S Object Type

Object obj = new MyClass();

int i = obj.hashCode(); Allowed and Valid. Object has


hashcode method.

obj.printMe(); Not Allowed. Not valid. Object


doesn’t know about any method
named printMe().

The Compiler decides whether you can call a


method based on the reference type, not the
actual object type.
Reference Type V/S Object Type

Object obj = new MyClass();

MyClass m = (MyClass) obj; Downcast obj to MyClass.

m.printMe(); Now after typecast, you can


invoke printMe() method.

You can call a method on an object only if the


class of the reference variable has that
method.
Coffee Cram

1. What is difference between –


String str = new String(“abc”);
String str = “abc”;
Fundamental
Classes
Wrapper Classes

• Primitive values in Java are not objects. In order to


manipulate these values as objects, the java.lang package
provides a wrapper class for each of the primitive data
types.

• All wrapper classes are final.

• The objects of all wrapper classes that can be


instantiated are immutable, that is, their state cannot be
changed.

• In addition to the methods defined for constructing and


manipulating objects of primitive values, the wrapper
classes also define useful constants, fields, and conversion
methods.
Although the Void class is considered a wrapper class, it
does not wrap any primitive value and is not instantiable (i.e.,
has no public constructors). It just denotes the class object
representing the keyword void. The Void class will not be
discussed henceforth.
Wrapper Conversion Utility methods
xxxValue() –
• When you need to convert the value of a wrapped numeric to
a primitive, use one of the many xxxValue() methods.
• All of the methods in this family are no-argument methods.

parseXxx() -
• Six parseXxx() methods (one for each numeric wrapper
type)
• parseXxx() returns the named primitive.
• parseXxx() takes a String, returns a primitive, is static.

valueOf() –
• valueOf() returns a newly created wrapped object of the
type that invoked the method.
Wrapper Conversion Utility methods

double d4 = Double.parseDouble("3.14");
// convert a String to a primitive
System.out.println("d4 = " + d4); // result is "d4 = 3.14"

Double d5 = Double.valueOf("3.14");
// create a Double object
System.out.println(d5 instanceof Double );
// result is "true"

long L2 = Long.parseLong("101010", 2);


// binary String to a primitive
System.out.println("L2 = " + L2); // result is "L2 = 42"

Long L3 = Long.valueOf("101010", 2);


// binary String to Long object
System.out.println("L3 value = " + L3);
// result is "L2 value = 42"
Always Remember this !!!
Study all the wrapper classes, their constructors and
various methods available in them.

Importance of Wrapper Classes would be clear


when we study Collections Framework.
Math Class

• Math is a final class.


• Defines a set of static methods to support common
mathematical functions, including functions for rounding
numbers, performing trigonometry, generating pseudo
random numbers, finding maximum and minimum of two
numbers, calculating logarithms and exponential.

• The Math class cannot be instantiated. Only the class


name Math can be used to invoke the static methods.

Study various methods of Math class.


System Class

• It has collection of static methods and variables.

• The standard input, output and error output of the Java


runtime are stored in the in, out and err variables.

static long currentTimeMillis() –

Returns the current time in terms of milliseconds since


midnight, January 1, 1970.
This method can be used to determine how long various
sections within the program take to execute, especially –
loops.
static void exit(int exitcode) –

Halts execution and returns the value of exit code to the


parent process (OS).
By convention, 0 means normal termination. All other values
indicate some form of error.

Study various methods of System class.


StringTokanizer Class

Study various methods of StringTokanizer class


Random Class

Study usage of Random class and various methods in it.

Priorities Class

Java does not have any class named Priorities.


Lets hope that the syllabus is referring to the class
named Properties. We will study this later.
Collections
Framework
Something important before we start...

Syllabus refers to Collections Framework with the name –


“Java utility package, classes and interfaces”.

Topics mentioned under this section, in the syllabus are


vague and unclear.

We don’t want any surprises in the exam, so we will study


Collections Framework completely.
Collection Framework
• A collection allows a group of objects to be treated as a
single unit. Arbitrary objects can be stored, retrieved, and
manipulated as elements of collection.
• This framework is provided in the java.util package.
• Collection framework comprises of three main parts –
- The core interfaces that allow collections to be manipulated
independently of their implementation.
- A small set of implementations i.e. concrete classes, that are
specific implementations of the core interfaces, providing data
structures that a program can use readily.
- Few static utility methods that can be used to perform
various operations on collections, such as sorting and searching,
or creating customized collections.
Core interfaces in Collection Framework
Core interfaces in Collection Framework
Classes and Interfaces Hierarchy
Classes and Interfaces Hierarchy
Classes and Interfaces Hierarchy (Simplified )
<< interface >>
Collection

<< interface >> << interface >>


Set List

<< interface >> LinkedList Vector


SortedSet

ArrayList

TreeSet HashSet LinkedHashSet


<< interface >>
Map

<< interface >>


SortedMap

TreeMap HashMap Hashtable LinkedHashMap

Remember : An interface Map and its descendants


do not inherit Collection interface.
Concrete Classes at a glance
Concrete Classes at a glance
Collection Interface

• The Collection interface specifies the contract that all


collections should implement.

• Collection interface contains two types of operations i.e.


methods -

• The basic operations are used to query a collection about its


contents and allow elements to be added and removed from a
collection.

• The bulk operations are performed on a collection as a single


unit.
Basic operations

int size()
boolean isEmpty()
boolean contains(Object element)
boolean add(Object element)
boolean remove(Object element)

The add() and remove() methods return true if the collection


was modified as a result of the operation.
By returning the value false, the add() method indicates that
the collection excludes duplicates, and that the collection
already contains an object equal to the argument object.

The contains() method checks for membership of the


argument object in the collection using object value equality.
Bulk operations

boolean containsAll(Collection c)
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean retainAll(Collection c)
void clear()

The containsAll() method returns true if all elements of the


specified collection are also contained in the current
collection.

The addAll(), removeAll(), and retainAll() methods are


destructive in the sense that the collection on which they are
invoked can be modified.
Enumeration

• The Enumeration interface defines the methods by which you


can enumerate (obtain one at a time) the elements in a
collection.

• This interface has been superseded by Iterator interface.

• Although not deprecated, Enumeration is considered obsolete


for the new code.

boolean hasMoreElements()
This returns true, when there are still more elements in the
collection you are enumerating. Returns false, when all the
elements have been enumerated.

Object nextElement()
Returns the next object in the enumeration as a generic
Object reference.
Iterator

• A collection provides an iterator which allows sequential


access to the elements of a collection.

• An iterator can be obtained by calling the following method


of the Collection interface :

Iterator iterator() - Returns an object which implements the


Iterator interface.

Iterator provides following methods -

boolean hasNext() :-

Returns true if the underlying collection still has elements left


to return.
Object next() :-
Moves the iterator to the next element in the underlying collection,
and returns the current element. If there are no more elements
left to return, it throws a NoSuchElementException.

Object remove() :-
Removes the element that was returned by the last call to the
next() method, from the underlying collection. Invoking this method
results in an IllegalStateException, if the next() method has not
yet been called, or when the remove() method has already been
called after the last call to the next() method. This method is
optional for an iterator, that is, it throws an
UnsupportedOperationException if the remove operation is not
supported.
Set
• Implementations of the Set interface do not allow duplicate
elements.

• This also means that a set can contain at most one null value.

• add() and addAll() methods will not store duplicates.

• An element is not currently in the set, two consecutive calls to


the add() method to insert the element will first return true, then
false.
Set

• The HashSet class implements the Set interface.

• A HashSet does not guarantee any ordering of the elements.

• A HashSet relies on the implementation of the hashCode()


and equals() methods of its elements.

• LinkedHashSet is a subclass of the HashSet class.

• LinkedHashSet guarantees that the iterator will access the


elements in insertion order, that is, in the order in which they
were inserted into the LinkedHashSet.
HashSet Constructors
HashSet()
Constructs a new, empty set.

HashSet(Collection c)
Constructs a new set containing the elements in the specified
collection. The new set will not contain any duplicates. This offers
a convenient way to remove duplicates from a collection.

HashSet(int initialCapacity)
Constructs a new, empty set with the specified initial capacity.

HashSet(int initialCapacity, float loadFactor)


Constructs a new, empty set with the specified initial capacity and
the specified load factor.

initial capacity - The number of buckets in the hash table.

load factor - the ratio of number of elements stored to its


current capacity.
Collections
Framework
List

• Implementation of List maintain their elements in order, and


can contain duplicates.

• The elements in a list are ordered. Each element, therefore,


has a position in the list.

• A zero-based index can be used to access the element at the


position designated by the index value. The position of an
element can change as elements are inserted or deleted from
the list.

• The List interface also defines operations that work


specifically on lists: position-based access of the list elements,
searching in a list, creation of customized iterators, and
operations on parts of a list.
List methods

Object get(int index)


Returns the element at the specified index.

Object set(int index, Object element)           


Replaces the element at the specified index with the specified
element. It returns the previous element at the specified index.

void add(int index, Object element)             


Inserts the specified element at the specified index. If
necessary, it shifts the element previously at this index and any
subsequent elements one position toward the end of the list. The
inherited method add(Object) from the Collection interface will
append the specified element to the end of the list.
List methods

Object remove(int index)                         


Deletes and returns the element at the specified index,
contracting the list accordingly. The inherited method
remove(Object) from the Collection interface will remove the
first occurrence of the element from the list.

// Element Search
int indexOf(Object o)
int lastIndexOf(Object o)
These methods respectively return the index of the first and
the last occurrence of the element in the list if the element is
found; otherwise, the value –1 is returned.
List (continued…)

• The ArrayList and Vector classes implement the List interface.

• The Vector and ArrayList classes are implemented using


dynamically resizable arrays, providing fast random access and
fast list traversal—very much like using an ordinary array.

• Unlike the ArrayList class, the Vector class is thread-safe,


meaning that concurrent calls to the vector will not compromise
its integrity.

• The LinkedList implementation uses a doubly-linked list.


Insertions and deletions in a doubly-linked list are very efficient -
elements are not shifted, as is the case for an array.

• When frequent insertions and deletions occur inside a list, a


LinkedList is the best choice to be used.
ArrayList Constructors

ArrayList()
Constructs a new, empty ArrayList. An analogous constructor is
provided by the LinkedList and Vector classes.

ArrayList(Collection c)
Constructs a new ArrayList containing the elements in the
specified collection. The new ArrayList will retain any duplicates.
The ordering in the ArrayList will be determined by the
traversal order of the iterator for the collection passed as
argument. An analogous constructor is provided by the
LinkedList and Vector classes.

ArrayList(int initialCapacity)
Constructs a new, empty ArrayList with the specified initial
capacity. An analogous constructor is provided by the Vector
class.
Map

• A Map defines mappings from keys to values. The <key, value>


pair is called an entry in a Map.

• A Map does not allow duplicate keys, in other words, the keys
are unique.

• Both the keys and the values must be objects. This means that
primitive values must be wrapped in their respective wrapper
objects, if they are to be put in a map.

• A map is not a collection and the Map interface does not extend
the Collection interface.
Map methods

Object put(Object key, Object value)


Inserts the <key, value> entry into the map. It returns the value
previously associated with the specified key, if any. Otherwise, it
returns the null value.

Object get(Object key)


Returns the value to which the specified key is mapped, or null if
no entry is found.

Object remove(Object key)


The remove() method deletes the entry for the specified key. It
returns the value previously associated with the specified key, if
any. Otherwise, it returns the null value.

void putAll(Map t)
Copies all entries from the specified map to the current map.
Map methods

boolean containsKey(Object key)


Returns true if the specified key is mapped to a value in the map.

boolean containsValue(Object value)


Returns true if there exists one or more keys that are mapped to
the specified value.

int size()
These methods return the number of entries (i.e., number of
unique keys in the map)

boolean isEmpty()
Returns true / false depending upon whether map is empty or not.

void clear()
deletes all the entries from the current map.
Map (continued…)

• The classes HashMap and Hashtable implement unordered maps.


The class LinkedHashMap is ordered.

• HashMap class is not thread-safe and permits one null key.

• Hashtable class is thread-safe and permits non-null keys and


values.

• The LinkedHashMap is a subclass of the HashMap class.

• By default, the entries of a LinkedHashMap are in key insertion


order, that is, the order in which the keys were inserted in the
map. This order does not change if a key is re-inserted, because
no new entry is created if the key's entry already exists.
HashMap Constructors

HashMap()
HashMap(int initialCapacity)
HashMap(int initialCapacity, float loadFactor)
Constructs a new, empty HashMap, using either specified or
default initial capacity and load factor.

HashMap(Map otherMap)
Constructs a new map containing the elements in the specified
map.
Properties
• Properties is a subclass of Hashtable.
• It is used to maintain list of values in which, key is also a String
and value is also a String.
• Properties class is used by many other Java classes.
E.g. System.getProperties() is used to get environmental values.

String getProperty(String key)


Returns the value associated with key. A null object is returned
if key is neither in the list nor in the default property list.

Object setProperty(String key, String value)


Associates value with a key. Returns the previous values
associated with key, or returns null if no such association exists.

We will study more about Properties class, during File


handling and IO.
TreeSet and TreeMap
• TreeSet is a sorted Set.
• TreeSet guarantees that the elements will be in ascending order,
according to the natural order of the elements.
• Optionally, you can construct a TreeSet with a constructor that
lets you define your own rules for what the natural order should be
(rather than relying on the ordering defined by the elements’
class)

• TreeMap is a sorted Map.


• TreeMap guarantees that the elements will be in ascending order
of keys, according to the natural order of the elements.
• Similar to TreeSet, TreeMap lets you pass your own comparison
rules in when you construct a TreeMap, to specify how the
elements should be compared to one another when they’re being
ordered.
Study various Constructors / Methods of

ArrayList, LinkedList, Vector.

HashSet, LinkedHashSet, TreeSet

Hashtable, HashMap, LinkedHashMap, TreeMap

Enumeration, Iterator, Properties


Always Remember this !!!
Threads
Multiprocessing

• This allows many processes to run simultaneously.

• Process is a running instance of the program. i.e. an


operating system process.

• CPU time is shared between different processes.

• OS provides context switching mechanism, which enables


to switch between the processes.

• Program’s entire contents (e.g. variables, global variables,


functions) are stored separately in their own context.

• Example:- MS-Word and MS-Excel applications running


simultaneously. (or any two applications for that matter)
Multithreading

• This allows many tasks within a program (process) to run


simultaneously.

• Each such task is called as a Thread.

• Each Thread runs in a separate context.

• Example:- Lets take a typical application like MS-Word.


There are various independent tasks going on, like displaying
GUI, auto-saving the file, typing in text, spell-checking,
printing the file contents etc…

• In Java, main() is considered as a main thread. GC which


runs as a background task can be considered as another
thread.
Multiprocessing Multithreading
• Threads may share the
• Each process has a same data.
complete set of its
own variables.
• It takes much less
• It takes more overhead to create &
overhead to launch destroy threads.
new processes.
• Inter-thread
• Inter-process
communication is communication is
slower & restrictive. easier.
Processes vs. Thread
• Processes are heavyweight.

• Require their own address space.

• Inter-process communication is expensive. i.e. Context


switching between the processes is expensive in terms of
CPU time.

• Threads are lightweight.

• Share same address space and share same heavyweight


process.

• Inter-thread communication is inexpensive. i.e. Context


switching between the threads is inexpensive in terms of
CPU time.
Thread

• Thread is an independent sequential path of execution


within a program. i.e. separate call stack.

• Many threads run concurrently within a program.

• At runtime, threads in a program exist in a common


memory space and can share both data and code.

• Multithreading enables you to write efficient programs


that make maximum use of CPU, keeping the idle time to
a minimum.
Java supports multi-threading

In Java, you really can


walk and chew gum at
the same time.

Multi-threading in Java means, your program can


perform many things simultaneously.
Multi-threading in Java

• Java supports multi-threading.

• But Java is totally platform-dependent as far as threading


is concerned.

• Threading is controlled by thread scheduling algorithm


which is dependent on the underlying OS.
OS

• So inconsistent behavior may be observed in the programs


using threads.
User threads and daemon threads

• Java runtime system distinguishes between the user threads


and daemon threads. As long as user thread is alive, JVM does
not terminate.
• Daemon thread is at the mercy of the runtime system: it is
stopped if there are no more user threads running, thus
terminating the program. Daemon threads exist only to serve
user threads.

• When a stand-alone application runs, user thread is


automatically created to execute the main() method. This is
called as a main thread.
• All other threads (child threads) are spawned from this main
thread inheriting user-thread status.
• setDaemon(boolean) method in the Thread class, can be
called to change the status of user-defined thread to either
user thread or daemon thread.

• This method must be called before thread is started. Any


attempt made to call this method, after the thread has been
started, throws IllegalThreadStateException.

Thread Creation

• In Java, thread is represented by an object of the Thread


class. Using threads can be achieved in one of the two ways –

- Extending java.lang.Thread class.


- Implementing java.lang.Runnable interface.
Implementing java.lang.Runnable interface

• The Runnable interface has the following specification,


comprising one method prototype declaration:
public interface Runnable {
void run();
}
• A thread, which is created based on an object that
implements the Runnable interface, will execute the code
defined in the public method run().

• In other words, the code in the run() method defines an


independent path of execution and thereby the entry and the
exits for the thread. The thread dies when the run() method
ends, either by normal completion or by throwing an uncaught
exception.
Implementing java.lang.Runnable interface (continued…)

• The procedure for creating threads based on the Runnable


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

- The start() method is invoked on the Thread object created


in the previous step. The start() method returns immediately
after a thread has been spawned.

• The run() method of the Runnable object is eventually


executed by the thread represented by the Thread object on
which the start() method was invoked.
UML : Sequence diagram – Using Runnable interface
Extending java.lang.Thread class

• A class can also extend the Thread class to create a thread.

A typical procedure for doing this is as follows –


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

- This subclass may call a Thread constructor explicitly in its


constructors to initialize the thread, using the super() call.

- The start() method (inherited from the Thread class) is


invoked on the object of the class to make the thread eligible
for running.
Some important constructors and methods from the
java.lang.Thread

Thread(Runnable threadTarget)
Thread(Runnable threadTarget, String threadName)

The argument threadTarget is the object whose run() method


will be executed when the thread is started. The argument
threadName can be specified to give an explicit name for the
thread, rather than an automatically generated one. A thread's
name can be retrieved by using the getName() method.

static Thread currentThread()

This method returns a reference to the Thread object of the


currently executing thread.
Methods from the java.lang.Thread (continued…)

final String getName()


final void setName(String name)

The first method returns the name of the thread. The second
one sets the thread's name passed as an argument.

void run()

The Thread class implements the Runnable interface by


providing an implementation of the run() method. This
implementation does nothing. Subclasses of the Thread class
should override this method.

If the current thread is created using a separate Runnable


object, then the Runnable object's run() method is called.
Methods from the java.lang.Thread (continued…)

final void setDaemon(boolean flag)


final boolean isDaemon()

The first method sets the status of the thread either as a


daemon thread or as a user thread, depending on whether the
argument is true or false, respectively. The status should be set
before the thread is started. The second method returns true
if the thread is a daemon thread, otherwise, false.

void start()

This method spawns a new thread, that is, the new thread will
begin execution as a child thread of the current thread. The
spawning is done asynchronously as the call to this method
returns immediately. It throws an IllegalThreadStateException
if the thread was already started.
Coffee Cram

• Why do we need to implement Runnable interface, when we


can create threads by extending Thread class ?
Threads
http://www.docjar.com
Coffee Cram

• Why do we need to implement Runnable interface, when we


can create threads by extending Thread class ?
Choosing an approach between -
Thread Class and Runnable Interface

• Extending Thread class means, subclass can not inherit any


other class (as Java does not allow multiple inheritance
through classes)

• Many Java programmers feel that classes should be


extended only when they are being enhanced or modified in
some way. When you extend Thread class, you are not really
enhancing Thread class and or not adding any new
functionality in it. Instead you are only interested in being
runnable.
Thread Life Cycle

Understanding the life cycle of a thread is valuable when


programming with threads.

Threads can exist in different states. Just because a


thread's start() method has been called, it does not mean
that the thread has access to the CPU and can start
executing straight away. Several factors determine how a
thread will proceed.

Threads can exist in different states:-


Thread Life Cycle

Ready-to-run state
A thread starts life in the
Ready-to-run state.

Running state
If a thread is in the Running
state, it means that the thread
is currently executing.
Thread Life Cycle

Dead state

Once in this state, the thread


cannot ever run again.

Non-runnable states
A running thread can transit to one of the non-runnable
states, depending on the circumstances.
A thread remains in a non-runnable state until a special
transition occurs.
A thread does not go directly to the Running state from a non-
runnable state, but transits first to the Ready-to-run state.
Thread Life Cycle

The non-runnable states can be characterized as follows:

• Sleeping: The thread sleeps for a specified amount of time.


• Blocked for I/O: The thread waits for a blocking operation to
complete.
• Blocked for join completion: The thread awaits completion of
another thread.
• Waiting for notification: The thread awaits notification from
another thread.
• Blocked for lock acquisition: The thread waits to acquire the
lock of an object.

We will study more about these states later.


Thread Scheduling
Schedulers in JVM implementations usually employ one of the
below given strategies:

1) Preemptive scheduling:
If a thread with a higher priority than the current running thread
moves to the Ready-to-run state, then the current running thread
can be preempted (moved to the Ready-to-run state) to let the
higher priority thread execute.

2) Time-Sliced or Round-Robin scheduling:


A running thread is allowed to execute for a fixed length of time,
after which it moves to the Ready-to-run state to await its turn to
run again.

Remember - Thread schedulers are implementation and


platform-dependent; therefore, how threads will be scheduled
is unpredictable, at least from platform to platform.
Hey Thread 4, you’ve
had enough time…go
back to runnable
state. Thread 2 you
take his place.
Thread 2 Thread 1

Thread Scheduler

Thread 4 Thread 3
Thread Priorities

• Threads are assigned priorities that the thread scheduler can


use to determine how the threads will be scheduled.
• The thread scheduler can use thread priorities to determine
which thread gets to run. The thread scheduler favors giving
CPU time to the thread with the highest priority in the Ready-
to-run state. This is not necessarily the thread that has been
the longest time in the Ready-to-run state.
• Heavy reliance on thread priorities for the behavior of a
program can make the program unportable across platforms, as
thread scheduling is platform–dependent.
• Priorities are integer values from 1 (lowest priority given by
the constant Thread. MIN_PRIORITY) to 10 (highest priority
given by the constant Thread.MAX_PRIORITY). The default
priority is 5 (Thread.NORM_PRIORITY).
Thread Priorities

• A thread inherits the priority of its parent thread.

• Priority of a thread can be set using the setPriority() method


and read using the getPriority() method, both of which are
defined in the Thread class.

• The following code sets the priority of the thread myThread


to the minimum of two values: maximum priority and current
priority incremented to the next level:

myThread.setPriority(Math.min(Thread.MAX_PRIORITY,
myThread.getPriority()+1));
Unary and Binary Numeric Promotions (continued...)

Floating-Point Arithmetic

• If any of the operands is a floating-point type, the operation


performs floating-point division.
int i1 = 4 / 5; // result: 0
int i2 = 8 / 8; // result: 1
double d2 = 4.0 / 8; // result: 0.5
double d3 = 8 / 8.0; // result: 1.0
double d4 = 12.0F / 8; // result: 1.5F

You might also like