0% found this document useful (0 votes)
16 views346 pages

Club - Java Day 1to3

The document provides an introduction to Java, detailing its features such as simplicity, platform independence, and object-oriented principles. It also covers variable types, data types, control flow statements, and the use of classes and objects, along with examples demonstrating Java syntax and functionality. Additionally, it explains the importance of the 'this' keyword and memory management through garbage collection.

Uploaded by

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

Club - Java Day 1to3

The document provides an introduction to Java, detailing its features such as simplicity, platform independence, and object-oriented principles. It also covers variable types, data types, control flow statements, and the use of classes and objects, along with examples demonstrating Java syntax and functionality. Additionally, it explains the importance of the 'this' keyword and memory management through garbage collection.

Uploaded by

siddhantlahane33
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 346

Core Java

Day1:
Introduction to java:
-Java technology is both a Programming Language and a Platform(OS+Hardware) from Oracle
Corporation.
-Launched on 18th march 2014.
features:
1.Simple-No Pointers, No Multiple Inheritance
For almost every task API (Application Programming Interface) is available; Programmer just need to
know how to use that API.

2. Platform Independent-Compile once run anywhere (run on any platform)


Unlike other programming languages such as C, C++ etc. which are compiled into platform specific
machines.
Java is guaranteed to be compile-once, run-anywhere language.
On compilation Java program is compiled into bytecode.
This bytecode is platform independent and can be run on any machine.
Any machine with Java Runtime Environment can run Java Programs.

3. Object Oriented-Strong Object Oriented Language, No Global Variable, No Friend Function.


4. Portable-Data types occupy same no. of bytes on all platforms.(Same bytes of memory use to all
OS)
5. Distributed-Client Server Application can be made effectively.
6. High Performance-Due to JIT(Just in time compiler), execution becomes faster
7. Multithreaded-You can create Multithreaded Applications.Java multithreading feature makes it
possible to write program that can do many tasks simultaneously.

8. Robust- most of the things are checked during compile time so no risk at runtime
Java puts a lot of emphasis on early checking for possible errors, as Java compilers are able to detect
many problems that would first show up during execution time in other languages.
It provides the powerful exception handling and type checking mechanism as compare to other
programming languages.

8.1.Safe-
If a bytecode contains any virus or malicious code, JVM will not execute it.
This features saves your system especially when you download java code and try to execute.

9. Dynamic-Supports late binding since beginning. You can load any class on the fly and find out its
information.
10. Secure-If bytecode contains virus or malicious code , it cannot be executed on the system. Thanks
to Java’s secure feature.
11. Automatic Garbage Collection :
Automatic garbage collection is the process of looking at heap memory, identifying which objects are
in use and which are not, and deleting the unused objects.
An in use object, or a referenced object, means that some part of your program still maintains a
pointer to that object.
An unused object, or unreferenced object, is no longer referenced by any part of your program.
So the memory used by an unreferenced object can be reclaimed.

-In the Java programming language, all source code is first written in plain text files ending with the
.java extension.
-Those source files are then compiled into .class files by the javac(Java compiler) compiler.
-Java SE8(java standard edition 8)

Where is Java Used?


Earlier, Java was only used to design and program small computing devices, but later was adopted as
one of the platform independent programming language. It can be interpreted on any platform
including Windows, Linux and so on.

 E-commerce Application
 Network or Computing Devices
 PDA
 Cell Phones [Mobile Information Devices Profile (MIDP)]
 PCs
 Mobile Tracking Systems
 Pulse Meter

Variable :
Variable is name of reserved area allocated in memory.

int data=50;//
Here data is variable

There Are Three Types Of Variables In Java


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

 Static Variable-A variable that is declared as static is called static variable. It cannot be local.
class A{

int data=50;//instance variable

static int m=100;//static variable

void method(){

int n=90;//local variable

}//end
In Java, There are of class
Two Types of Data Types
Primitive Data Types
Non-Primitive Data Types

Datatypes Default value size

boolean false 1 bit

char '\u0000' 2 byte

byte 0 1 byte

short 0 2 byte

int 0 4 byte

long 0L 8 byte
public class Datatypes_Demo
float 0.0f 4 byte

double { 0.0d 8 byte

public static void main(String[] args)


{
// integral types
byte a=10;
short b=20;
int c=30;
long d=40;
System.out.println(a+"\t"+b+"\t"+c+"\t"+d);
// floating point
float e=3.5f;
double f=5.6;
System.out.println(e+"\t"+f);
// character
char g='A';
// boolean
System.out.println(g);
boolean h=true;
System.out.println(h);
// reference types
String i="hello";
System.out.println(i);
}
}
Example:
-if L&R both are same, automatic conversion takes place.e.g.int a=10
-if L is heavier than R automotive conversion takes place. e.g. double d=10.3f
-if R is heavier than L,you have to typecast else you get compile.e.g. Float f=23.03
possible

Not Double float


possible
float
Double
public class Automatic_Explicit_Conversion
{
public static void main(String[] args)
{
// integral types
byte a=10;

int c=30;

c=a; // automatic conversion


System.out.println(c);

// a=c; // not possible,explicit cast is needed


a=(byte)c; // explicit cast
System.out.println(a);

double d=4.8; // automatic cast


System.out.println(d);
// float d=3.5; // not possible bec, 3.5 is by default
double
float e=3.5f; // explicit cast
float f=(float)3.5;
System.out.println(e+"\t"+f);
}
}

Char of 2 bytes because:


Since Java is designed to support Internationalization ( I18N ), it makes sense that it would use
Unicode to represent characters.
Unicode defines a fully international character set that can represent all of the characters found in all
human languages.

It is a unification of dozens of character sets such as Latin, Greek, Arabic, Russia and many more.
For this purpose, it requires 16 bits.
Thus char in java is 16 bit type.
The range of char is 0 to 65535.
There are no negative chars.

Types of comments:
in java we have 3 types of comments

a) single line //
b) multiline
/* */
c) document comment ( in order to create documentation )
/** **/

control flow:
if/else if/else: used to apply condition on the program
public class If_Demo
{
public static void main(String[] args)
{
int a=10;
if(a>0)
{
System.out.println("it's positive");
}
else if(a<0)
{
System.out.println("it's negative");
}
else
{
System.out.println("it's zero");
}
}
}
For
1:
public class For_Demo_1
{
public static void main(String[] args)
{
int i;
for(i=0;i<5;i++)
{
System.out.println(i);
}
}
}
2:
public class For_Demo_2
{
public static void main(String[] args)
{
int i;
for(i=0;i<5;i++)
{
if(i==3)
{
break; //if I is 3 them break. op 0,1,2,3

}
System.out.println(i);
}
}
}

3:
public class For_Demo_3
{
public static void main(String[] args)
{
int i;
for(i=0;i<5;i++)
{
if(i==3)
{
continue; //is I=3 then continue op 0,1,2,4
}
System.out.println(i);
}
}
}
Nested for loop:
package datatypes_pro;

public class Nested_For_Demo


{
public static void main(String[] args)
{
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
System.out.println(i+"\t"+j);
}
System.out.println();
}
}
}

While loop: pre test loop


public class While_Demo
{
public static void main(String[] args)
{
int a=10;
// Pre-Test Loop
while(a<20)
{
System.out.println(a);
a++;
}
}
}
Do while loop: post test loop

public class Do_While_Demo


{
public static void main(String[] args)
{
int a=10;
// Post-Test Loop
Do
{
System.out.println(a);
a++;
}while(a<20);
}
}
Switch Case:
public class Switch_Demo
{
public static void main(String args[])
{
char ch='E';

switch(ch) // byte,int,short and char and Strin(After JDK7)


{
case 'A': System.out.println("Vowel A");
break;
case 'E': System.out.println("Vowel E");
break;
case 'I': System.out.println("Vowel I");
break;
case 'O': System.out.println("Vowel O");
break;
case 'U': System.out.println("Vowel U");
break;
default: System.out.println("Not a Vowel");
}
}
}

package firstpro;
import java.util.Scanner;
public class Demo1
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter a number");
int num=sc.nextInt();
System.out.println("Number accepted is\t"+num);

System.out.println("Enter amount");
double amount=sc.nextDouble();
System.out.println("Amount accepted is\t"+amount);

System.out.println("Enter login name");


String loginname=sc.next(); //not read afte space
System.out.println("Login name accepted is\t"+loginname);

System.out.println("Enter full name");


String fullname=sc.nextLine();// afte space all word read
System.out.println("Full name accepted is\t"+fullname);
}

the difference between "next()" or "nextFoo() and "nextLine()"


methods is:
next() or nextFoo() methods do not read the newline entered by user in
the previous input.
nextLine() method reads the newline entered by user in the previous
input.

Properties file:In that file we only send the English world in program
client provide there translation words in front of them and run code by
translate.

Demo 1:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int k) // member function


{
num=k;
}
public int getNum() // member function
{
return num;
}
}
public class Demo1
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
on heap
// m1.num=150; // not possible
m1.setNum(150);
System.out.println(m1.getNum());
}
}

Demo2:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int k) // member function


{
num=k;
}
public int getNum() // member function
{
return num;
}
}
public class Demo2
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
}
}

Demo 3:

class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int num) // member function


{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo3
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
}
}

what is "this"?

"this" is a reference which refers to the current or invoking object.

What is the importance of "this"?


when u create multiple objects, u have those many copies of
instance members however , u have only one copy of member function/s.
In that case how will member function keep a track of invoking object ?
member function/s will come to know about invoking or current object
through "this" reference.

can we use "this" with static members?


no because this refers to object and static are not associated
with objects.

How can we use "this" keyword in program?

private String name;


public void setName(String name)
{
this.name=name;
}

here "this.name" is an instance member and "name" is a local member.

Demo 4
class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int num) // member function


{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo4
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
m1=null;
what will happen to object where "m1" refers to ?
the object to which "m1" was referring to will be
marked for Garbage Collection ( provided no other reference referring
to that object) and after some time ( depends on JVM implementation) it
will be garbage collected.
System.out.println("done"); //done is printed
}
}

Demo 5:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter


public void setNum(int num) // member function
{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo5
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
m1=null;
System.out.println(m1.getNum()); // NullPointerException
// when reference contains "null" and we use it to invoke a member or
member function, we get "NullPointerException".
System.out.println("done"); //done not printed
}
}

Demo 6:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter


public void setNum(int num) // member function
{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo6
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
m1=null;
if(m1!=null) // this is the way you can avoid
"NullPointerException"
{
System.out.println(m1.getNum());
}
System.out.println("done"); //done will print
}
}

Demo 7:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter


public void setNum(int num) // member function
{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo7
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
m1=null; // only because "m1" contains "null", we'll not
get "NullPointerException"
// you get it only when u invoke any member with the help of "m1".
System.out.println("done");
}
}

Demo 8:

class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int num) // member function


{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo8
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
MyNumber m3=m2; // m3 refers to the same object where "m2"
refers to
m3.setNum(500);
System.out.println(m2.getNum()); // 500
m2=null; // no problem for the object since it is still
referred by "m3"
System.out.println(m2.getNum()); // NullPointerException

}
}

Demo 9:

class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int num) // member function


{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo9
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
MyNumber m3=m2; // m3 refers to the same object where "m2"
refers to
m3.setNum(500);
System.out.println(m2.getNum()); // 500
m2=null; // no problem for the object since it is still
referred by "m3"
m2=new MyNumber();

}
}
Demo 10:
class MyNumber
{
private int num; // instance member or member variable

// setter and getter

public void setNum(int num) // member function


{
this.num=num;
}
public int getNum() // member function
{
return num;
}
}
public class Demo10
{
public static void main(String args[])
{
MyNumber m1=new MyNumber(); // instance or object creation
m1.setNum(150);
System.out.println(m1.getNum());
MyNumber m2=new MyNumber();
m2.setNum(200);
System.out.println(m2.getNum());
MyNumber m3=m2; // m3 refers to the same object where "m2"
refers to
m3.setNum(500);
System.out.println(m2.getNum()); // 500
m2=null; // no problem for the object since it is still
referred by "m3"
m2=new MyNumber();
m2=m3; // m2 will refer to that object which is referred by
"m3" and the object which was referred by "m2" will be marked for GC

}
}

Class is blueprint just and idea:


Demo 11:
// call by value

public class Demo11


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
void disp1(int k)
{
k=200;
}
public static void main(String args[])
{
Demo11 s1=new Demo11();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1" by passing "num"
s1.disp1(s1.num);
System.out.println(s1.getNum()); // 100
}
}

Demo 12:
// call by value

public class Demo12


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
int disp1(int k)
{
k=200;
return k;
}
public static void main(String args[])
{
Demo12 s1=new Demo12();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1" by passing "num"
int result=s1.disp1(s1.num);
System.out.println(result); // 200
System.out.println(s1.getNum()); // 100
}
}

Demo 13,14:
// call by value

public class Demo13


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
void disp1(Demo13 ref) // Demo13 ref=s1; // ref refers to that
object where "s1" refers
{
ref.num=200;
}
public static void main(String args[])
{
Demo13 s1=new Demo13();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1"
s1.disp1(s1);
System.out.println(s1.getNum()); // 200
}
}

S1 and ref pointing to same object after scope completed ref is


destroyed but before destroy the value of object is changed to 200.
Demo 15:
// call by value

public class Demo15


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
void disp1(Demo15 ref) // Demo15 ref=s1; // ref refers to that
object where "s1" refers
{
ref=new Demo15();
ref.num=200;
}
public static void main(String args[])
{
Demo15 s1=new Demo15();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1"
s1.disp1(s1);
System.out.println(s1.getNum()); // 100
}
}

From disp one more object created on heap but scope is completed and
reference get destroyed
garbage collector call and mark object for garbage collection
Demo 16:

// call by value

public class Demo16


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
int disp1(Demo16 ref) // Demo16 ref=s1;// ref refers to that
object where "s1" refers
{
ref=new Demo16();
ref.num=200;
return ref.num;
}
public static void main(String args[])
{
Demo16 s1=new Demo16();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1"
int result=s1.disp1(s1);
System.out.println(result); // 200
System.out.println(s1.getNum()); // 100
}
}
Demo 17:
// call by value

public class Demo17


{
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
Demo17 disp1(Demo17 ref) // Demo17 ref=s1; // ref refers to
that object where "s1" refers
{
ref=new Demo17();
ref.num=200;
return ref;
}
public static void main(String args[])
{
Demo17 s1=new Demo17();
s1.setNum(100);
System.out.println(s1.getNum()); // 100
// call "disp1"
Demo17 ref1=s1.disp1(s1); // internally it becomes "Demo17
ref1=ref"
System.out.println(ref1.getNum()); // 200
System.out.println(s1.getNum()); //100
}
}
What is the difference between Procedural programming and OOPS?

1. Procedural language is based on functions but object oriented language is based on real world
objects.
2. Procedural language gives importance on the sequence of function execution but object
oriented language gives importance on states and behaviours of the objects.
3. Procedural language exposes the data to the entire program but object oriented language
encapsulates the data.
4. Procedural language is complex in nature so it is difficult to modify, extend and maintain but
object oriented language is less complex in nature so it is easier to modify, extend and
maintain.
5. Procedural language provides less scope of code reuse but object oriented language provides
more scope of code reuse.

Procedure Oriented Programming e.g. C:

 Gives importance to functions rather than data. Whenever any task is given developers try to
divide it into number of functions.
 Data can be global or local. Global data can be accessed or even altered by all the functions,
hence there is no data security.
 When the volume of application becomes large, it is very difficult to maintain the code.

 Doesn’t model real world problems very well. This is because functions are action-oriented
and do not really correspond to the elements of the problem (e.g.: Customer, Account, Vehicle
etc.)

Object-oriented programming (OOP) refers to software design in which programmers define not only
the data for a data structure, but also the types of operations (functions) that can be applied to the data.
 e.g
Account
acc_id
name
balance
setName(), getName()
Class

A Class is a plan which describes the object. We call it as a blue print of how the object should be represented.
Mainly a class would consist of a name, attributes & operations. Considering the above example,

A Mobile can be a class which has some attributes like Profile Type, IMEI Number, Processor, and some more.)

& operations like Dial, Receive & Send Message .

Objects:

Any real world entity which can have some characteristics or which can perform some work is called as Object.
This object is also called as an instance. If we consider the above

example, a mobile manufacturing company, at a time manufactures lacs of pieces of each model which are the
instances. These objects are differentiated from each other via some identity or its characteristics.
AbstractionAbstraction means Hiding an implementation and showing only essential features.It means
providing information about what object does instead of how it does.
Also called : Model Building
Example: Car Brakes(pressing the pedals will stop the vehicle but you do not need to know how it
works.)
Phone-when we make a call or receive a call we just know how to do that, we don't know the internal
working of the phone.
Data encapsulation -> Binding the data and functions together in one unit is called as "Encapsulation".
In java "class" is the example of Encapsulation.
-Things should be encapsulated in such a manner to achieve abstraction

Function Overloading:
Function overloading means defining more than one function with the same name but with different arguments.

e.g.

Void Add(int a,int b);

Void Add(char a,char b);

 Local member is initialized before use:

Eg.1)Int data;

System.out.println(data); //this is wrong get error

Eg.2)int A;

A=20;

System.out.print(A) //here we initialized A before use so we get output correct and no error

JDK(Java development kit):allows you to write the program and run the program

JRE(Java runtime environment)

Why do you need JRE in between java application and operating system.
Each operating system has got something called native code ,now what is job of native code it is used to execute
any program

.class file format is different from respective of native code JRE knows how to convert .class format into
windows native code,JRE on windows will convrt .class file format in windows native code.

JRE is different for diff platforms(OS)

Java is only software and platform

OS is only platform

Source file declaration:

Source File Declaration Rules

Before we dig into class declarations, let's do a quick review of the rules associated with declaring
classes, import statements, and package statements in a source file:

■ There can be only one public class per source code file.
Public class demo{
p.s.v.m(){
}
}
Public class A{ //it is not allowd
}

■ Comments can appear at the beginning or end of any line in the source code file; they are
independent of any of the positioning rules discussed here.

■ If there is a public class in a file, the name of the file must match the name of the public class. For
example, a class declared as public class Dog { } must be in a source code file named Dog.java.

Public class demo{


p.s.v.m(){
}
}

Save By: demo.java


To compile: javac demo.java
We get: demo.class
To run: java demo //jvm comes and check there is have main and run the code

■ If the class is part of a package, the package statement must be the first line in the source code file,
before any import statements that may be present.

Package workplace; //package must be declared in first line


Import java.util.*;

■ If there are import statements, they must go between the package statement (if there is one) and the
class declaration. If there isn't a package statement, then the import statement(s) must be the first
line(s) in the source code file.
If there are no package or import statements, the class declaration must be the first line in the source
code file.

■ import and package statements apply to all classes within a source code file.
In other words, there's no way to declare multiple classes in a file and have
them in different packages, or use different imports.

■ A file can have more than one nonpublic class.


Class A{
}
Class C{
}
Public class B{
}
■ Files with no public classes can have a name that does not match any of the classes in the file.

3)
Class A{
Main{
}//in A class there is main so A class only executed
}
Class B{
}
Flow:
A.java //save
Javac A.java //compile
A.class //weget
Java A //run
Invitation of jvm_ it will check main()_ &main is not their_ it will throw the error
If main get_ call to that class_ If any class declared In class A_ then that class called.

4)
Class A
{
B class execute when function call
}
Class B
{
}

Automatic garbage collection:


Automatic garbage collection is the process of looking at heap memory, identifying which objects are
in use and which are not, and deleting the unused objects. An in-use object, or a referenced object,
means that some part of your program still maintains a reference to that object. An unused object, or
unreferenced object, is no longer referenced by any part of your program. So the memory used by an
unreferenced object can be reclaimed.
Default value of each datatype:
default value of byte is 0
default value of short is 0
default value of int is 0
default value of long is 0

default value of float is 0.0


default value of double is 0.0
default value of char is _ \u0000
default value of boolean is false
default value of String is null

constructor

is a special member function.

It is special because

a) it is used to initialize instance members.


b) it has no return type
c) it is called as soon as object is created.

There are 2 types of constructors in java.

a) default or no-arg constructor


b) parameterized constructor

a) default or no-arg constructor


it is a constructor with no arguments.
e.g.
MyClass()
{
}

when u don't define any constructor in the class, compiler provides


default or no-arg constructor.

b) parameterized constructor
constructor with at least one argument.
e.g.
MyClass(int k)
{
}
this has to be explicitly provided by the programmer.

e.g.
public class MyClass11
{
int num;
MyClass11(int num)
{
this.num=num;
}
MyClass11()
{
}
p.s.vm
{
MyClass11 m2=new MyClass11(200); // you need parameterized
constructor
MyClass11 m1=new MyClass11(); // you need default or no-arg
constructor
}
}

e.g1:
class Sample
{
// Compiler provides "default constructor" here

private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
}
public class ConstructorDemo1
{
public static void main(String args[])
{
Sample s1=new Sample(); // will invoke "default
constructor" provided by compiler
s1.setNum(200);
System.out.println(s1.getNum());
}
}

e.g2:
class Sample
{

Sample()
{
System.out.println("inside default constructor");
}
private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
}
public class ConstructorDemo2
{
public static void main(String args[])
{
Sample s1=new Sample(); // will invoke "default
constructor" provided by compiler
s1.setNum(200);
System.out.println(s1.getNum());
}
}
e.g3:
class Sample
{

Sample()
{
System.out.println("inside default constructor");
}

Sample(int num)
{
this.num=num;
System.out.println("inside parameterized constructor");
}

private int num;

public void setNum(int num)


{
this.num=num;
}
public int getNum()
{
return num;
}
}
public class ConstructorDemo3
{
public static void main(String args[])
{
Sample s1=new Sample(); // will invoke "default
constructor" provided by compiler
s1.setNum(200);
System.out.println(s1.getNum());
Sample s2=new Sample(100); // will invoke "parameterized
constructor"
System.out.println(s2.getNum());
}
}

Finalize function:
java does not have destructor.
just before object gets garbage collected, following method gets
called. Programmer can override(define) this finalize method in order
to release resources such as file, database connection or sockets.

protected void finalize()


{
}

Since there is no guarantee as to when exactly object will get garbage


collected, u can not rely upon "finalize" method to release the
resources such as Connection , Socket etc.

Garbage collection can not be forced in java. U can just make a request
for Garbage Collection , by invoking a method "System.gc()". or
"Runtime.getRuntime().gc()".

gc() method is used to request for garbage collection.


inside System class we have following method:
public static void gc()
{
Runtime.getRuntime().gc();
}

static member

static members are allocated memory as soon as class gets loaded in the
memory. They are not associated with the instance.
Since they are not associated with instance, they have only one copy in
the memory, irrespective of no.of instances created.
They can be accessed by class name. They are also called as "class
variables".

static member function is used to access private static member.

e.g.
Account object
non-static members - accid, name, balance
static member - rateofinterest.
Can static member function access non-static data ?
No. because static member function can be called without creating object. When object is not created,
non-static member is not allocated memory.

Can non-static member function access static data ?


Yes. Because in order to invoke non-static member function u need to create object and by that time
static members are already allocated memory

static block or static initializer

syntax

static
{

a) static block is used to access static variables.


b) static block gets invoked as soon as class gets loaded.
c) u can define more than one static blocks inside class definition.
They will be executed in the order in which they are defined.

static block vs static member function

static member function needs to be called explicitly whereas static


blocks are called implicitly , as soon as class gets loaded.

Static member function:


class Sample
{
private int num;
private static int cnt=10;
public Sample(int num)
{
this.num=num;
}
public void setNum(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public static int getCnt()
{
return cnt;
}
}

public class MyClass8


{
public static void main(String args[])
{
Sample s1=new Sample(100);
System.out.println(s1.getNum());

Sample s2=new Sample(200);


System.out.println(s2.getNum());
System.out.println(Sample.getCnt());

}
}

What happens when you execute java Application?


1)Myclass get loaded
2)Jvm invokes main function
3)main function Is static in java because jvm can call main function
without creating object for class.
4)main function is returs void because for jvm does not need to return
anything
5)main function is public because jvm can access it.

e.g.

class MyClass
{
public static void main(String args[])
{
System.out.println("Welcome to java");
}
}

java MyClass
a) MyClass gets loaded.
b) JVM invokes "main" function.
What are Class Loaders ?
1.footstrap loaders or parameterized class loaders //bootstrap prog load from that
2.extension class loaders //intermediate programs load
3.system class loaders //hi hello simple program load from that
//there is multiple classes in java to work load distribute class loader created

What is class "Class" in java ?


In java whenever any class gets loaded it is represented by instance of class "Class".
This instance holds information about loaded class such as member variables, methods, constructors
etc.
public class MyClass
{
public static void main(String args[])
{
System.out.println(“hello world”);
}
}
Now when you run this application:
MyClass will be loaded and it will be represented by an instance of class “Class”.
class A

private int var=200;

public static void fun()

System.out.println(“inside fun”);

public class MyClass

private int num=100;

public static void main(String args[])

MyClass m1=new MyClass();

System.out.println(“hello world”);

A.fun(); // Then in the main function we have created an instance of class “A” , so class “A” will
be loaded here. This also means that we will have one more instance of class “Class” representing class “A”.

}class object directly save in Class on heap


*Static block or initializer:
1)
public class MyClass9
{
static
{
System.out.println("in MyClass9 first static
initializer");//first this call
}
public static void main(String args[])
{
System.out.println("in main");
}
}

2)
public class MyClass10
{
static
{
System.out.println("in MyClass10 first static
initializer");//1
}
public static void main(String args[])
{
System.out.println("in main"); //3
}

static
{
System.out.println("in MyClass10 second static
initializer");//2
}

3)
public class MyClass11
{
static
{
System.out.println("in MyClass11 first static initializer");
}
public static void main(String args[])
{
System.out.println("in main");
}

static
{
System.out.println("in MyClass11 second static
initializer");
}
}
class A
{
static
{
System.out.println("in A first static initializer"); //a not
called
}
}

4)
public class MyClass12
{
static
{
System.out.println("in MyClass12 first static
initializer");//1
}
public static void main(String args[])
{
System.out.println("in main");//3
new A();
}

static
{
System.out.println("in MyClass12 second static
initializer");//2
}
}
class A
{
static
{
System.out.println("in A first static initializer");//4 }
}

/*create as many as instances of this class. At the end display how


many instances u have created. */

public class MyClass13


{
int num;
static int cnt;
public MyClass13()
{
cnt++;
}
public MyClass13(int num)
{
this.num=num;
cnt++;
}
public void setNum(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public static int getCnt()
{
return cnt;
}
public static void main(String args[])
{
MyClass13 m1=new MyClass13();
MyClass13 m2=new MyClass13(200);
m1.setNum(100);
System.out.println(m1.getNum());
System.out.println(m2.getNum());
System.out.println(MyClass13.getCnt());
MyClass13 m3=new MyClass13(300);
System.out.println(m3.getNum());
System.out.println(MyClass13.getCnt());
}

}
But there is error in that program is that if we need to add more
function we need to add constructor also and also if we miss to provide
cnt++ show wrong op
So we will use non static block
Non Static block:
non static block used before constructor and it will execute before each & evry constructor is called it
is use for repetitive operation.

/*create as many as instances of this class. At the end display how


many instances u have created. */

public class MyClass14


{
int num;
static int cnt;

// non-static initializer

{
cnt++; //using this counter count each time when
object created
}
public MyClass14()
{

}
public MyClass14(int num)
{
this.num=num;

}
public void setNum(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public static int getCnt()
{
return cnt;
}
public static void main(String args[])
{
MyClass14 m1=new MyClass14();
MyClass14 m2=new MyClass14(200);
m1.setNum(100);
System.out.println(m1.getNum());
System.out.println(m2.getNum());
System.out.println(MyClass14.getCnt());
MyClass14 m3=new MyClass14(300);
System.out.println(m3.getNum());
System.out.println(MyClass14.getCnt());
}

}
final keyword:
when "final" keyword is applied to any member, that means it is constant, once it is initialized.
final member must be initialized.

final keyword can be applied to


a) instance member
b) class variable
c) local variable
d) member function
e) class
e.g.
public class Demo4
{
int k=60;
final int num1=30;
final static int num2=40;
public static void main(String args[])
{
final int num3=50;
System.out.println(new Demo4().num1+"\t"+num2+"\t"+num3);
new Demo4().k=90;
new Demo4().num1=20; // Error
}
}

*Final member must be initialized through constructor-


class Sample
{
final int id;
Sample(int id)
{
this.id=id;
}
Sample()
{
id=0;
}
int getId()
{
return id;
}
}
public class FinalDemo
{
public static void main(String args[])
{
Sample s1=new Sample(1);
Sample s2=new Sample(2);
System.out.println(s1.getId()+"\t"+s2.getId());
// s1.id=4; it will not compile
Sample s3=new Sample();
System.out.println(s3.getId());
}
}

S.O.P:
class System
{
public static PrintStream out;
public static InputStream in;
}
class PrintStream
{
public void print(){}
public void println(){} //printstram have print() & println()
}

System.out.println();
out.ptintln()  we create reference of printStream class and call println function by out.println()
System.out -> out is static member so to call out class_name.member.System is the class.
a) “hello” need to be displayed
b) U need to invoke “print()” or “println()” method println(“hello”)
c) Both the methods are not static in “printstream” class, so you need to reference of
”Printstream” class.
d) “out” is reference of “prinstream” & member of system & type of printstream
out.printstream(“Hello”)
e) Out is a member of system & that member is static in order to access the member no need to
create object of class whenever we want to access the out we did not create object of system
directly call with class name.

What is Singleton:

// developer part
class Singleton
{
private static Singleton obj=new Singleton(); //always object
created on heap

private Singleton() //make constructor private


{
}

void disp1()
{
System.out.println("in disp1");
}
void disp2()
{
System.out.println("in disp2");
}

// provide a method which will return "obj"


public static Singleton getSingleton()
{
return obj; //return obj
}
}

// client part
public class SingletonDemo
{
public static void main(String args[])
{
// Singleton s1=new Singleton(); // not allowed=not possible
bcoz constructor is private
// Singleton ref=Singleton.obj; // not possible singleton
cannot resolved because it is private
Singleton ref=Singleton.getSingleton();
ref.disp1();
ref.disp2();
Singleton.getSingleton().disp1();
}
}

only one object created , that too inside the class.


clients are not allowed to create object- private constructor.
non-static methods , client can call.
static method which will return the reference of the only object which u have created inside the class.

if you want to invoke 6-7 functions from main, is it advisable to make them static so that we can
invoke with the syntax "classname.function" ?
non-static method
works on the state of the object. -means for every call we need to create object
static method
is used to access private static variable.
it's a utility method. That means whatever data is provided during invocation static method
works on it and performs the action.
-don’t use static in every time use for important purpose
lazy_eager_resolution
class Sample
{
int num1=100; // num1 will be allocated memory only after we create object/s
static int num2=200; // num2 will be allocated memory as soon as Sample class gets loaded.
}
class A { }
class B { }

class Sample
{
private A ob1=new A(); // class A will be loaded only after first object of Sample gets created.
- lazy resolution

private static B ob2=new B(); // class B will be loaded immediately after class Sample gets
loaded - eager resolution
}

demo
package firstpro;

class A
{
static
{
System.out.println("inside A static block");
}
}
class B
{
static
{
System.out.println("inside B static block");
}
}
public class Demo1
{
private A ref1=new A(); // lazy resolution
private static B ref2=new B(); // eager resolution_that first
because static

public static void main(String[] args)


{
System.out.println("in main");
new Demo1(); // class A will be loaded now
}

output:

inside B static block


in main
inside A static block

demo2:
package firstpro;

class A
{
static
{
System.out.println("inside A static block");
}
}
class B
{
static
{
System.out.println("inside B static block");
}
}
public class Demo2
{
private A ref1=new A(); // lazy resolution
private static B ref2=new B(); // eager resolution
public static void main(String[] args)
{
new Demo2(); // class A will be loaded now
System.out.println("in main");
new Demo2(); // class A will not be loaded again as
// classes are loaded only once in Java
}
}
O/p
Ref2
Ref1
In main
Array:

Final array:
public class FinalArrayDemo
{

public static void main(String args[])


{
final int arr[]=new int[3];//you cannot make that reference
to any other element but array elements can modified
arr[0]=10;
arr[1]=20;
arr[2]=30;
// arr=new int[4]; error size cant be chaged
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
arr[1]=100; // no problem
System.out.println("After modifying");
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
2)
int arr[]=new int[3];
arr[0]=10;
arr[1]=20;
arr[2]=30;
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}

3)
public class ArrayDemo3
{
public static void main(String args[])
{
int arr[]={10,20,30};

for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}

4) package core1;

public class ArrayDemo4


{
public static void main(String args[])
{
int arr[][]=new int[3][3];
arr[0][0]=10;
arr[0][1]=20;
arr[0][2]=30;
arr[1][0]=40;
arr[1][1]=50;
arr[1][2]=60;
arr[2][0]=70;
arr[2][1]=80;
arr[2][2]=90;

for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr[i].length;j++)
{
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}

5) public class ArrayDemo5


{
public static void main(String args[])
{
int arr[][]={{10,20,30},{40,50,60},{70,80,90}};

for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr[i].length;j++)
{
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
6)public class ArrayDemo5
{
public static void main(String args[])
{
int arr[][]={{10,20,30},{40,50,60},{70,80,90}};

for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr[i].length;j++)
{
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}

7) public class ArrayDemo7


{
public static void main(String args[])
{
int arr[][]={{10,20,30},{40,50},{60,70,80,90}}; // jagged
array

for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr[i].length;j++)
{
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}

package

package is a collection of related classes and interfaces.


package is mainly used to avoid name conflicts.
package concept is similar to "namespace" concept of C++.

java has so many in-built packages . e.g.


java.awt
java.io
java.util
java.lang
and so on

by def. java.lang is available to all the java applications.

in order to use package u need to use the keyword "import".


when u say "import", nothing is physically included ( unlike #include
of c and c++ ). It is only for compiler. Runtime performance is not at
all affected with "import" statements.

Array of instances/object:
public class ArrayOfInstance
{
public static void main(String args[])
{
MyClass arr[]=new MyClass[3]; // array of references to
MyClass

for(int i=0,j=10;i<arr.length;i++,j+=10)
{
arr[i]=new MyClass(j); // object creation//array value
is updated in each loop i=0 j=10 ,i=1 j=20,i=2 j=30
}

for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i].getNum());
}
}
}

class MyClass
{
int num;
MyClass(int num)
{
this.num=num;
}
int getNum()
{
return num;
}
}

package info
package is a collection of related classes and interfaces.

package is mainly used to avoid name conflicts.


package concept is similar to "namespace" concept of C++.

java has so many in-built packages . e.g.

java.awt
java.io
java.util
java.lang
and so on

by def. java.lang is available to all the java applications.

in order to use package u need to use the keyword "import".

when u say "import", nothing is physically included


( unlike #include of c and c++ ). It is only for compiler. Runtime
performance is not at all affected with "import" statements.

jar is a compression utility in java.


it can compress any type of files upto 50%.
james gostlie created files also in jar
predefined classess available in jar

syntax

jar <options> <name of jar file> <file/s or folder/s to be compressed>

jar file has to be saved with an extension ".jar"

options are
c - create
f - file
u - update. i.e. to add more file/s to an existing jar file
x - extract the file/s
t - test the jar file
m - manifest. i.e. serving some imp information.

Developer and Client

Developer - James Gosling and his team


who defines class or classes [ as a part of package/s ]

what have they done?

1) They have defined all the classes as a part of some or


other package.
2) They have compiled those classes.
3) They have stored all those .class files inside "jar"
file. [ JRE/lib ]

4) They have created documentation of all the classes which


have been developed [ javadocs ]

5) They have shared "jar" files and "javadocs" with us.

Client - we all
who use those classes developed by developer.

How do we use the class/s developed by James Gosling and his


team?

1) we go through javadocs to get information about class/s


2) since jar files are associated with JDK , we can easily
use them.

Devloper and client steps:


For developer side;

1)creat class in root


2)create pacakage
3)creat class(generate comments)
4)add getter setter and int num
5)add constructors
6)create class 2
7)create setter getter and constructor
8)p1 right click export jar file next select path
9)select 2 files and project generate java doc ente bin path in jdk
Enter client doc folder path
10)create project of client root and add package class client
11)right click on client build path configure build path classpath add
external jars
12)ctrl shift o
13)create object and call functions in jar

Reusability
means using existing type while defining a new type. It can be achieved in two ways:
a) composition/aggregation [has-a relationship]
b) inheritance [is-a relationship]

you go for composition/aggregation when you want to use some of the functionalities of existing type
inside new type.
e.g.
while designing "Car" you would reuse "Engine" by composition/aggregation, because "Car"
is not an "Engine" it just needs some functionalities of Engine.

you go for inheritance when you realize that new type is "same as" existing type.
e.g.
while designing "Car" you would reuse "FourWheeler" because Car is same as FourWheeler.

Inheritance:
The ability for a new class to be created from an existing class by extending it is known as
inheritance. It provides reusability. Basically you go for inheritance when u realize that "new type is
same as existing type".
e.g.
class Person
{
private String name,address;
private int age;
// setters and getters
}
now we can derive "Student" class from Person.
class Student extends Person
{
private String qualification;
private int rollno,ccppid;

//setters and getters


}
Here Student can inherit "name","address" and "age" from "Person" class.

Java allows only 3 types of inheritance


a) single level b) multi-level c) Hierarchical
Inheritance is inbuilt in java i.e. if your class is not derived from any base class, "java.lang.Object" is
the base class of it.
Access Specifier:
1)Private:

2)Default

3)Protected
4)Public

Note:
Top level classes are the classes which are not nested classes(means class within classes)
In java rule is top level class can be either “Public” or “Default” it cannot be “Private” or “Protected”
But nested classes have all access modifier
In java by default parent is Java.lang.object

Demo1:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1); //First print disp1
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2); //second print disp2
}
}
public class Demo1
{
public static void main(String args[])
{
sub s1=new sub();
s1.disp1();
s1.disp2();
}
}

Demo2:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base()
{
System.out.println("in base no-arg"); //from base invoke nd
execute and print and then sub execute
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub()
{
System.out.println("in sub no-arg"); // from main we invoke
sub constructor then implicitly invoke to base constructor
}
}
public class isa
{
public static void main(String args[])
{
sub s1=new sub();
s1.disp1();
s1.disp2();
}
}

//
in base no-arg
in sub no-arg
10
20

// what if base class does not have a no-arg constructor ?

Demo3:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}

base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub()
{
System.out.println("in sub no-arg"); //no def constructor in
base /and we cannot invoke base parameterized constructor from sub
}
}
public class isa
{
public static void main(String args[])
{
sub s1=new sub(); // Error
s1.disp1();
s1.disp2();
}
}
//Show error

Demo 4:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub()
{
super(10); //super is use to explicitly invoke base para
constructor
System.out.println("in sub no-arg");
// super(10); Error, super has to be on first line
}
}
public class Demo4
{
public static void main(String args[])
{
sub s1=new sub();
s1.disp1();
s1.disp2();
}
}

Demo 5:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub()
{
super(10);
System.out.println("in sub no-arg");
}
sub(int num2)
{
this.num2=num2;
System.out.println("in sub param"); //show error bcoz in
only one constructor have explicitly invoking
}
}
public class Demo5
{
public static void main(String args[])
{
sub s1=new sub();
s1.disp1();
s1.disp2();
}
}

/
Demo 6:
/ when base class does not have "no-arg constructor", all the
constructors of sub class must explicitly invoke "parameterized
constructor" of base class.
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub()
{
super(10);
System.out.println("in sub no-arg");
}
sub(int num2)
{
super(20);
this.num2=num2;
System.out.println("in sub param");
}
}
public class Demo6
{
public static void main(String args[])
{
sub s1=new sub();
s1.disp1();
s1.disp2();
}
}

Demo 7:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base //error bcoz we do not def constructor in
sub1/we do not pass value to parameterized
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
this.num3=num3;
}
}
public class isa
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}

Demo 8:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub1()
{
super(5);
} //in multilevel now program run correct
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
this.num3=num3;
}
}
public class Demo8
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}

Demo 9:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub1()
{
super(5);
}
sub1(int num2) //we not explicit call to para constructor
{
this.num2=num2;
}
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
this.num3=num3;
}
}
public class Demo9
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}

Demo 10:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub1()
{
super(5);
}
sub1(int num2)
{
super(8); //explicit call to para
this.num2=num2;
}
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
super(45);
this.num3=num3;
}
}
public class Demo11
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}

Demo 11:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub1()
{
super(5);
}
sub1(int num2)
{
super(8);
this.num2=num2;
}
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
super(45); //para call
this.num3=num3;
}
}
public class Demo11
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}

Demo 12:
class base
{
int num1=10;
void disp1()
{
System.out.println(num1);
}
base(int num1)
{
this.num1=num1;
System.out.println("in base param");
}
}
class sub1 extends base
{
int num2=20;
void disp2()
{
System.out.println(num2);
}
sub1()
{
super(5);
}
sub1(int num2)
{
super(8);
this.num2=num2;
}
}
class sub2 extends sub1
{
int num3=30;
void disp3()
{
System.out.println(num3);
}
sub2(int num3)
{
super(45);
this.num3=num3;
}
sub2(int a,int b) //no any error from this
{
num3=a;
}
}
public class Demo12
{
public static void main(String args[])
{
sub2 s1=new sub2(10);
s1.disp1();
s1.disp2();
s1.disp3();
}
}
Overriding
It is a feature to provide specific behaviour to parent class.

1) arguments must be same otherwise it becomes "overloading".

(overloading:same functions name with different arguments


overriding: same function name with same behaviour and arguments must
be same)

2) returntype of overriding can be co-variant.


if overridden method has "parent" as a return type then overriding
method can have "child" as a return type.

class fourwheeler{
fourwheeler disp1()
{
//overriden
}
}
class car extends fourwheeler{
car disp1() //overriding (covariant return type)
{
}
}

3) overriding method must be having same or more accessibility as


compare to overridden method.
class base
{
void disp()---------------------------> <default> protected public
{ protected public
sop() public
^
}
protectcted
}
^
class sub extends base

{
void disp()---------------------------> <default> protected public
{ protected public
sop() public

}
}

Base is overriden private->overriding accessiblity in sub is


default,protected,public
base is default->accessiblity in sub is default,protected,public
base is protected->accessiblity in sub is protected,public
base is public->accessiblity in sub is public
*all methods in inbuild classes are 99% public
4) overriding and checked-exception rule :

a) overriding method may not declare any checked exception.


b) overriding method can declare same checked exception or its sub-type
declared by overriden method.
c) overriding method can not declare checked exception not declared by
overriden method.

Final method:
If method is final we cannot override

Why we make method final?


When method is more than sufficient for any given scenario then we make
method final.
(jar apan konti class perfect banavli tar developer is sure so no need
to write child class method so we make parent final)

Demo 13:
class base
{
void disp() // overridden
{
System.out.println("base disp"); //hide that disp
}
}
class sub1 extends base
{
void disp() // overriding
{
System.out.println("sub disp");
}
}
public class isa
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 14:

class base
{
void disp() // overriden
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp() // overriding
{
System.out.println("sub disp");
super.disp(); //now disp of base call
}
}
public class Demo14
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}

Demo 15:
class base
{
final void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp() // error,can not override final method
{
System.out.println("sub disp");
}
}
public class Demo15
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 16:

class base
{
final void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
/* void disp() // error,can not override final method if we hide
that automatically invoke base
{
System.out.println("sub disp");
}*/
}
public class Demo16
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}

Final class:
Final class cannot be inherited

Why we make final class?

If whatever class is more than sufficient for any scenario then the
developer make final class for e.g String class

Demo 17
final class base
{//when class make final then class make final

}
class sub1 extends base
{

}
public class isa
{
public static void main(String args[])
{
base s1=new base();

}
}
Demo 18 no any changes
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub disp");
}
}
public class isa
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}

Demo 19:
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp(int k) // overloading
{
System.out.println("sub disp");
}
}
public class Demo19
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 20:

// example of co-variant return type


class A{}
class B extends A{}

class base
{
A disp()
{
System.out.println("base disp");
return null;
}
}
class sub1 extends base
{
A disp()
{
System.out.println("sub disp");
return null;
}
}
public class Demo20
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 21:
// example of co-variant return type
class A{}
class B extends A{}
class base
{
A disp()
{
System.out.println("base disp");
return null;
}
}
class sub1 extends base
{
B disp() // co-variant return type
{
System.out.println("sub disp");
return null;
}
}
public class Demo21
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 22:
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
/*void disp()
{
System.out.println("sub disp");
}*/
/*protected void disp()
{
System.out.println("sub disp");
}*/
public void disp()
{
System.out.println("sub disp");
}
}
public class Demo22
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}

Disp 23:
class base
{
protected void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp() // error
{
System.out.println("sub disp");
}
/*protected void disp()
{
System.out.println("sub disp");
}
public void disp()
{
System.out.println("sub disp");
}*/
}
public class Demo23
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}
Demo 24:
class base
{
public void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
/*void disp() // error
{
System.out.println("sub disp");
}*/
/*protected void disp() // error
{
System.out.println("sub disp");
}*/
public void disp()
{
System.out.println("sub disp");
}
}
public class Demo24
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp();
}
}

what is Binding?

resolving function call with function body is called as Binding.

how many types of Binding are there?

2 types: early binding and late binding

early binding means resolving function call with function body at


the compilation time.
In Java early binding happens when a function is "private" or
"static" or "final".

late binding means resolving function call with function body at


the runtime.
for the methods other than "private" or "static" or "final" we
have always late binding in java.

By default in java late binding happen


Late binding is also called dynamic binding \ run time polymorphism
Demo 25:
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub disp");
}
}
public class Demo25
{
public static void main(String args[])
{
base ref=new sub1(); // upcasting
ref.disp(); // late binding
}
}

Ref.disp()
1.type(always compiler knows)======in early
binding(static,final,private)
2.content(can be changed or runtime also) ====in late binding(remaining
else)

Ref.disp()
Ref= type of ref is base

What is role of compiler in case of late binding?

Base ref =new sub1()


Ref.disp()

For compiler “ref ” is of type “base”


Compiler will search “disp” in base
If it is there = yes
If it is accessible =yes
Is it private static or final =no
Ok,Then it will go “late binding”

Complier write instruction for jvm to follow


Look at the content of ref and invoke disp() accordingly (during
runtime)
Ref.print()

For compiler “ref” is of type “base ”


Compiler will search “print” in base
Is it there =no
Compiler error

Demo 26:

class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub1 disp");
}
}
class sub2 extends sub1
{
}
public class isa
{
public static void main(String args[])
{
base ref=new sub2(); // upcasting
ref.disp(); // late binding
}
}
Demo 27:
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub1 disp");
}
void print()
{
System.out.println("sub1 print");
}
}
public class isa
{public static void main(String args[])
{
base ref=new sub1(); // upcasting
ref.disp(); // late binding
ref.print(); //error
}}
Day 5:
Example 1:
class Animal
{
void makeSound()
{
}
}
class Tiger extends Animal
{
void makeSound() // overriding makeSound() of Animal
{
S.o.p("roar");
}
}
class Dog extends Animal
{
void makeSound() // overriding makeSound() of Animal
{
S.o.p("bark");
}
}
class Cat extends Animal
{
void makeSound() // overriding makeSound() of Animal
{
S.o.p("meow");
}
}
public class AnimalDemo1
{
p.s.v.main(String args[])
{
// create objects of Tiger, Dog and Cat
// invoke "makeSound()" on these objects
Tiger t1=new Tiger();
t1.makeSound();
Dog d1=new Dog();
d1.makeSound();
Cat c1=new Cat();
c1.makeSound();
}
}

so in the above case when we write "makeSound()" in all the child


classes ,
what exactly are we doing ?

we are overriding "makeSound()" method in all these child classes.

When do we do overriding?

when behaviour is same ( makeSound ) but implementations are


different ( roar/bark/meao)
class Animal
{
void makeSound()
{
}
}
class Tiger extends Animal
{
void makeSound()
{
S.o.p("roar");
}
}
class Dog extends Animal
{
void makeSound()
{
S.o.p("bark");
}
}
class Cat extends Animal
{
void makeSound()
{
S.o.p("meow");
}
}
public class AnimalDemo2
{
static void perform()
{
accept a choice from user i.e. whether Dog , Cat or Tiger
based on that create object and invoke "makeSound()"
[ use scanner to accept a string and switch... case to
invoke methods ]
e.g. Scanner...... // input
String choice
switch(choice)
{
/*case "dog": Dog d=new Dog();
d.makesound();*/
case "cat": Cat c=new Cat();
c.makesound();
case "lion": Lion t=new Lion();
t.makesound();
case "elephant": Elephant e=new Elephant();
e.makesound();
default: S.o.p("invalid choice");
}
}
p.s.v.main(String args[])
{
// invoke "perform()" here

}
}
let's hope that your code is working fine now.

add one more child class of Animal i.e. "Elephant" and override
"makeSound()" in it.

now how will you change "perform()" method ?

what you need to do here is:


define one more child class of Animal i.e. Elephant ,
override "makeSound()" and add one more case for "Elephant" inside
switch block

let's hope that your code is working fine now.

remove the class "Tiger" from your hierarchy and think what change do
you need to make inside "perform()" so that code will work fine.

you must have seen that whenever any changes happen to our class
hierarchy, we need to make changes in the "perform()" method. This is
called as "Maintenance drawback".

So how will we ensure that our perform() method remains unchanged no


matter what way our hierarchy changes.

create a new project


AnimalDemo3 class
with main function

copy Animal hierarchy from previous project

make following changes in the "perform()" and main() functions

static void perform(Animal ref)


{
ref.makeSound();
}

main()
{
invoke perform by passing instances of Animal child classes

perform (new Tiger());


perform (new Dog());
perform (new Cat());

}
in the above code "ref" is of type "Animal". But it can take any child
class object as an argument. When we pass any child object to "ref" [
which is of parent class type ] , it is known as "Upcasting".

inside "perform()" , we have written "ref.makeSound()" . So which


"makeSound()" does it call ?

answer is whichever child object we pass during runtime, its


"makeSound()" method gets called. Since this method invocation happens
at "Runtime", it is known as "Dynamic or Runtime Polymorphism".

create a new project

AnimalDemo4 class with


main function

copy entire Animal hierarchy and

make following changes to "Tiger" class:

class Tiger extends Animal


{
void makeSound()
{
S.o.p("roar");
}
void hunting()
{
S.o.p("hunting");
}
}

copy "perform()" method from the previous code and paste it inside
"AnimalDemo4" class.

now think how will you invoke "hunting()" method from "perform()"
method ?

void perform(Animal ref)


{
ref.makeSound();
// we would like to invoke "hunting()" alongwith "makeSound()"

void perform(Animal ref)


{
ref.makeSound();
// we would like to invoke "hunting()" alongwith
"makeSound()"
ref.hunting(); // compilation error check Is there hunting
is present in inside animal so not present so show error

Tiger t1=new Tiger();


t1.hunting(); //makesound different tiger and hunt
different tiger

}
p.s.v.main(String args[])
{
perform(new Dog());
perform(new Cat());
perform(new Tiger());
perform(new Elephant());

even though above code works it is not logically right because what we
are doing is the tiger object which is created inside main function on
that we are performing "makeSound" and inside "perform()" we are
creating a new tiger on which we are invoking "hunting()".

The solution is we have to invoke "hunting()" method exactly on the


same object which is passed from main.

.... discussion and solution of the above issue

Solution:

just copy entire code and paste it in a new project.

make following changes in perform and main functions:

void perform(Animal ref)


{
ref.makeSound();
Tiger t=(Tiger)ref; // convert from parent to child i.e.
downcast by typecasting first check tiger object is accessible in ref
then both t and ref point towards same object
t.hunting(); //then same object is hunt
}
p.s.v.main(String args[])
{
//perform(new Dog());
//perform(new Cat());
perform(new Tiger());
//perform(new Elephant());
}

downcasting is used when you want to invoke a method of child class


which is not there in the parent class.
just copy entire code and paste it in a new project.

make following changes in main functions:

void perform(Animal ref)


{
ref.makeSound();
Tiger t=(Tiger)ref; // convert from parent to child i.e.
downcast
t.hunting();
}
p.s.v.main(String args[])
{
perform(new Dog());
perform(new Cat());
perform(new Tiger());
perform(new Elephant());
}

save and run the above code.

what happend?

you get "ClassCastException" because when ref contains objects other


than "Tiger" we are trying to convert them to "Tiger" which is
logically wrong.

what is the solution?

we need to put a condition. i.e. only when "ref" contains "Tiger"


we should downcast.
How will we do that?

make following changes in the "perform()" method.

void perform(Animal ref)


{
ref.makeSound();
if(ref instanceof Tiger) // if ref refers to "Tiger"
{
Tiger t=(Tiger)ref; // convert from parent to child
i.e. downcast
t.hunting();
}
}
Second example

create a new project


create a class "Electronic_Demo1" with main function.

class Electronic_Appliance
{
void on()
{
}
void off()
{
}
}
class TV extends Electronic_Appliance
{
void on()
{
S.o.p("TV on");
}
void off()
{
S.o.p("TV off");
}
}

class Refrigerator extends Electronic_Appliance


{
void on()
{
S.o.p("Refrigerator on");
}
void off()
{
S.o.p("Refrigerator off");
}
}
class Washing_Machine extends Electronic_Appliance
{
void on()
{
S.o.p("Washing_Machine on");
}
void off()
{
S.o.p("Washing_Machine off");
}
}
public class Electronic_Demo1
{
static void perform()
{
// how will you achieve dynamic polymorphism ?
// you need to invoke "on" and "off" on a specific appliance
which is passed to "perform" method
}
p.s.v.main()
{

}
}

Solution:

static void perform(Electronic_Appliance ref)


{
ref.on();
ref.off();
}
p.s.v.main()
{
perform(new TV());
perform(new Refrigerator());
perform(new Washing_Machine());
}

if it works, then copy the entire code to new project and add one more
method in "Washing_Machine" class

void fillWater()
{
S.o.p("fillwater");
}

how will you invoke it in perform() method ?

static void perform(Electronic_Appliance ref)


{
ref.on();
if(ref instanceof Washing_Machine)
{
Washing_Machine w=(Washing_Machine)ref;
w.fillWater(); //now do fill water on correct
washing machine
}
ref.off();
}
Example 3:

open your persondemo project and let's add some methods inside "Person"
class only :

void walk()
{
S.o.p("walk");
}
void talk()
{
S.o.p("talk");
}
void eat()
{
S.o.p("eat");
}

now invoke these methods with the help of all the child class objects.

hope your code works fine.

Suppose we have a parent class, Person


e.g.

class Person
{
void walk()
{
// code to walk
}
void talk()
{
// code to talk
}
void eat()
{
// code to eat
}
void sleep()
{
// code to walk
}
}

one more function which we can think about "Person" but we cannot write
implementation inside "Person" class i.e. "performDuties()" . Its
implementation must be given inside child classes.
But how will you make it compulsory for child classes to define
"performDuties()" ?

you will have to make it "abstract" and for that class also must be
"abstract".
e.g.

abstract class Person


{
abstract void performDuties(); // it's a contract
// other stuff as it is

in Student and Employee classes provide an implementation of


"performDuties()"

we cannot instantiate a class in two scenarios:

a) when class is abstract


or
b) private constructor

in java as soon as u define a class with "abstract" keyword, class


becomes abstract.

abstract class can not be instantiated. It is because abstract classis


incomplete class ( it has got atleast one contract i.e. abstract method
)

abstract class can contain abstract as well as non-abstract methods.

abstract method is a method which is declared with "abstract" keyword.


( it can not be private)

a child class of an abstract class has to provide implementation to the


method which is declared "abstract" in parent class or else make child
class also "abstract".

a class can not be "abstract" and "final" both. It is because


"abstract" encourages inheritance and "final" stops inheritance.

can abstract class have a constructor?


yes.
but we cannot instantiate abstract class , so what's the use of that
constructor?
yes we cannot instantiate abstract class but when we instantiate
child class of that abstract class, child class constructor needs to
invoke parent class constructor.

In abstract class for making function abstract we need to make class


abstract
In abstract only decalaration on the class and definition in child
classes
When to use abstract class in java?

while designing Parent class, if u realize that there is some


functionality compulsorily required in child classes but Parent class
is not able to define it. This functionality is a contract or abstract
function. Since abstract function can not be declared inside non-
abstract class, u have to make class as abstract.

abstract class cannot be instantiated.


because abstract class is incomplete i.e. it has at least one
contract [abstract method]

can abstract class have a constructor?

yes, it will be invoked from sub class constructor when sub class
gets instantiated.

e.g
abstract class A
{
abstract void disp1();
abstract void disp2();
abstract void disp3();
abstract void disp4();
+
concrete methods
}
abstract class B extends A
{
}

class child1 extends B [ define all ]


{
}
abstract class C extends A [ define none ]
{
}

class child2 extends C [define all]


{
disp1(){} disp2(){} disp3(){} disp4(){}
}
abstract class D extends A
{

abstract class child3 extends D [define disp2 ,disp3]


{
disp1(){} disp4(){}
}

e.g.
void performDuties()
{
S.o.p("duties of Student");
}

void performDuties()
{
S.o.p("duties of Employee");
}

in the main function invoke "performDuties()" on Student and Employee


objects.

so your class "Person" has contract ( abstract method "performDuties()"


) and concrete behaviour (non-abstract methods such as getters ,
setters, walk,talk and eat)

contract-abstract method declaration on top and definition on child

concrete-normal class declaration and definition on same location in


class

What is abstract class in java ?

abstract class is the one which can contain contract plus


concrete behaviour.

abstract class cannot be instantiated.

now that "performDuties()" is an abstract method inside Person class,


which every single child class has to define, it is also called as a
"contract".

so abstract method is called as "contract" and


other non-abstract methods are called as "concrete behaviour"

Thus we can say that abstract class is a combination of "contract" and


a "concrete behaviour".

let's have one more example

Example1
create new project

"UIComponentDemo" class with main function

abstract class UIComponentCreator


{
abstract void createComponent(); // contract
void showComponent() // concrete behaviour
{
S.o.p("let's show component inside the given window");
}
}
class WindowsUIComponentCreator extends UIComponentCreator
{
void createComponent() //definition of abstract
{
S.o.p("create component as per Windows platform");
}
}

class MacUIComponentCreator extends UIComponentCreator


{
void createComponent() //definition of abstract
{
S.o.p("create component as per Mac platform");
}
}

write a class "Demo" with "perform()" and "main()"


in the main function create objects of "WindowsUIComponentCreator" and
"MacUIComponentCreator" and pass them to the "perform()" and invoke
createComponent() and showComponent() polymorphically.

Solution:

public class Demo


{
static void perform(UIComponentCreator ref)
{
ref.createComponent();
ref.showComponent();
}
main()
{
perform(new WindowsComponentCreator());
perform(new MacComponentCreator());
}
}

What is abstraction?

abstraction means showing relavent details of an object and


hiding unnecessary details.

with the help of abstract class you can achieve 0 to 100% abstraction.
What does that mean?

if abstract class does not have any abstract method, that means there
is no abstraction.

if abstract class has got some abstract methods ( at least one ), there
is a partial abstraction.

if abstract class has got all the abstract methods, in that case we can
achieve 100% abstraction.
Example 2
create a new project
EventDemo1 class with main function

abstract class MouseEvent


{
abstract void mouseClicked();
abstract void mouseEntered();
abstract void mouseExited(); //pure abstract class
}

abstract class WindowEvent


{
abstract void windowClosing();
abstract void windowOpening();
}

class GuiApp1
{
// how can we extend MouseEvent and WindowEvent both in this
class?
}

is it possible to say

class GuiApp1 extends MouseEvent,WindowEvent


{
}

No. because multiple inheritance is not allowed in java.

There are two ways we can solve the problem.

one way is

class GuiApp1 extends MouseEvent


{
void mouseClicked()
{
S.o.p("mouse clicked");
}

void mouseEntered()
{
S.o.p("mouse entered");
}
void mouseExited()
{
S.o.p("mouse exited");
}
}
class GuiApp2 extends WindowEvent
{
void windowClosing()
{
S.o.p("window closing");
}
void windowOpening()
{
S.o.p("window opening");
}
}

now create objects of these two classes and invoke their methods
from main function.

the other way is:

since our MouseEvent and WindowEvent classes have got only abstract
methods ( contracts ) we can have them as "interfaces" instead of
"abstract classes".

What is the advantage if they are interfaces?


GuiApp class can implement more than one interfaces.

create another project


with InterfaceDemo1 class with main function

inteface MouseEvent
{
void mouseClicked();
void mouseEntered();
void mouseExited();
}

interface WindowEvent
{
void windowClosing();
void windowOpening();
}
class GuiApp implements MouseEvent,WindowEvent
{
// define all abstract methods and write some message in all
these methods
}

inside main function create object of "GuiApp" class and invoke all the
methods ( 5 methods )

what are intefaces ?

intefaces are abstract in nature. i.e. they have all abstract methods
(100% abstraction )

interface methods are by default "public" and "abstract".


a class can implement one or more interfaces.

a class which implement/s interface/s , has to define all the methods


of that/those interface/s.

Example 2:
let's see one more example.

create a new project

StorageDemo class with main function.

interface Storage
{
void store();
void load();
void display();
}
class FileStorage implements Storage // implementation of Storage
{
public void store()
{
S.o.p("store inside filesystem");
}
public void load()
{
S.o.p("load from filesystem");
}
public void display()
{
S.o.p("display from filesystem");
}
}
class DatabaseStorage implements Storage
{
public void store()
{
S.o.p("store inside Database");
}
public void load()
{
S.o.p("load from Database");
}
public void display()
{
S.o.p("display from Database");
}
}

create a class "Demo" with "perform()" and "main()"


define "perform()" in such a way that whichever implementation of
"Storage" is passed, it should invoke "store()" , "load()" and
"display()" of that implementation.

in main function create objects of "FileStorage" and "DatabaseStorage"


and invoke "perform()" method.

Solution:

public class Demo


{
static void perform(Storage ref)
{
ref.store();
ref.load();
ref.display();
}
main()
{
perform(new FileStorage());
perform(new DatabaseStorage());
}
}

what if we have only "contract" at the parent level ?

e.g.
abstract class Shape
{
abstract void draw(); // every child must define draw
}

if you have only a contract at the parent level, instead of abstract


class you can define interfaces. this is because a class can implement
more than one interfaces.

interface example.......
abstraction means showing relevant attributes of an object and hiding
unnecessary details.

how do you achieve abstraction in java using interfaces?

The user who want to use the methods of the interface, he only
knows the contract of this interface i.e its methods, information about
the implementation is completely hidden from the user, thus achieving
100% abstraction.

//polymorphic invocation(ClassCastException and instanceof Demos)


Demo1:

class Weapon
{
void attack()
{

}
}
class Gun extends Weapon
{
void attack()
{
System.out.println("attack with Gun");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("attack with Bomb");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("attack with Sword");
}
}
public class WeaponDemo1
{
static void perform(Weapon ref)
{
ref.attack(); // polymorphic invocation
}
public static void main(String args[])
{
perform(new Gun());
perform(new Bomb());
perform(new Sword());
}
}

Demo 2:

class Weapon
{
void attack()
{

}
}
class Gun extends Weapon
{
void attack()
{
System.out.println("attack with Gun");
}
void fillBullets()
{
System.out.println("filling bullets");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("attack with Bomb");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("attack with Sword");
}
}
public class WeaponDemo1_a
{
static void perform(Weapon ref)
{
// along with attack also invoke "fillBullets()" method of Gun

ref.fillBullets();
ref.attack(); // polymorphic invocation //but show error
bcoz parent no having attach function
}
public static void main(String args[])
{
perform(new Gun());
//perform(new Bomb());
//perform(new Sword());
}
}

Demo 3:

class Weapon
{
void attack()
{

}
}
class Gun extends Weapon
{
void attack()
{
System.out.println("attack with Gun");
}
void fillBullets()
{
System.out.println("filling bullets");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("attack with Bomb");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("attack with Sword");
}
}
public class WeaponDemo1_b
{
static void perform(Weapon ref)
{
// along with attack also invoke "fillBullets()" method of Gun
// ref.fillBullets(); fillBullets() is not there inside //
"Weapon" class, so u can't invoke it using Weapon class reference.

Gun ob=new Gun();


ob.fillBullets(); // but it's a different Gun
ref.attack(); // polymorphic invokation
}
public static void main(String args[])
{
perform(new Gun());
//perform(new Bomb());
//perform(new Sword());
}

Demo 4:

class Weapon
{
void attack()
{

}
}
class Gun extends Weapon
{
void attack()
{
System.out.println("attack with Gun");
}
void fillBullets()
{
System.out.println("filling bullets");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("attack with Bomb");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("attack with Sword");
}
}
public class WeaponDemo2
{
static void perform(Weapon ref)
{
// along with attack also invoke "fillBullets()" method of Gun
// we would like to invoke "fillBullets()" on that Gun which is there
inside "ref"
Gun ob=(Gun)ref; // downcasting
ob.fillBullets(); //but in that in all weapons there is
fill bullet call by downcasting
ref.attack(); // polymorphic invokation
}
public static void main(String args[])
{
perform(new Gun());
//perform(new Bomb());
//perform(new Sword());
}
}
Demo 5:
class Weapon
{
void attack()
{

}
}
class Gun extends Weapon
{
void attack()
{
System.out.println("attack with Gun");
}
void fillBullets()
{
System.out.println("filling bullets");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("attack with Bomb");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("attack with Sword");
}
}
public class WeaponDemo4
{
static void perform(Weapon ref)
{
// along with attack also invoke "fillBullets()" method of Gun

if(ref instanceof Gun)


{
Gun ob=(Gun)ref; // downcasting
ob.fillBullets();
}
ref.attack(); // polymorphic invokation
}
public static void main(String args[])
{
perform(new Gun());
perform(new Bomb());
perform(new Sword());
}

 Why can't child class reference refer to parent class object


class base
{
void disp()
{
//print is not available here
}
}
class sub extends base
{
void print()
{ //print and disp is available here
}
}

public class Demo


{
p.s.v.main()
{
base ref=new base();
sub ref2=(sub)ref; // will fail but why?
Discuss

}
}

let's assume that


sub ref2=(sub)ref; works at runtime

now what if we say:


ref2.print();
when compiler had encountered this statement compiler must have
written late binding instructions. As per those instructions since the
content of "ref2" during runtime is "base" and base does not have
"print()" method , it will be a problem. We shouldn't get this problem
that's why JVM does not allow us to make
"sub class reference" refer to "base class".
why do you upcast?

- in order to perform late binding. It is basically a "program to


interface" concept which always gives us maintenance advantage even if
there is a change in the inheritance hierarchy.

why do you downcast?

- suppose we have written a function which has an argument of


"base type" so that we can pass any child object i.e. we follow
"program to interface" concept. At a given time if u want to check the
existence of a particular child in parent class pointer and invoke its
method [which is not available in parent class] we need to downcast.

what is "instanceof" operator?

instanceof operator checks is-a relationship. It returns true or false.

e.g.
if "ref" refers to "Dac_Dbda" and u check
if(ref instanceof Dac_Dbda) it returns "true"

if "ref" refers to "Mscit" and u check


if(ref instanceof Dac_Dbda) it returns "false"

overriding method must have same or more accessibility as compare to


overridden method.

class base
{
void disp()
{
S.o.p("base disp");
}
}
class sub extends base
{
private void disp()
{
S.o.p("sub disp");
}
}

above code will not compile, but for the time being let's assume that
it will compile successfully. What can be the side effect of this code?

some where in the same package if we say

public class Demo


{
p.s.v.main()
{
base ref=new sub();
ref.disp();
}
}

here for the compiler "ref" is of type "base", so compiler will search
"disp" in base
is it there ? yes
is it accessible ? yes
is it final ? no
is is static ? no

so as per compiler's instruction (which you know) dynamic binding will


take place i.e. "sub" class "disp" which is "private" will get invoked.
This will violate accessibility concept. It should not happen that's
why compiler stops you at:

class base
{
void disp()
{
S.o.p("base disp");
}
}
class sub extends base
{
private void disp() // compilation error
{
S.o.p("sub disp");
}
}

overriding method can have covariant return type.

class base
{
String disp()
{
S.o.p("base disp");
return null;
}
}
class sub extends base
{
Object disp()
{ //object_string,int.Null
We cant put string in object bcoz
string is sub type of object
S.o.p("sub disp");
return null;
}
}

above code will not compile, but for the time being let's assume that
it will compile successfully. What can be the side effect of this code?

some where in the code if we say

public class Demo


{
p.s.v.main()
{
base ref=new sub();
String s=ref.disp();
}
}

here for the compiler "ref" is of type "base", so compiler will search
"disp" in base
is it there ? yes
is it accessible ? yes
is it final ? no
is is static ? no

your statement inside "main"

String s=ref.disp();

is correct as per compiler because "disp" of base has "String" as a


return type.

so as per compiler's instruction (which you know) dynamic binding will


take place i.e. "sub" class "disp" which will return "Object" which
"String s" cannot catch. It should not happen that's why compiler stops
you at:

class base
{
String disp()
{
S.o.p("base disp");
return null;
}
}
class sub extends base
{
Object void disp() // Compilation error
{
S.o.p("sub disp");
return null;
}}
Demo 28:
If upcasting is done downcasting will be successful and if upcasting
fail downcasting will fail at run time
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub1 disp");
}
}
public class Demo28
{
public static void main(String args[])
{
base ref1=new sub1(); //upcasting
sub1 s1=(sub1)ref1; //downcasting //sub reference
pointing sub object
System.out.println("first test over");

base ref2=new base(); // no upcasting


sub1 s2=(sub1)ref2; // downcasting this is not possible
sub ref base object
System.out.println("second test over");
}
}

Demo 29: in instance of we check is a relationship .

class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub1 disp");
}
}
public class is
{
public static void main(String args[])
{
base ref1=new sub1(); //upcasting
if(ref1 instanceof base) // sub is base
{
System.out.println("it is base");
}
if(ref1 instanceof sub1) // sub is sub
{
System.out.println("it is sub1");
}

base ref2=new base();


if(ref2 instanceof base) // base is base
{
System.out.println("it is base");
}
if(ref2 instanceof sub1) //base is sub no
{
System.out.println("it is sub1");
}

//base ref2=new base(); // no upcasting


//sub1 s2=(sub1)ref2; // downcasting
System.out.println("second test over");
}
}
// it is base
it is sub1
it is base
second test over

package day4;
class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub1 extends base
{
void disp()
{
System.out.println("sub1 disp");
}
}
public class is
{
public static void main(String args[])
{
base ref1=new sub1(); //upcasting
if(ref1 instanceof sub1) //sub is sub
{
sub1 s1=(sub1)ref1;
}
else
{
System.out.println("can not convert to s1");
}
System.out.println("first test over");
base ref2=new base();
if(ref2 instanceof sub1) //base is sub
{
sub1 s2=(sub1)ref2;
}
else
{
System.out.println("can not convert to s2");
}
System.out.println("second test over");}}

Demo 30:
// use of upcasting
class Shape
{
void draw(){}
}
class Triangle extends Shape
{
void draw()
{
System.out.println("in Triangle draw");
}
}
class Circle extends Shape
{
void draw()
{
System.out.println("in Circle draw");
}
}
class Rect extends Shape
{
void draw()
{
System.out.println("in Rect draw");
}
}

public class Demo31


{
static void perform(Shape ref)
{
ref.draw();
}

public static void main(String args[])


{
perform(new Rect()); //performs(shape ref=new triangle)

perform(new Triangle());

}
}

Demo 31:

abstract class Shape //abstract class only added


{
abstract void draw();
}
class Triangle extends Shape
{
void draw()
{
System.out.println("in Triangle draw");
}
}
class Circle extends Shape
{
void draw()
{
System.out.println("in Circle draw");
}
}
class Rect extends Shape
{
void draw()
{
System.out.println("in Rect draw");
}
}
class Poly extends Shape
{
void draw()
{
System.out.println("in Poly draw");
}
}
public class Demo32
{
static void perform(Shape ref)
{
ref.draw();
}

public static void main(String args[])


{
perform(new Rect());

perform(new Triangle());

perform(new Poly());

}
}

Demo 33:
interface emp1 //interface class created
{
void disp1(); // public and abstract
}
class sub1 implements emp1
{
/*public*/ void disp1()
{
System.out.println("sub1 disp1");
}
}
public class Demo33
{
public static void main(String args[])
{sub1 s1=new sub1();
s1.disp1();}}
interface emp1
{
void disp1(); // by default in interface functions are public
and abstract
}
interface emp2
{
void disp2();
}
class sub1 implements emp1,emp2
{
public void disp1()
{
System.out.println("sub1 disp1");
}
public void disp2()
{
System.out.println("sub1 disp2");
}
}
public class Demo34
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp1();
s1.disp2();

}
}

interface emp1 //interface used


{
void disp1(); // public and abstract
}
interface emp2
{
void disp2();
}
interface emp3 extends emp1,emp2
{
void disp3();
}
class sub1 implements emp3
{
public void disp1()
{
System.out.println("sub1 disp1");
}
public void disp2()
{
System.out.println("sub1 disp2");
}
public void disp3()
{
System.out.println("sub1 disp3");
}
}
public class Demo35
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp1();
s1.disp2();
s1.disp3();

}
}

Demo 35:
interface emp1
{
void disp1(); // public and abstract
}
interface emp2
{
void disp2();
}
interface emp3 extends emp1,emp2 //prior java 8 muliple inheritance not
happen
{
void disp3();
}
class sub1 implements emp3
{
public void disp1()
{
System.out.println("sub1 disp1");
}
public void disp2()
{
System.out.println("sub1 disp2");
}
public void disp3()
{
System.out.println("sub1 disp3");
}
}
public class Demo35
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp1();
s1.disp2();
s1.disp3();

}
}

Demo 37:

interface emp1
{
void disp1(); // public and abstract
}
interface emp2
{
void disp2();
}
interface emp3 extends emp1,emp2
{
void disp3();
}
class base
{
void print()
{
System.out.println("base print");
}
}
class sub1 extends base implements emp3
{
public void disp1()
{
System.out.println("sub1 disp1");
}
public void disp2()
{
System.out.println("sub1 disp2");
}
public void disp3()
{
System.out.println("sub1 disp3");
}
}
public class Demo36
{
public static void main(String args[])
{
sub1 s1=new sub1();
s1.disp1();
s1.disp2();
s1.disp3();
s1.print();
}
}

Demo 38:

class base
{
public void disp()
{
System.out.println("in base disp");
}
}
class sub1 extends base
{
public void disp()
{
System.out.println("in sub1 disp");
}
}
class sub2 extends base
{
public void disp()
{
System.out.println("in sub2 disp");
}
}
class sub3 extends base
{
public void disp()
{
System.out.println("in sub3 disp");
}
}
public class Demo38
{

public static void main(String args[])


{
/*create an array of base class having 3 elements
store all the child class objects in this array.
traverse the array and invoke disp of all the classes.*/

base arr[]=new base[3];


arr[0]=new sub1();
arr[1]=new sub2();
arr[2]=new sub3();

for(int i=0;i<arr.length;i++)
{
arr[i].disp();
}
}
}

Demo 39:
class base
{
public void disp()
{
System.out.println("in base disp");
}
}
class sub1 extends base
{
public void disp()
{
System.out.println("in sub1 disp");
}
}
class sub2 extends base
{
public void disp()
{
System.out.println("in sub2 disp");
}
}
class sub3 extends base
{
public void disp()
{
System.out.println("in sub3 disp");
}
}
public class Demo39
{

public static void main(String args[])


{
/*create an array of base class having 3 elements
store all the child class objects in this array.
traverse the array and invoke disp of sub2 only.*/

base arr[]=new base[3];


arr[0]=new sub1();
arr[1]=new sub2();
arr[2]=new sub3();

for(int i=0;i<arr.length;i++)
{
if(arr[i] instanceof sub2)
{
arr[i].disp();
break;
}
}
}
}

Demo 40:

interface base
{
void disp();
}
class sub1 implements base
{
public void disp()
{
System.out.println("in sub1 disp");
}
}
class sub2 implements base
{
public void disp()
{
System.out.println("in sub2 disp");
}
}
class sub3 implements base
{
public void disp()
{
System.out.println("in sub3 disp");
}
}
public class Demo40
{

public static void main(String args[])


{
/*create an array of base having 3 elements
store all the child class objects in this array.
traverse the array and invoke disp of sub2 only.*/

base arr[]=new base[3];


arr[0]=new sub1();
arr[1]=new sub2();
arr[2]=new sub3();

for(int i=0;i<arr.length;i++)
{
if(arr[i] instanceof sub2)
{
arr[i].disp();
break;
}
}
}
}

Special:

class base
{
int i;
base()
{
add(1);
}
void add(int v)
{
i+=v;
}
void print()
{
System.out.println(i);
}
}
class sub extends base
{
sub()
{
add(2);
}
void add(int v) //jiska object uski method call in java
{
i+=v*2; //i=1*2=2 i=2*2+2=6 i=8*2+6=22
}
}
public class Special
{
static void disp(base b)
{
b.add(8);
b.print();
}
public static void main(String args[])
{
disp(new sub());
}
}

R n D static block
class base
{
static
{
System.out.println("in base static");
}
base()
{
System.out.println("base const");
}
}
class sub extends base
{
static
{
System.out.println("in sub static");
}
}
public class myclass1
{

public static void main(String args[])


{
base b=new base();

System.out.println("....................");
sub s=new sub();
}
}

o/p:
in base static
base const
....................
in sub static
base const

Instance of:
class base
{

}
class sub extends base
{

}
public class myclass extends sub
{

public static void main(String args[])


{
myclass m=new myclass();
if(m instanceof myclass)
{
System.out.println("myclass"); //himself
}
if(m instanceof sub)
{
System.out.println("sub"); //father
}
if(m instanceof base)
{
System.out.println("base"); //grand father
}
if(m instanceof Object)
{
System.out.println("Object"); //sabkabaap
}

System.out.println("**********************");
base b=new sub();
if(b instanceof base) //call
{
System.out.println("base");
}
if(b instanceof sub)
{
System.out.println("sub");
}
if(b instanceof myclass)
{
System.out.println("myclass");
}
if(b instanceof Object) //call
{
System.out.println("Object");
}
}
}

// myclass
sub
base
Object
**********************
base
sub
Object
Program to interface and program to implementation info:

Demo1:

class Weapon
{
void attack()
{
}
// some other stuff
}
class Gun extends Weapon
{
void attack()
{
System.out.println("Gun attack");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("Sword attack");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("Bomb attack");
}
}

class Soldier
{
// program to implementation

// Soldier class here is tightly coupled with a specific Weapon


ie. Gun or Bomb or Sword
// it gives us maintenance drawback

//Gun ob=new Gun(); // Soldier has Gun


//program to implement(tightly couple)
//Bomb ob=new Bomb();
Sword ob=new Sword(); //tightly couple
void fight()
{
ob.attack();
}
}

public class SoldierDemo1


{
public static void main(String args[])
{
Soldier s1=new Soldier();
s1.fight();
}
}
Demo2:

class Weapon
{
void attack()
{
}
// some other stuff
}
class Gun extends Weapon
{
void attack()
{
System.out.println("Gun attack");
}
}
class Sword extends Weapon
{
void attack()
{
System.out.println("Sword attack");
}
}
class Bomb extends Weapon
{
void attack()
{
System.out.println("Bomb attack");
}
}

class Soldier
{

// Soldier class here is loosely coupled with a specific Weapon


ie. Gun or Bomb or Sword
// it gives us maintenance advantage

Weapon ref; // program to interface(loose coupling)


void fight(Weapon ref)
{
this.ref=ref;
ref.attack();
}

public class SoldierDemo2


{
public static void main(String args[])
{
Soldier s1=new Soldier();
s1.fight(new Gun()); // or
s1.fight(new Sword());
}
}
Demo3:Difference
class Driver
{
// program to implementation
// Driver is tightly coupled with Car or Bus

Car c=new Car();


or
Bus b=new Bus();

void perform()
{
c.drive();
or
b.drive();
}
}

vs
class Driver
{
// program to interface

// Driver is loosely coupled with a specific FourWheeler

FourWheeler ref;

void perform(FourWheeler ref)


{
this.ref=ref;
ref.drive();
}
}

Demo 4:
class base
{
static int a=20;
static
{
System.out.println("base static");
}
}
class sub extends base
{
static int a=10;
static
{
System.out.println("sub static");
}
}
public class MyClass1
{
public static void main(String[] args)
{
System.out.println(sub.a);
}}
Early binding:
Static used in this so there is early binding.

Demo1:
class base
{
static void disp() //static used here so early binding
{
System.out.println("base disp");
}
}
class sub extends base
{
static void disp()
{
System.out.println("sub disp");
}
}
public class Demo1
{
public static void main(String args[])
{
sub s=new sub();
s.disp(); // sub disp
base ref=new sub();
ref.disp();

/*what compiler does

sub.disp(); //sub disp call

base.disp(); //base disp call


*/
}
}

Demo 2:

class base
{
void disp()
{
System.out.println("base disp");
}
}
class sub extends base
{
static void disp() // error overriding method is static
{
System.out.println("sub disp");
}
}
public class c1
{
public static void main(String args[])
{
sub s=new sub();
s.disp();
base ref=new sub();
ref.disp();

}
}

Demo 3:

class base
{
static void disp()
{
System.out.println("base disp");
}
}
class sub extends base
{
void disp() // error overridden method is static
{
System.out.println("sub disp");
}
}
public class Demo3
{
public static void main(String args[])
{
sub s=new sub();
s.disp();
base ref=new sub();
ref.disp();

}
}

Both overriding and overridden method need to be static


Demo 4:

class base
{
static void disp(int k)
{
System.out.println("base disp");
}
}
class sub extends base
{
static void disp() //overloading done
{
System.out.println("sub disp");
}
}
public class c1
{
public static void main(String args[])
{
sub s=new sub();
s.disp(); //sub disp call

/* what compiler does

sub.disp(); //sub disp call

*/
}
}

Demo 5:

class base
{
static void disp()
{
System.out.println("base disp");
}
}
class sub extends base
{
static void disp(int k)
{
System.out.println("sub disp");
}
}
public class Demo5
{
public static void main(String args[])
{
sub s=new sub();
s.disp();
s.disp(20);

/* what compiler does

base.disp();
sub.disp(20);

*/
}
}

Demo 6:

class base
{
final void disp()
{
System.out.println("base disp");
}
}
class sub extends base
{
/*void disp() Not Possible
{
System.out.println("sub disp");
}*/
}
public class Demo6
{
public static void main(String args[])
{
base ref=new sub();
ref.disp(); // early binding
}
}

Demo 7:

class base
{
private void disp()
{
System.out.println("base disp");
}
}
class sub extends base
{
void disp()
{
System.out.println("sub disp");
}
}
public class c1
{
public static void main(String args[])
{
base ref=new sub();
ref.disp(); // error disp() has private access in base
}
}
Demo 8:
class sub extends Demo8
{
void disp()
{
System.out.println("sub disp");
}
}
public class Demo8
{
private void disp()
{
System.out.println("Demo8 disp");
}
public static void main(String args[])
{
Demo8 ref=new sub();
ref.disp(); // early binding
}
}

Some more programs:


First:

class base
{
static int a=20;
static
{
System.out.println("base static");
}
}
class sub extends base
{
static int a=10;
static
{
System.out.println("sub static");
}
}
public class MyClass1
{
public static void main(String[] args)
{
System.out.println(sub.a);
}

base static
sub static
10
Second:

class base
{
static void disp(int k)
{
System.out.println("base disp");
}
static
{
System.out.println("base static block");
}
}
class sub extends base
{
static void disp()
{
System.out.println("sub disp");
}
static
{
System.out.println("sub static block");
}
}
public class Demo4
{
public static void main(String args[])
{
sub.disp(4);
}
}

output:

base static block


base disp

Third:

class base
{
static void disp(int k)
{
System.out.println("base disp");
}
static
{
System.out.println("base static block");
}
}
class sub extends base
{
static void disp()
{
System.out.println("sub disp");
}
static
{
System.out.println("sub static block");
}
}
public class Demo4
{
public static void main(String args[])
{
sub.disp();
}
}

/*

base static block


sub static block
sub disp

*/

RnD about null pointer exception:

class Sample
{
static void disp1()
{
System.out.println("in disp1");
}
void disp2()
{
System.out.println("in disp2");
}
}
public class one
{

public static void main(String args[])


{
Sample s=null;
s.disp1(); //no need to create object for static
void disp method
//s.disp2(); NullPointerExeption

}
}

/*
output:

in disp1

*/
R_n_D in java:
public class Demo2
{
void disp(Object o)
{
System.out.println("in Object disp");
}
void disp(String o)
{
System.out.println("in String disp");
}

public static void main(String args[])


{
Demo2 d=new Demo2();
d.disp("hello");
d.disp(null); //null in string class
d.disp(10);
}
}

/*
output:
in string disp
in string disp
in object disp

*/

About Interface:

interface myinterface
{
void disp1();
void disp2();
}
class sub implements myinterface
{
public void disp1()
{
System.out.println("disp1");
}
public void disp2()
{
System.out.println("disp2");
}
public void print()
{
System.out.println("print");
}
}
public class InterfaceDemo
{
public static void main(String args[])
{
myinterface ref=new sub();
ref.disp1();
ref.disp2();
// ref.print(); // error print not in myinterface
System.out.println(ref.toString()); // works
}
}

/*

ref.toString() // works_ not yet done by sir

using interface reference we can invoke any methods of "Object" class.


this is because interface reference can point to the object of some or
the other class and Every class is derived from "Object" class.

*/
About Overloading:
Demo 1:

class base
{
void disp(Object ref)
{
System.out.println("in Object method");
}
void disp(String ref)
{
System.out.println("in String method");
}
}
public class MyClass
{
public static void main(String[] args)
{
base b=new base();
b.disp("hello"); //nearest
}
}

// output: in String method

Demo2:
class base
{
void disp(Object ref)
{
System.out.println("in Object method");
}
}
class sub extends base
{
void disp(String ref)
{
System.out.println("in String method");
}
}
public class MyClass
{
public static void main(String[] args)
{
base b=new sub();
b.disp("hello");
/*here for compiler, b is of type "base"
compiler will check "disp("hello") " inside "base" class
yes
it's disp(Object)

now compiler writes an instruction for JVM to follow:


during runtime check the content of "b" and invoke
"disp(Object)" of that content

*/

sub s=new sub();


s.disp("welcome");

/* here for compiler "s" is of type "sub"


compiler will check whether "disp("welcome")" is there in
sub

actually sub class has two disp methods:


disp(Object) and disp(String)
so as usual compiler gives preference to disp(String)
and writes following instruction for JVM

during runtime check the content of "s" and invoke


"disp(String)" of that content.*/

s.disp(100);

/* here for compiler "s" is of type "sub"


compiler will check whether "disp(100)" is there in sub

sub class has two disp methods:


disp(Object) and disp(String)
compiler here knows where 100 can go , i.e.
disp(Object)
and writes following instruction for JVM

during runtime check the content of "s" and invoke


"disp(Object)" of that content.*/

}
}
Demo 3:

class base
{
void disp(String ref)
{
System.out.println("in String method");
}
}
class sub extends base
{
void disp(Object ref)
{
System.out.println("in Object method");
}
}
public class MyClass
{
public static void main(String[] args)
{
base b=new sub();
b.disp("hello");

sub s=new sub();


s.disp("welcome");
s.disp(100);
}
}

/*
output:
in String method
in String method
in Object method

Favour composition over inheritance is a one of the popular object oriented design principles, which helps us to
create flexible and maintainable code in object oriented languages.

Inheritance drawbacks:

a) Tight coupling- if base class ( Fourwheeler) is changed, sub class (Car) will break.
b) inheritance breaks encapsulation. white-box reuse. That is, with inheritance, the parent class
implementation is often visible to the subclasses.

Composition Advantages:

black-box reuse as it does not break encapsulation. “Car” knows only an interface “Engine”. It doesn’t know the
implementation

Loose coupling, program to interface. During runtime any implementations (such as “HondaEngine”
,”MarutiEngine” or “BMWEngine” can be passed to “Engine ref” and “on()” method can be invoked
polymorphically.)

White box-in white box we know which car we invoke e.g BMW
Black box-we invoke Engine we don’t know which engine is invoked.
In Object Oriented Programming, there are many different types of relationships which can exist between two or
more classes. The most common two types are:

 Inheritance — an “is a” relationship

 Association — a “has a” relationship

There are two types of Association relationships — Aggregation and Composition.

What is an Association relationship?

An association relationship between two classes is a “has a” relationship. For example:

 A Car has an Engine and a Wheel

 A Person has a Leg and an Arm

 A Book has Pages

This usually represents when there are two classes, ClassA and ClassB, and either:

 ClassA contains ClassB as an attribute, or

 Instances of ClassB are constructed inside ClassA

What’s the difference between Aggregation and Composition?

There are two sub-types of Association relationships — Aggregation and Composition. What’s the difference
between these two?

Composition

Composition implies that the contained class cannot exist independently of the container. If the container is
destroyed, the child is also destroyed.

Take for example a Page and a Book. The Page cannot exist without the Book, because the book is composed
of Pages. If the Book is destroyed, the Page is also destroyed.

In code, this usually refers to the child instance being created inside the container class:

class Book:
def __init__(self):
page1 = Page('This is content for page 1')
page2 = Page('This is content for page 2')
self.pages = [page1, page2]

class Page:
def __init__(self, content):
self.content = contentbook = Book() # If I destroy this Book instance,
# the Page instances are also destroyed

Aggregation

With an aggregation, the child can exist independently of the parent.

So thinking of a Car and an Engine, the Engine doesn’t need to be destroyed when the Car is destroyed.

class Car:
def __init__(self, engine):
self.engine = engine

class Engine:
def __init__(self):
passengine = Engine()
car = Car(engine) # If I destroy this Car instance,
# the Engine instance still exists

How are these represented a UML diagram?

In a UML diagram, both Aggregation and Composition are represented with a diamond arrow between the
classes. The diamond end goes on the side of the container.

 Aggregation uses an open diamond

 Composition uses a closed diamond

Here’s an example:

Aggrigation Demo:
package aggregation;

class Teacher
{
private String name;
private int age;
public Teacher(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}

public int getAge() {


return age;
}

public void setAge(int age) {


this.age = age;
}
public void work()
{
System.out.println("Teacher is working");
}
};

class Department
{
private Teacher teacher;
private String dname;
public Department(String dname)
{
teacher=null;
this.dname=dname;
}
public String getDname()
{
return dname;
}
public void addTeacher(Teacher teacher)
{
this.teacher=teacher;
}
public void perform()
{
System.out.println(dname+"\t");
teacher.work();
}
}

public class AggregationDemo


{
public static void main(String[] args)
{
Department sd=new Department("Science Department");
Department md=new Department("Maths Department");
System.out.println(sd.getDname());
System.out.println(md.getDname());
Teacher t1=new Teacher("Abc",35);
System.out.println(t1.getName()+"\t"+t1.getAge());
md.addTeacher(t1);
md.perform();
System.out.println("Lets close the maths department");
md=null; // delete maths department
System.out.println(t1.getName()+" still exists and can join
some other department");
sd.addTeacher(t1);
sd.perform();
// ..... after some time ......
sd=null; //delete science department
System.out.println(t1.getName()+" still exists and can join
some other department");

}
Sequence:
1) Department class gets instantiated and its members are allocated
memory.
2) "md" reference is created on the stack.
3) "md" refers to the instance of Department inside heap.
4) Teacher class gets instantiated and its members are allocated
memory.
5) "t1" reference is created on the stack.
6) "t1" refers to the instance of Teacher inside heap.
7) when "addTeacher()" method gets called,"teacher" reference of
Teacher class inside the instance of Department refers to the Teacher
instance on the heap.
8) we say "md=null" inside the application.
9) Department instance on the heap is marked for GC.
10) That does not affect Teacher instance available on heap because it
is still referenced by "t1" reference on the stack.
Composition Demo:

package aggregation;

import java.util.Scanner;

class Room
{
private String name;
public Room(String name)
{
this.name=name;
}
public Room()
{
name=null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
};

class House
{
private Room rooms[];
private String name;
private String address;
private int no_rooms;
public House(String name,String address,int no_rooms)
{
this.name=name;
this.address=address;
this.no_rooms=no_rooms;
this.rooms=new Room[no_rooms];
String rname;
Scanner sc=new Scanner(System.in);
for(int i=0;i<no_rooms;i++)
{
System.out.println("enter room name");
rname=sc.next();
this.rooms[i]=new Room();
this.rooms[i].setName(rname);
}
}

public String getName() {


return name;
}

public String getAddress() {


return address;
}
void showRooms()
{
for(int i=0;i<no_rooms;i++)
{
System.out.println(rooms[i].getName());
}
}
}
public class CompositeDemo
{
public static void main(String args[])
{
House house=new House("Samrat Mansion","Juhu,Mumbai",4);
System.out.println(house.getName());
System.out.println(house.getAddress());
System.out.println("house has following rooms");
house.showRooms();
System.out.println("Lets renovate the house");
house=null;
}
}
1) House class instance is created on the heap and its members are
allocated memory.
2) When House class constructor gets invoked, Room class array of
reference is created on the heap.
3)"rooms" reference of Room type inside House instance refers to the
array created above.
4) 3 instances of Room class are created on the heap and their members
are allocated memory.
5) "rooms" reference created at //3 refers to the Room instances
created above.
6) "house" reference of type House class is created on the stack.
7) "house" reference refers to the House class instance available on
the heap.
8) application says "house=null".
9) House instance available on the heap is marked for GC.
10) array of Room reference available on the heap is marked for GC.
11) Room instances available on the heap are marked for GC.

This():

This used for explicitly invoke the same class constructors.

Trial 1:
public class MyDynamicArray
{
public MyDynamicArray()
{
this(10); //so it invoke below constructor
}

public MyDynamicArray(int capacity)


{
create dynamic array with the given capacity
}
}

we want to make capacity by default 10 if not provided

MyDynamicArray array1=new MyDynamicArray(50);

MyDynamicArray array2=new MyDyanamicArray();

Trial 2:
class base
{
base()
{
System.out.println("in base no-arg");
}
}
public class trial1 extends base
{
trial1()
{
this(30);
System.out.println("in def const");
}
trial1(int k)
{
this(20,40);
System.out.println("in 1 param");
}
trial1(int x,int y)
{
System.out.println("in 2 param");
}
public static void main(String args[])
{
trial1 t=new trial1();
}
}

Trial 3:
class base
{
base(int k)
{
System.out.println("in base param");
}
}
public class trial2 extends base
{
trial2()
{
this(30);
System.out.println("in def const");
}
trial2(int k)
{
this(20,40);
System.out.println("in 1 param");
}
trial2(int x,int y)
{
super(30); // super is required here

//super is used also with this in one class but different


constructors
System.out.println("in 2 param");
}
public static void main(String args[])
{
trial2 t=new trial2();
}
}
Day 7:

Enum pro

enum is a user defined data type.

it is used to define set of predefined values. It helps in making the


program more readable and also helps to reduce programming bugs.

some of the examples where enum is used in java are:

compass directions (values of NORTH, SOUTH, EAST, and WEST)


The days of the week. MONDAY,TUESDAY etc.
sizes in case of Pizza
SMALL , MEDIUM,LARGE etc.

enum MyFont
{
PLAIN,BOLD,ITALIC
}

Enum:
You can also create your own constants by marking a variable static const. But sometimes you'll want to create
a set of constant values to represent the only valid values for a variable. This set of valid values is commonly
referred to as an enumeration.

Let's say that you 're creating a GUI Application where, u need to create ur component and set the font style (
plain or bold or italic).

Demo 1:
class MyFont
{
public static final int PLAIN=0;
public static final int BOLD=1;
public static final int ITALIC=2;
}

class MyComponent
{
public void setStyle(int style)
{
switch(style)
{
case 0: System.out.println("plain");
break;
case 1: System.out.println("bold");
break;
case 2: System.out.println("italic");
break;
default: System.out.println("unpredictable font");
}
}
}
public class Demo1
{
public static void main(String args[])
{
MyComponent mc=new MyComponent();
mc.setStyle(MyFont.BOLD);
mc.setStyle(MyFont.ITALIC);
// mc.setStyle(MyFont.plain); //Error
mc.setStyle(1); // saves typing
mc.setStyle(6); // can be risky
}
}

Demo 2:
enum MyFont
{
PLAIN,BOLD,ITALIC
}

class MyComponent
{
publicvoid setStyle(MyFont font)
{
switch(font)
{
case PLAIN: System.out.println("plain");
6 break;
case BOLD: System.out.println("bold");
break;
case ITALIC: System.out.println("italic");
break;
}
}
}
public class Demo1
{
public static void main(String args[])
{
MyComponent mc=new MyComponent();
mc.setStyle(MyFont.BOLD);
mc.setStyle(MyFont.ITALIC);
mc.setStyle(MyFont.PLAIN);

// mc.setStyle(1); // will not compile hence there is no


// risk of unpredictable result

}
}

The good news about this technique is that it DOES make the code easier to read. The other good news is that
you can't ever change the value of the fake enums you've created; e.g. BOLD will always be 1. The bad news is
that there's no easy or good way to make sure that the value of “style” will always be 0, 1, or 2. If some hard to
find piece of code sets “style” equal to 6, it's possible that your code will break..
Garbage collector:

gc() method is used to request for garbage collection.

inside System class we have following method:

public static void gc()


{
Runtime.getRuntime().gc();
}

Runtime.getRuntime().gc();

Class Runtime
getRuntime is reference of runtime======static
gc is the function=====non static method
e.g System.out.print();

System.gc();==is as compared to slow so use


Runtime.getRuntime().gc();

Example:

public class MyClass


{
@Override
protected void finalize()
{
System.out.println("in finalize method");
}
public static void main(String args[])
{
System.out.println("in main");
MyClass m=new MyClass();
m=null;
System.gc(); //garbage collection
for(int i=0;i<10;i++)
{
System.out.println("Hello\t"+i);
}
System.out.println("done");
}
}
Immutable Demo:

Immutable: Once you create a object you cannot change state(attribute)


you try to a new object will be created.

Mutable:is you can change its state anytime.

Immutable demo:
class Immutable
{
private int num;

public Immutable(int num)


{
this.num=num;
}
int getNum()
{
return num;
}
public String toString()
{
return "["+num+"]";
}
public Immutable add(int k)
{
return new Immutable(num+k);
}
}
public class ImmutableDemo
{
public static void main(String args[])
{
Immutable i1=new Immutable(10);
System.out.println(i1);
Immutable i2=i1.add(20);
//need to create new object in immutable

System.out.println(i1);
System.out.println(i2);
}
}

Mutable demo:

class Mutable
{
private int num;

public Mutable(int num)


{
this.num=num;
}
public void setNum(int num)
{
this.num=num;
}
int getNum()
{
return num;
}
public String toString()
{
return "["+num+"]";
}
public Mutable add(int k)
{
num+=k;
return this; //if we not return value we need to write
function in line i1.add(50) -> i1.add(20)
}
}
public class MutableDemo
{
public static void main(String args[])
{
Mutable i1=new Mutable(10);
System.out.println(i1);
i1.add(20).add(50).add(100); //directly call without
creating object
System.out.println(i1);
}
}

Object methods:
Demo1:

package day6;
class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}
}
public class ObjectDemo1
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
MyNum m2=new MyNum(100);

System.out.println(m1.toString()); //as per our comfort we use


or not use predefined
System.out.println(m2);

if(m1.equals(m2))
{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals"); //else
printed
}
if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");//else printed
}

System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}

Demo2:
package day6;
class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
}

public class ObjectDemo2


{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
MyNum m2=new MyNum(100);

System.out.println(m1.toString()); internal representation of


s.o.p(m1)
System.out.println(m2);

if(m1.equals(m2))
{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());}}
Demo 3:

class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
public boolean equals(Object ref) //if we want to compare the
data of object then we need to
override the function of object
{
//Num==ref.num; num variable is not in object class so it is
logically not possible
MyNum ob=(MyNum)ref; // downcasting
return num==ob.num;
}
}
public class ObjectDemo3
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
MyNum m2=new MyNum(100);

System.out.println(m1.toString());
System.out.println(m2);

if(m1.equals(m2)) // m1 goes implicitly and m2 get


explicitly
{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}

System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
What is diff between equals() and == ?

By default equals() and == operator both are same they check wether two
references refer to same obj or not cause equals() method of object
class
Internally uses == operator
The diff is that equals() can be overridden in order check the content

Demo 4:
class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
public boolean equals(MyNum ref)
{
System.out.println("equals with MyNum");
return num==ref.num;
}
}
public class ObjectDemo4
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
MyNum m2=new MyNum(100);

System.out.println(m1.toString());
System.out.println(m2);

if(m1.equals(m2)) //m1 is implicit and m2 is explicit


{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());}}
Demo 5:

class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
public boolean equals(MyNum ref)
{
System.out.println("equals with MyNum");
return num==ref.num;
}
}
public class ObjectDemo5
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
Object m2=new MyNum(100); //object class predefined god
class

System.out.println(m1.toString());
System.out.println(m2);

if(m1.equals(m2)) // even if we say m2.equals(m1)


{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}

System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
Demo 6:

class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
public boolean equals(Object ref)
{
MyNum ob=(MyNum)ref;
return num==ob.num;
}
}
public class ObjectDemo6
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
Object m2=new MyNum(100);

System.out.println(m1.toString());
System.out.println(m2);

if(m1.equals(m2))
{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}

System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
Demo 7:
class MyNum
{
int num;
MyNum(int num)
{
this.num=num;
}

public String toString()


{
return "["+num+"]";
}
public boolean equals(Object ref)
{
MyNum ob=(MyNum)ref;
return num==ob.num;
}
public int hashcode()
{
return num;
}
}
public class ObjectDemo7
{
public static void main(String args[])
{
MyNum m1=new MyNum(100);
Object m2=new MyNum(100);

System.out.println(m1.toString());
System.out.println(m2);

if(m1.equals(m2))
{
System.out.println("m1 and m2 are equals");
}
else
{
System.out.println("m1 and m2 are not equals");
}

if(m1==m2)
{
System.out.println("m1 and m2 are ==");
}
else
{
System.out.println("m1 and m2 are not ==");
}
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());}}
Equals() and hashCode() both are contract if equals is true must
hashCode() also returns the same value

Native classes defined in C++ and we only declare them


Native is like abstract one line declaration code
1.Whenever it is invoked on the same object more than once during an execution of a Java application, the
hashCode method must consistently return the same integer,provided no information in the object is
modified. This integer need not remain consistent from one execution of an application to another
execution of the same application.

2.If two objects are equal according to the equals(Object) method, then calling the hashCode method on
each of the two objects must produce the same integer result.

3.It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then
calling the hashCode method on each of the two objects must produce distinct integer results. They may
return same hashcode.

Why do we need string pool?


ans:-
a) Object creation in general is a time-consuming process.
b) Object creation costs memory.
c) to increase performance and to reduce overhead.

Demo1:

public class StringDemo1


{
public static void main(String args[])
{
String str1=new String("hello");

System.out.println(str1); // toString() of String


}
}

Demo2:
package day6;
public class StringDemo2
{
public static void main(String args[])
{
String s1=new String("hello");
String s2=new String("hello");

System.out.println(s1);
System.out.println(s2);

if(s1.equals(s2)) //this is check as per word wise


{
System.out.println("s1 and s2 are equals");
}
else
{
System.out.println("s1 and s2 are not equals");
}

if(s1==s2)
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}

Demo3:

package day6;
public class StringDemo3
{
public static void main(String args[])
{
String s1=new String("hello");
String s2="hello"; //string pool used

System.out.println(s1);
System.out.println(s2);

if(s1.equals(s2))
{
System.out.println("s1 and s2 are equals");
}
else
{
System.out.println("s1 and s2 are not equals");
}

if(s1==s2)
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}

Demo 4:

public class StringDemo4


{
public static void main(String args[])
{
String s1=new String("hello");
String s2="hello";
String s3="hello"; //both In same stringpool

System.out.println(s1);
System.out.println(s2);

System.out.println(s3);

if(s2.equals(s3))
{
System.out.println("s2 and s3 are equals");
}
else
{
System.out.println("s2 and s3 are not equals");
}

if(s2==s3)
{
System.out.println("s2 and s3 are ==");
}
else
{
System.out.println("s2 and s3 are not ==");
}
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
}

Demo 5:
package day6;
public class StringDemo5
{
public static void main(String args[])
{
String s1=new String("hello");
String s2="hello";
String s3="hello";

System.out.println(s1);
System.out.println(s2);

System.out.println(s3);

if(s1.equals(s3))
{
System.out.println("s1 and s3 are equals");
}
else
{
System.out.println("s1 and s3 are not equals");
}

if(s1==s3)
{
System.out.println("s1 and s3 are ==");
}
else
{
System.out.println("s1 and s3 are not ==");
}
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
}
Demo 6:
public class StringDemo6
{
public static void main(String args[])
{
String s1="hello";
String s2=new String("hello");

if(s1==s2)
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}

}
}

Demo 7:

public class StringDemo7


{
public static void main(String args[])
{
String s1="hello";
String s2=new String("hello");

if(s1.equals(s2))
{
System.out.println("s1 and s2 are equals");
}
else
{
System.out.println("s1 and s2 are not equals");
}

}
}

Demo 8://
/* When the intern method is invoked, if the pool already contains a
string equal to this String object as determined by the equals(Object)
method, then the string from the pool is returned

*/

public class StringDemo8


{public static void main(String args[])
{
String s1="hello";
String s2=new String("hello");

//2000 2000
if(s1 == s2.intern())
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}
}}

S2 will check the value of “Hello” and intern method goes to stringpool and
check the object where the value will match

Demo 9

/* When the intern method is invoked, if the pool already contains a


string equal to this String object as determined by the equals(Object)
method, then the string from the pool is returned. Otherwise, this
String object is added to the pool and a reference to this String
object is returned.

*/

public class StringDemo9


{
public static void main(String args[])
{
String s2=new String("hello");

String s1=s2.intern();
if(s1 == s2)
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}

}
}
Op are not equal

Demo 10:
public class StringDemo10
{
public static void main(String args[])
{
String s1="hello";

String s2=s1.concat(" world");

System.out.println(s1);
System.out.println(s2);
}
}
Demo 11:
* in this code what if we would like to ignore cases */

public class StringDemo11


{
public static void main(String args[])
{
String s1="admin";

String s2="Admin";

System.out.println(s1);
System.out.println(s2);

if(s1==s2)
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}

if(s1.equals(s2))
{
System.out.println("s1 and s2 are equals");
}
else
{
System.out.println("s1 and s2 are not equals");
}
}
}
admin
Admin
s1 and s2 are not ==
s1 and s2 are not equals

Demo 12:

public class StringDemo12


{
public static void main(String args[])
{
String s1="admin";

String s2="Admin";

System.out.println(s1);
System.out.println(s2);

if(s1==s2) // false
{
System.out.println("s1 and s2 are ==");
}
else
{
System.out.println("s1 and s2 are not ==");
}

if(s1.equals(s2)) // false
{
System.out.println("s1 and s2 are equals");
}
else
{
System.out.println("s1 and s2 are not equals");
}

if(s1.equalsIgnoreCase(s2)) // true
{
System.out.println("s1 and s2 are equalsIgnoreCase");
}
else
{
System.out.println("s1 and s2 are not
equalsIgnoreCase");
}
}
}

Demo 13:
public class StringDemo13
{
public static void main(String args[])
{
String s1="hello";

if(s1=="hel"+"lo") // compiler adds "hel" and "lo" and creates


"hello"
{
System.out.println("true");
}
else
{
System.out.println("false");
}

}
}

Demo 14:
public class StringDemo14
{public static void main(String args[])
{
String s1="hello";
String s2="hel";
//2000 4000
if(s1==(s2+"lo"))
{System.out.println("true");
}
else
{System.out.println("false");
}
}}
Demo 15:
public class StringDemo15
{
public static void main(String args[])
{
String s1=new String("hello");

if(s1==("hel"+"lo")) // compiler will add "hel" and "lo"


{
System.out.println("true");
}
else
{
System.out.println("false");
}

}
}False

Demo 16:
public class StringDemo16
{
public static void main(String args[])
{
String s1="hello";
final String s2="hel";

if(s1==(s2+"lo")) // compiler adds "hel" and "lo"


{
System.out.println("true");
}
else
{
System.out.println("false");
}

}
}

Demo 17:

public class StringDemo17


{
public static void main(String args[])
{
String str1="hello world";
System.out.println(str1.charAt(0)); //h

String str2=str1.concat(" welcome");


System.out.println("str1 is \t"+str1);//hello world
System.out.println("str2 is \t"+str2);//hello world welcome

int val=str1.compareTo(str2);
System.out.println("comparison is\t"+val);//-8 in two strin

System.out.println(str1.indexOf('e'));//1_in which index e


is located
System.out.println(str1.lastIndexOf('l'));//9_in last when l
is locat

System.out.println("Length of str1 is
\t"+str1.length());//10

String str3=str1.replace('e','i');//replace e to i
System.out.println(str1);
System.out.println(str3);

System.out.println(str1.substring(2));//llo

String str4="ABCDEFG";
String str5=str4.toLowerCase();//abcdefg
System.out.println(str4);
System.out.println(str5);

String str6=str1.toUpperCase();//ABCDEFG
System.out.println(str1);
System.out.println(str6);

String str7=" how are you ";


System.out.println(str7);

String str8=str7.trim();//to trim front space


System.out.println(str7);
System.out.println(str8);

}
}

Wrapper classes are used to wrap primitive types.

in java Wrapper classes are available for each primitive types.


e.g.

primitive Wrapper class

byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

earlier versions of java:

public class Demo


{
static void show(Object ref)
{
S.o.p(ref);
}
main()
{
show(new String("hello")); // alld
show(new ArrayList()); // alld
show(new LinkedList()); // alld
int num=10;
show(num); // was not possible

}
}

Solution: Wrapper classes were introduced

above program can be written as:

public class Demo


{
static void show(Object ref)
{
S.o.p(ref);
}
main()
{
show(new String("hello")); // alld
show(new ArrayList()); // alld
show(new LinkedList()); // alld
int num=10;
// show(num); // was not possible

Integer ob=new Integer(num);

show(ob); // this is possible

}
}

Before JDK1.5

converting primitive to Wrapper

int num=10;

Integer ob=new Integer(num);

JDK1.5 onwards

int num=10;
Integer ob=num; // Autoboxing

i.e. Autoboxing means assigning primitive to wrapper

here when we do autoboxing i.e.


Integer ob=num;
what compiler does is, compiler converts above statement into the
statement which we used to write before jdk5
i.e.
Integer ob=new Integer(num);
why compiler does this?
it's because JVM doesn't understand autoboxing.
So we can say that autoboxing is only at compiler level. It is just a
syntactical sugar for a developer.

Before JDK1.5

converting Wrapper to primitive

int num=10;

Integer ob=new Integer(num);

int temp=ob.intValue();

JDK1.5 onwards

int num=10;
Integer ob=num; // Autoboxing
int temp=ob; // unboxing

i.e. unboxing means assigning wrapper to primitive

here when we do unboxing i.e.


int temp=ob
what compiler does is, compiler converts above statement into the
statement which we used to write before jdk5
i.e.
int temp=ob.intValue();

why compiler does this?

it's because JVM doesn't understand unboxing.


So we can say that unboxing is only at compiler level. It is just a
syntactical sugar for a developer.

Demo1:
public class WrapperDemo1
{
public static void main(String args[])
{
// how do u wrap primitive inside the wrapper class ?

int num=100;
Integer ob=new Integer(num);
System.out.println(ob);
}
}
Demo2:

public class WrapperDemo2


{
public static void main(String args[])
{
String str="125";
str+=10; //12510
System.out.println(str);}}
Demo 3
public class WrapperDemo3
{
public static void main(String args[])
{
String str="125";
int k=Integer.parseInt(str);
k+=10;
System.out.println(k);
}
}

o/p = 135

Demo 4
public class WrapperDemo4
{
public static void main(String args[])
{
String str=" 125 ";
int k=Integer.parseInt(str.trim());
k+=10;
System.out.println(k);
}
}

Demo 5:
public class WrapperDemo5
{
public static void main(String args[])
{
int num=100;

// converting primitive to wrapper


Integer ob=new Integer(num);

// converting wrapper to primitive

int k=ob.intValue();
System.out.println(k);
}
}
Demo 6:
public class WrapperDemo6
{
public static void main(String args[])
{
int num=100;
System.out.println(num);

// converting primitive to wrapper


Integer ob=num; // autoboxing
System.out.println(ob);

// converting wrapper to primitive


int k=ob; // unboxing
System.out.println(k);
}
}

Day 7:
How to pass primitive to a method which has Object as a parameter JDK5
onwards

show(Object ref)
{
S.o.p(ref);
}
we can call this show() function as follows:

int num=100;
show(num); // it's possible from jdk5 onwards

how it's possible?

when you say


show(num); //not possible before jdk 5-after jdk 5 it is
possible

what compiler does ?


show(new Integer(num)); // autoboxing

i.e. compile does autoboxing ( converts int to Integer ) and pass that
Integer to the method which has "Object" as a parameter.

Varargs:

fixed no. of arguments function

void disp(int k,int p)


{
S.o.p(k+"\t"+p);
}
how will you call this function?

disp(10,20);

i.e. we must pass 2 arguments while calling this method. neither less
than 2 nor more than 2

what do you mean by variable no. of argument function ?

void disp(int ...k) // it can take 0 or more arguments


{
for(int i=0;i<k.length;i++)
{
S.o.p(k[i]);
}

}
[ ... is called as ellipsys]

how will you call this function ?


disp();
disp(10);
disp(10,20);
disp(10,20,30);
and so on .........

Demo 1:
public class Demo1
{
void disp(int ...set) //elipsys
{
for(int i=0;i<set.length;i++)
{
System.out.println(set[i]);
}
for(int k:set) // foreach_(Same convert it like traditional
for loop) set will internally traverse 10=k ,20=k
{
System.out.println(k);
}
}
public static void main(String args[])
{
Demo1 d=new Demo1();
d.disp(10,20);
System.out.println(".................");
d.disp(100,200,300,400,500);
}
}
getClass().getName()

class A
{
public String toString()
{
return "My Name is\t"+getClass().getName();
}
}

getClass() method belongs to "java.lang.Object" class. It has a return


type class "Class".
this method returns the object of class "Class" which represents
class "A".

getName() method belongs to "java.lang.Class" class. It has a return


type "String". when we invoke it, it returns the name of that class to
which class Class instance represents.

Demo2:
class A
{
public String toString()
{
return "My Name is\t"+getClass().getName();
}
}
class B
{
public String toString()
{
return "My Name is\t"+getClass().getName();
}
}
class C
{
public String toString()
{
return "My Name is\t"+getClass().getName();
}
}
class D
{
public String toString()
{
return "My Name is\t"+getClass().getName();
}
}
public class Demo2
{
void disp(Object ...col)
{
for(int i=0;i<col.length;i++)
{
System.out.println(col[i]);
}
System.out.println("Using foreach loop");
for(Object ref:col)
{
System.out.println(ref);
}
}
public static void main(String args[])
{
A ob1=new A();
B ob2=new B();
C ob3=new C();
D ob4=new D();
new Demo2().disp(ob1,ob2,ob3,ob4);
}
}

overloading_info_with_widening_and boxing:

Overloading- considering
a)Widening (upcasting )
b)Autoboxing
c)Var-args

Widening beats boxing ... widening wins


Widening beats var-args ... widening wins
boxing beats var-args ...boxing wins

1)
void disp(int x) //windings
{
System.out.println("in int");
}
void disp(short y) //windings
{
System.out.println("in short");
}

byte b=30;
disp(b);

Ans:- in short
Primitive widening uses the "smallest" method argument possible.

2)

class A
{
void disp(Integer x) //boxing_Wrapper
{
S.o.p("in Integer");
}
void disp(int x) //widenings
{
S.o.p("in int");
}

.......
int num=5;
disp(num);
}

Ans:- in int
Boxing has taken a back seat

3)

class A
{
void disp(Integer x) //boxing
{
S.o.p("in Integer");
}
void disp(long x) //widening
{
S.o.p("in long");
}

.......
int num=5;
disp(num);
}
Ans:- in long
widening beats boxing

4)
class A
{
void disp(int x,int y) //widening
{
System.out.println("in two ints");
}
void disp(byte ...x) //varargs
{
System.out.println("in byte var arg");
}

.....
byte a=3,b=6;
disp(a,b);
}
Ans:- in two ints
Compiler chooses old style

5)

class A
{
void disp(Byte x,Byte y) //boxing
{
System.out.println("in two Bytes");
}
void disp(byte ...x) //varargs
{
System.out.println("in byte var arg");
}

.......
byte a=3,b=6;
disp(a,b);
}
Ans:- in two Bytes
boxing beats var-args

Imp:- Reference widening depends upon inheritance.


Wrapper classes are peers(cousins,friends,collegues) to each other.

6)
e.g following code will not work

void disp(Long x) //boxing _both are


{
System.out.println("in Long");
}

disp(new Integer(4)); //boxing

// compiler error
7)
Overloading When combining Widening and Boxing.

void disp(Long x) //Boxing


{
System.out.println("in Long");
}

byte b=4; //primitive/widening


disp(b);

Above code will not work

compiler can do boxing followed by widening operation

e.g Following code will work.

void disp(Object o) //object is father of all classed and byte is


child class so do upcasting
{
System.out.println("in Object");
}

byte b=4;
disp(b); //boxing disp(new Byte(b)) first autoboxing i.e. byte
will be converted to Byte and then Byte will be passed to Object [
upcasting ]

8)

Overloading in combination with Var-args


You can combine var-args either with widening or boxing , not both.

e.g. Following code will not work because of "ambiguity"

void disp(long...x) //windening elipsys


{
System.out.println("in long var args");
}
void disp(Integer...y) //boxing elipsys
{
System.out.println("in Integer var args");
}

int p=20,q=30;
disp(p,q);

Rules For Overloading methods using Widening, boxing, and var-args.


1) Primitive widening uses the "smallest" method argument possible.
2) Used individually, boxing and var-args are compatible with
overloading.
3) You cannot widen from one wrapper type to another (IS-A fails).
4) You cannot widen and then box (An int can't become Long).
5) You can box and then widen.(An int can become an Object, via
Integer).
6) You can combine var-args with either widening or boxing.

Command line arguments:

arguments which can be given to the running java program. it also means
that arguments given to main function. in Java main function is always
ready to accept command line arguments.

public static void main(String args[])

public class CommandLineDemo


{
public static void main(String args[])
{
for(int i=0;i<args.length;i++)
{
System.out.println(args[i]);
}
}
}

how to run above program?

java CommandLineDemo abc xyz pqr

Why main function's signature is:

public static void main(String args[])


or
public static void main(String ...args)

public - JVM should be able to access it

static - JVM should be able to invoke it without the object of a


class in which main function is defined.
void - main function is not supposed to return anything to the
JVM
String args[] - main function should be ready to accept command
line arguments
command line arguments are those which we pass at the
time of executing the program. These are the arguments which are passed
to the main function.

public class WrapperDemo1


{
public static void main(String args[])
{
String str="125";
System.out.println(str);
str+=10;
System.out.println(str); // 12510 i.e. concatenation

str="125";
// lets convert str into int
int k=Integer.parseInt(str);
k+=10;
System.out.println(k); // 135
}
}

parseInt()__is used for convert string to int.


-if we write arr[i]+arr[1] without parseInt we get 100200.
-using parseInt ans is 300

In eclipse how we use command line argument


Right click->run as->run as configurator->java class name->arguments-
>program arguments->enter numbers 100 200 300

Imp_Info_Protected:

Protected members are “accessible outside the package only through inheritance“.
i.e you can access a protected member of a class in its subclass present in some other
package directly as if the member is present in the subclass itself. But that protected member
will not be accessible in the subclass outside the package by using parent class’s reference.
e.g.
package core1;
public class Base
{
protected int cnt=20;
}

package core2;

import core1.Base;

class Sub extends Base


{
void disp1()
{
System.out.println(cnt); // valid
}
static void disp2()
{
System.out.println(new Sub().cnt); // valid
// System.out.println(new Base().cnt); // invalid
}
}
public class MyClass1
{
public static void main(String[] args)
{
//System.out.println(new Sub().cnt); // invalid
//System.out.println(new Base().cnt); // invalid
}

Demo1:
package trial;

public class MyClass1 {


protected void disp()
{
System.out.println("inside MyClass1 disp");
}
}

package trial1;

import trial.MyClass1;

class Sub extends MyClass1


{
void fun()
{
disp();// no error // through inheritance
//new MyClass1().disp();// error
}
protected void disp()
{
System.out.println("inside overridden disp of sub");
}
}
class Sub1 extends Sub
{
void disp2()
{
disp(); // disp of MyClass1 if Sub does not override
// new Sub().disp(); // error if Sub does not override
// new MyClass1().disp(); // error
}
}
public class MyClass2
{
public static void main(String[] args)
{
// new Sub().disp(); //error if Sub does not override
new Sub().fun();
new Sub1().disp2();
}
}

Bridge Methods in Java:


what is bridge method in java?
or
how does co-variant return type work in java?

class Base
{
Object disp()
{
System.out.println("in Base disp");
return null;
}
}
class Sub extends Base
{
String disp()
{
System.out.println("in Sub disp");
return null;
}

Object disp() // bridge method will be provided by compiler and


will be called during runtime
{
invoke "String disp()" method of the same class //jvm don’t
know this
}

}
public class BridgeDemo
{
public static void main(String args[])
{
Base ref=new Sub();
ref.disp(); // during runtime check the content of "ref"
and invoke "Object disp()" method
// so during runtime since the content of "ref" is
"Sub", "Object disp()" of Sub which is a bridge method gets
//called which invokes "String disp()" which programmer has
defined.

// if we write following statements


ref=new Base();
ref.disp(); // Base class "Object disp()" will be called
}
}
Day 8

Exception Handling: An exception is an event, which occurs during the


execution of a program, that interrupts the normal flow of the
program's instructions.

Why exception:

In traditional programming, error detection, reporting, and handling


often lead to confusing code because programmers would use error code
inside the main logic.
Exceptions are readable e.g.
FileNotFoundException,ClassNotFoundException,NullPointerException etc.

A second advantage of exceptions is the ability to propagate error


reporting up the call stack of methods. i.e. if a method does not want
to handle an exception it can propagate it to the caller and so on. we
did not have this advantage in traditional programming.

Thid advantage is, because all exceptions thrown within a program are
objects, the grouping or categorizing of exceptions is a natural
outcome of the class hierarchy.

Due to programmer error Due to system error


Unchecked error checked error
Null pointer exception=if we make ref is null and if we call non static
method using that ref it gives null pointer exception
But if we call static method it will access

NumberFormatException= occurs when an attempt is made to convert a string


with improper format into a numeric value.e.g xyz yzf

ClasscastException= parent is animal in that roar is function.and tiger is


child in which roar and kill tiger is function we call only with roar by
upcating if we call kill tiger is class cast exception

String object cannot be cast to an integer object and attempting to do so


will result in a class cast exception

indexoutofBoundsException=arr[4] and we call arr[5]=10

io exception-file not present when compile

Sql exception-if we pass select , from table it will compile In java but
show error in sql.

exception can be raised by


a) JVM
or
b) Application [ Developer ]

When exception is raised , it happens in two steps :

a) instantiation of that particular exception class


b) throwing that exception (that instance) to the caller.

Exception Handling Keywords

Throw

Exceptions can be thrown by either java run time environment or by the code itself. JRE throws
exception when java’s rules are violated. An example is, when the code accesses an array location
which is not available then ArrayIndexOutOfBoundsException is thrown. Pretty nice name right and
obviously it explains the problem. All the java exception classes are not having any attributes and
standard methods. It is a common design. Class name describes what exception it is and the hierarchy
forms an organization chart kind of structure using which java exceptions are used.

Programmers can throw an exception to indicate a problem condition. Either java’s predefined
exceptions can be used or custom exceptions can be created by extending the already available
exceptions. Programmer can throw a custom exception or a predefined Java exception. Mostly custom
exceptions are created based on business conditions. Programmer can use the Java keyword ‘throw‘
to generate an exception. It is done by instantiating the exception class of choice and then thrown.

try – catch

A thrown exception should be handled. If the program does not handles an exception, then it will be
handled by the java run time environment. A block of code where an exception is expected should be
surrounded by try – catch block. try indicates the start of the exception handling block and catch the
end of the block. Following catch a block of code can be written which is the exception handling code
block. This is the part the handles the exception. A catch will have an exception identified and it will
catch only that type of exception. Type means the same exception and all its sub classes. There can be
multiple catch blocks for a try block.

throws

When a Java method is going to throw an exception, to indicate that as part of the method signature
‘throws‘ keyword should be used followed by the exception. It means that the caller of this method
should handle the exception given in the throws clause. There can be multiple exceptions declared to
be thown by a method. If the caller of that method does not handles the exception, then it propagates
to one level higher in the method call stack to the previous caller and similarly till it reaches base of
the method call stack which will be the java’s run time system.

finally

After catch block there can be one more block of code declared as ‘finally‘. Irrespective of whether
an exception is thrown or not, the finally block of code will always be executed. Important piece of
code that must be executed, even if a program fails belong to this finally block. Example would be
closing a database connection, a file handle, etc.

finally block gets executed irrespective of whether exception is raised


or not.
it can be used to release resources such as file,socket,database
connection etc. since you can not rely upon "finalized" method for the
same task.
finally block can follow after catch (try..catch...finally ) or even
after try (try...finally).
finally block will not get executed if
a) System.exit(0) is called inside try ,catch or finally block.
b) exception gets raised in finally block itself.

Demo 1:

public class Example1


{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
arr[4]=10;
System.out.println("Array assigned");
}

}//ArrayIndexBoundException

Demo2:

ArrayIndexOutOfBoundsException:
public class Example2
{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
try
{
arr[4]=10;
}
catch(ArrayIndexOutOfBoundsException ae) //exception class
sub class
{
//System.out.println(ae);
ae.printStackTrace(); //check on which line have
exception
}
System.out.println("Array assigned");
}
}

Demo3:
// one try , multiple catch blocks.
public class Example3
{
public static void main(String args[])
{
int arr[]=new int[4];
Example6 e1=null;
System.out.println("Array created");
try
{
arr[4]=10; //only check first line error so throw to
catch
e1.toString();
}
catch(ArrayIndexOutOfBoundsException ae)
{
System.out.println(ae);
}
catch(NullPointerException ne)
{
System.out.println(ne);
}
System.out.println("Array assigned");
}
}

Demo 4:
// the most generic catch block.
public class Example4
{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
try
{
arr[4]=10;
}
catch(Exception ae) //father of all exception_generic catch
block
{
System.out.println(ae);
}
System.out.println("Array assigned");
}
}
Demo 5:
// one try , multiple catch blocks.
/* when u define one try and multiple catch, the rule is most specific
catch block should precede most generic catch block
public class Example5
{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
try
{
arr[4]=10;
}
catch(ArrayIndexOutOfBoundsException ae)
{
// if i want to perform any specific task in case of
AIOOB(ArrayIndex………)
System.out.println(ae);
}
catch(Exception ae)
{
System.out.println(ae);
}

System.out.println("Array assigned");}}
Demo 6:
public class Example6
{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
try
{
arr[4]=10;
}
catch(ArrayIndexOutOfBoundsException ae)
{
System.out.println("In catch\t"+ae);
}
finally
{
System.out.println("I am always printed"); //always
printed
}
System.out.println("Array assigned");
}
}

Demo 7:
/*
finally{} block always executes whether or not exception is raised
*/
public class Example7
{
public static void main(String args[])
{
int arr[]=new int[4];
System.out.println("Array created");
try
{
arr[3]=10;
}
catch(ArrayIndexOutOfBoundsException ae)
{
System.out.println("In catch\t"+ae);
}
finally
{
System.out.println("I am always printed");
}
System.out.println("Array assigned");
}
}
What is “handle or declare” rule?
Ans:- a) whenever any method raises checked exception/s , method has to either handle
[try….catch] or declare [throws] that checked exception/s.
b) whenever u invoke a method which has declared [using throws] checked exception/s , caller
method has to either handle [try….catch] or declare [throws] that checked exception/s.

throws-declare
throw-raise
handle-try catch

how to create user defined exception?


checked exception or unchecked exception

for checked exception:

public class MyException extends Exception{} //input output


exception

for unchecked exception:

public class MyException extends RuntimeException{} //null


pointer

on what basis you will decide whether to create checked or unchecked


exception?

you create checked exception when you would like your client to take
corrective action/s in case of exception. i.e. checked exception
somehow enforces client to handle it. (using try...catch) and the
corrective action/s can be taken inside catch block.

you create unchecked exception when you feel there is no need of any
corrective action by client in case of exception.

User defined exception:


Myexception:
public class MyException extends Exception
{
public MyException(String mess) //4)constructor of myexception
{
super(mess); //using super go to constructor of exception
class pass the string zero or negative not allow to exception class
}
}
In calc:
public class Calc
{
public int sqr(int num)throws MyException //3)declare exception
and go to myexception
{
if(num<=0) //1)-9 is less than zero
{
throw new MyException("Zero or negative not allowed");
//2)raise the exception
}
return num*num;
}
}
Clientapp:
public class ClientApp
{
public static void main(String args[])
{
Calc c=new Calc();
int result=0;
try
{
result=c.sqr(-9);
System.out.println(result); //is we provide positive
it will print sqare
}
catch(MyException m)//last)if -9 catch and print m
{
System.out.println(m);
}
System.out.println("Done");
}
}

Client 1:
public class ClientApp1
{
static void disp()throws MyException
{
Calc c=new Calc();
int result=0;
result=c.sqr(-9);
System.out.println(result);
}
public static void main(String args[])
{
try
{
disp();
}
catch(MyException m)
{
System.out.println(m);
}
System.out.println("Done");
}}
ClientApp 2:

public class ClientApp2


{
static void disp()throws MyException
{
Calc c=new Calc();
int result=0;
result=c.sqr(-9);
System.out.println(result);
}
public static void main(String args[])throws MyException//if we
throw exception jvm show runtime error,if we throws Myclass then it
works correct
{
disp(); //not handled only
System.out.println("Done");
}
}

throws keyword is used to "declare" exception.

what do you mean by "declaring" exception ?

"Declaring" exception means propagating it to the caller and then it's


caller's resposibility to "handle or declare".

will following code work? No

try
{

some code
}
catch(Object e) //exception or error type
{

no above code wont compile.

why?

because if "catch(Object)" is allowed , then people can write

throw new String("hello");

throw new Integer(20);

throw new Sample();

etc.

and the rule is along with "throw" you can have class of type
"Throwable" only.
Types of Exceptions in Java

Java defines two kinds of exceptions:

 Checked exceptions: Exceptions that inherit from the Exception class


are checked exceptions. Checked exceptions are those exceptions which
can be raised in a correct program. Client code has to handle the checked
exceptions thrown by the API, either in a catch clause or by forwarding it
outward with the throws clause.//ioexceptions ,sql exception

 Unchecked exceptions: Unchecked exceptions are those exceptions


which can be raised due to programming mistakes.
RuntimeException also extends from Exception. However, all of the
exceptions that inherit from RuntimeException get special treatment.
There is no requirement for the client code to deal with them, and hence
they are called unchecked exceptions. //null point ,arrayindexoutofbound
exceptions

Demo 1

package core1;
import java.io.IOException;

public class jdb1


{
void disp3()
{
int num=20;
if(num>10)
{
throw new IOException(); // compilation error : add throws or
try_catch
}
}
void disp2() //culprit to exception
{
disp3();
}
void disp1()
{
disp2();
}
public static void main(String args[])
{
jdb1 j=new jdb1();
j.disp1();
}
}
Demo 2:

package core1;

import java.io.IOException;

public class jdb1


{
void disp3()throws IOException
{
int num=20;
if(num>10)
{
throw new IOException();
}
}
void disp2()
{
disp3(); // compilation error: add throws or try_catch
}
void disp1()
{
disp2();
}
public static void main(String args[])
{
jdb1 j=new jdb1();
j.disp1();
}
}

Demo 3:
package core1;

import java.io.IOException;

public class jdb1


{
void disp3()throws IOException
{
int num=20;
if(num>10)
{
throw new IOException();
}
}
void disp2()throws IOException
{
disp3();
}
void disp1()
{
disp2(); // compilation error: add throws or try_catch
}
public static void main(String args[])
{
jdb1 j=new jdb1();
j.disp1();
}}
Demo 4:
package core1;

import java.io.IOException;

public class jdb1


{
void disp3()throws IOException
{
int num=20;
if(num>10)
{
throw new IOException();
}
}
void disp2()throws IOException
{
disp3();
}
void disp1()throws IOException
{
disp2();
}
public static void main(String args[])
{
jdb1 j=new jdb1();
j.disp1(); // compilation error : add throws or try_catch
}
}

Demo 5:

package core1;

import java.io.IOException;

public class jdb1


{
void disp3()throws IOException
{
int num=20;
if(num>10)
{
throw new IOException();
}
}
void disp2()throws IOException
{
disp3();
}
void disp1()throws IOException
{
disp2();
}
public static void main(String args[])throws IOException // bad idea
{
jdb1 j=new jdb1();
j.disp1();
}
}

No compilation error Output: RuntimeException…….


Demo 6:

package core1;

import java.io.IOException;

public class jdb1


{
void disp3()throws IOException
{
int num=20;
if(num>10)
{
throw new IOException();
}
}
void disp2()throws IOException
{
disp3();
}
void disp1()throws IOException
{
disp2();
}
public static void main(String args)
{
jdb1 j=new jdb1();
j.disp1();

try
{
j.disp1();
}
catch(IOException e)
{
System.out.println(e); //now it worksp properly
}

}
}

Catching multiple exceptions in a single catch:

/*
Catching multiple exceptions in a single catch block reduces code
duplication and increases efficiency.

The bytecode generated while compiling this program will be smaller


than the program having multiple catch blocks as there is no code
redundancy.
*/
Demo 1:
package firstpro;
public class Demo1
{
public static void main(String[] args)
{
try {
int array[] = new int[10];
array[10] = 30 / 0;
}
catch (ArithmeticException | ArrayIndexOutOfBoundsException e)
//as wee as
{
System.out.println(e.getMessage());
}
}
}

/*
output:

/ by zero

*/

|=>(as well as) single pipe ,use more than one exception

Demo 2:

package firstpro;
public class Demo2
{
public static void main(String[] args)
{
try {
int array[] = new int[10];
array[10] = 30 / 5;
}
catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}

/*
output:
java.lang.ArrayIndexOutOfBoundsException: 10
at firstpro.Demo2.main(Demo2.java:10)
Done
*/
Demo 3:

/*If the base exception class has already been specified in the
catch block, do not use child exception classes in the
same catch block. Otherwise, we will get a compilation error.*/

package firstpro;

public class Demo3


{
public static void main(String[] args)
{
try {
int array[] = new int[10];
array[10] = 30 / 5;
}
catch (ArithmeticException | Exception e) // Error
{
e.printStackTrace();
}
System.out.println("Done");

Demo 4:
/*If the base exception class has already been specified in the
catch block, do not use child exception classes in the
same catch block. Otherwise, we will get a compilation error.*/

package firstpro;

public class Demo4


{
public static void main(String[] args)
{
try {
int array[] = new int[10];
array[10] = 30 / 5;
}
catch (Exception | ArithmeticException e) // error
{
e.printStackTrace();
}
System.out.println("Done");

}
R n d about runtime exception:

package datatypes_pro;

import java.io.IOException;

public class Demo


{
void disp1()throws Exception // works
{

}
void disp2()throws RuntimeException // works
{

}
void disp3()
{
throw new Exception(); // error either handle or declare
bcoz parent not handle child
}
void disp4()
{
throw new RuntimeException(); //works
}
public static void main(String ...arg)
{
System.out.println("in main");

/* following try and catch block will give compilation


error:
* Unreachable catch block for IOException.
* This exception is never thrown from the try statement
body
*/
try
{

}
catch(IOException ii)
{
ii.printStackTrace();
}

/*
* No problem about following try and catch block
*/
try
{
}
catch(RuntimeException re)
{
re.printStackTrace();
}
}
}

ARM(Automatic resource management):

what is Resource Management?

it means releasing the resources once you used them.

Before java7 programmer had to do Explicit Resource Management.

e.g

try
{
FileInputStream fis=new FileInputStream("abc.txt");
// code to read the file
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
fis.close();
}
what is exactly Automatic Resource Management (ARM) ?

it means now (java7 onwards) programmer can write the code as


follows:

// ARM block

try(FileInputStream fis=new FileInputStream("abc.txt"))


{
// code to read the file
}
catch(FileNotFoundException e)
{
e.printStackTrace();
} //this all is arm block

That's it. it means you don't have to define "finally" block.

when you compile above code , compiler will convert this code into:

try
{
FileInputStream fis=new FileInputStream("abc.txt");
// code to read the file
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
fis.close();
}

That is compiler provides "finally" block which has "fis.close()"


statement. So since compiler takes care of releasing resource/s , It is
known as "Automatic Resource Management"

can we write any class inside ARM block?

No. inside ARM block you can write only those classes which
implement "AutoCloseable" or "Closeable" interface.

Assertions

Assertions are used to test the program. The advantage is assertions


are by default disable, u need to enable them.

Assertions vs System.out.println statements while testing the code:


if u write S.o.p statements while testing the code, u need to remove or
comment them while the code goes to client.

if u write assert statements u need not do anything as assertions


are by default disable.

How to do in eclipse:
Right click->run as configurator->name of code->arguments->vm
arguments->-ea so it enables assertion

public class AssertDemo


{
public static void main(String args[])
{
System.out.println("Before checking num");
int num=10;
assert(num<=10);
System.out.println("After checking num");

assert(num>20):"num is not gt 20"; //show error


System.out.println("After checking num");
}
}

assert boolean expression

here if boolean expression is true , remaining code will get


executed.if expression is false, then AssertionError will come.

it is recommended not to handle AssertionError (though we can handle


it)
because when it comes we would like to stop the execution.

Class not found:

public class Demo


{
public static void main(String args[])
{
try
{
Class.forName("com.mysql.jdbc.Driver");//forName is
used to load class explicitly and com.mysql.jdbc.Driver this is
package there is much setting to load class so we cannot do that so
class not found error

}
catch(ClassNotFoundException cnfe)
{
cnfe.printStackTrace();
}
System.out.println("done");
}
}

No class def:
class Y
{

class Z
{
}
public class Demo
{
static Y ref=new Y();
public static void main(String args[])
{
System.out.println("in main");
Z ref1=new Z();
}
}

If we compile both class x and y if anyone class is deleted so it shows no class def

what are the ways to load a class ?

a) object creation or static member invocation for the first time

b) java MyClass(by creating oject)

c) Class.forName() is used to load a given class.


overriding and checked-exception rule :

same argument
return type can be covariant
access specifier same or more than that

a) overriding method may not declare any checked exception.


b) overriding method can declare same checked exception or its sub-type
declared by overriden method.
c) overriding method can not declare checked exception not declared by
overriden method.

overriding method may not declare any checked exception.

class base
{
public void disp()throws IOException
{
}
}
class sub extends base
{
public void disp()
{
}
}

main()
{
base ref=new sub();

ref.disp();

overriding method can declare same checked exception

class base
{
public void disp()throws IOException
{
}
}
class sub extends base
{
public void disp()throws IOException
{
}
}

main()
{
base ref=new sub();
ref.disp();

overriding method can declare same checked exception or its sub-type


declared by overriden method.

class base
{
public void disp()throws IOException
{
}
}
class sub extends base
{
public void disp()throws EOFException
{
}
}

main()
{
base ref=new sub();

ref.disp();

overriding method can not declare checked exception not declared by


overriden method.

// following code will not work

class base
{
public void disp()throws IOException
{
}
}
class sub extends base
{
public void disp()throws Exception
{
}
}

main()
{
base ref=new sub();
ref.disp();

}
class base
{
public void disp()
{
}
}
class sub extends base
{
public void disp()throws Exception // compilation error(parent
cannot access child)
{
}
}

main()
{
base ref=new sub();
ref.disp();
}

Day7_remaining part

Inner classes:

Inner class makes the code more readable and maintainable.

The inner class shares a special relationship with the outer class i.e. the inner class has access to all
members of the outer class and still have its own type is the main advantages of Inner class.
Advantage of inner class is that they can be hidden from the other classes in the same package and
still have the access to all the members (private also) of the enclosing class. This increases the level of
encapsulation.

Inner classes are best used in the event handling mechanism and to implement the helper classes.

Nested classes are divided into two categories: static and non-static.

Nested classes that are declared static are called static nested classes.

Non-static nested classes are called inner classes.

classes which are defined inside any method are known as "Local Inner Classes".

Outer class/nested class demo1:

public class Outer


{
int num1=20;
void disp1()
{
System.out.println("in disp1");
}
Outer()
{
System.out.println("in Outer def const");
/*inner ref=new inner();
ref.disp2();*/
}
static
{
System.out.println("in outer static block");
}
class inner //class Inner is present in outer
{
int num2=30;
final int kk=60;
static final int op=9;
void disp2()
{
System.out.println("in disp2");
disp1();
}
static
{
System.out.println("in inner static block");
}
}
public static void main(String args[])
{
Outer o=new Outer();
System.out.println(o.num1);
o.disp1();
Outer.inner i=o.new inner();
i.disp2();
}
}
class Outer
{
private int num1=10;
int num2=20;
protected int num3=30;
public int num4=40;

static int num5=50;

static
{
System.out.println("in Outer static block");
}

void outerDisp()
{
System.out.println(num1+"\t"+num2+"\t"+num3+"\t"+num4);
}

static class inner //static block in inner


{
void innerDisp()
{
System.out.println(num5);
}
static
{
System.out.println("in inner static block");
}
}
}

public class Demo


{
public static void main(String args[])
{
Outer o1=new Outer();
Outer.inner i=new Outer.inner();

o1.outerDisp();
i.innerDisp();
}
}
Anonymous class:

It is not compact:

interface Myinterface{

void disp();

class Myclass implements Myinterface{

@Override

public void disp() { //define

// TODO Auto-generated method stub

class task{

Myinterface disp() { //override

return new Myclass(); //intialize

}
It is compact:

interface emp
{
void disp();
}
public class AnonymousDemo
{
static emp getEmp() //static method
{
return new emp() //return , initialization
{
public void disp() //definition implement
{
System.out.println("in disp");
}
};
}
/*static emp getEmp()
{
emp e=new emp() //reference created
{
public void disp() //implement,initialization
{
System.out.println("in disp diff way");
}
};
return e; //return reference
}*/
public static void main(String args[])
{
emp e1=AnonymousDemo.getEmp();
e1.disp();
}
}

Day 9:
Cloning:

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

If the cost of creating a new object is large and creation is resource intensive, we clone the object. We use the
interface Cloneable and call clone() method to clone the object.

Marker:in such method no any abstract method(air).


imp. points about object cloning in java
java.lang.Object class has

protected Object clone()throws CloneNotSupportedException


method
if you need to clone object of a particular class, that class has to
a) implement "Cloneable" interface
[ Cloneable interface does not have any abstract method. It's a marker
interface ]
b) override "clone()" method of Object class.

Does Object class implement Cloneable interface ?


No. Why ?

Java founders did not make Object class implements Cloneable. Had they
made Object class implement Cloneable , each and every class in Java
would have become Cloneable ( eligible for cloning). This is what they
( java founders) did not want. They wanted to give a choice to the
programmer. If programmer would like to clone the object , then he can
implement the class with Cloneable otherwise not.
If we object class implements clonable interface then all each and every classes
then become clonable.

Why object class in clone is protected ?


suppose you are a developer and develop one class for clients. e.g.

public class MyClass


{
members and methods
}

now this class is derived from Object which has "protected Object
clone()" method. It means MyClass has the same method because it hasn't
overridden "clone()" method. Now think can client from some other
package invoke "clone()" method of MyClass?
answer is :
if client creates the child class of "MyClass" then client can
invoke "clone()" method through inheritance ( direct call) , but if
client creates object of MyClass and tries to invoke it is not
possible. Client will not always create child class of MyClass without
any valid reason.
In this case if developer would like clients to invoke "clone()" using
the reference of MyClass, he will override it with "public"
accessibility.
Hence to give a choice to a programmer (in our example developer)
whether or not his clone method should be invoked by client, "clone()"
method is protected in Object class.

Clone class is protected to override we use protected or public bcoz


developer has a choice to give access client or not by doing class
public or protected
Without copy:
package core1;

import java.util.Arrays;

class Center // Immutable class


{
private String name,address;
private int prnnos[];
//private int prnnos[]= {100,200,300,400,500};
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the address
*/
public String getAddress() {
return address;
}
/**
* @return the prnnos
*/
public int[] getPrnnos() {
return prnnos;
}
/**
* @param name
* @param address
* @param prnnos
*/
public Center(String name, String address, int[] prnnos) {
super();
this.name = name;
this.address = address;
this.prnnos = prnnos;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Center [name=" + name + ", address=" + address + ",
prnnos=" + Arrays.toString(prnnos) + "]";
}

}
public class Test8
{
public static void main(String args[])
{
Center c1=new Center("Vita","mumbai",new int[]{100,200,300,400,500});
System.out.println(c1);
// c1.setName --- not possible
// c1.setAddress --- not possible //no hava a setters to
become immutable class members
// c1.setPrnnos --- not possible

int temp[]=c1.getPrnnos();
System.out.println("let's display all prnnos");
for(int i=0;i<temp.length;i++)
{
System.out.println(temp[i]);
}
temp[1]=0; // violation of Immutability you can make
changes in array so it becomes mutable.
System.out.println(c1);
}
}
With copy1:

package core1;

import java.util.Arrays;

class Center // Immutable class


{
private String name,address;
private int prnnos[];
//private int prnnos[]= {100,200,300,400,500};
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the address
*/
public String getAddress() {
return address;
}
/**
* @return the prnnos
*/
// let's return copy of prnno array
public int[] getPrnnos() {
int prncopy[]= {100,200,300,400,500};
return prncopy; //copy only changed
}
/**
* @param name
* @param address
* @param prnnos
*/
public Center(String name, String address, int[] prnnos) {
super();
this.name = name;
this.address = address;
this.prnnos = prnnos;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Center [name=" + name + ", address=" + address + ",
prnnos=" + Arrays.toString(prnnos) + "]";
} //not need to use this

}
public class Test8
{
public static void main(String args[])
{
Center c1=new Center("Vita","mumbai",new
int[]{100,200,300,400,500});
System.out.println(c1);

// c1.setName --- not possible


// c1.setAddress --- not possible
// c1.setPrnnos --- not possible

int temp[]=c1.getPrnnos();
System.out.println("let's display all prnnos");
for(int i=0;i<temp.length;i++)
{
System.out.println(temp[i]);
}
temp[1]=0; // No problem as we are modifying copy
System.out.println(c1);
}
}

Shallow copy:as it is copy


Deep copy: copy by modifying

With copy2:

By using clone array go to object find clone(copy) of array in object in


object and override

package core1;

import java.util.Arrays;

class Center // Immutable class


{
private String name,address;
private int prnnos[];
//private int prnnos[]= {100,200,300,400,500};
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the address
*/
public String getAddress() {
return address;
}
/**
* @return the prnnos
*/
// let's return copy of prnno array
public int[] getPrnnos() {
int[] prncopy=prnnos.clone(); //clone the array go to object
class and override
return prncopy;
}
/**
* @param name
* @param address
* @param prnnos
*/
public Center(String name, String address, int[] prnnos) {
super();
this.name = name;
this.address = address;
this.prnnos = prnnos;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Center [name=" + name + ", address=" + address + ",
prnnos=" + Arrays.toString(prnnos) + "]";
}

}
public class Test8
{
public static void main(String args[])
{
Center c1=new Center("Vita","mumbai",new
int[]{100,200,300,400,500});
System.out.println(c1);

// c1.setName --- not possible


// c1.setAddress --- not possible
// c1.setPrnnos --- not possible

int temp[]=c1.getPrnnos();
System.out.println("let's display all prnnos");
for(int i=0;i<temp.length;i++)
{
System.out.println(temp[i]);
}
temp[1]=0; // No problem as we are modifying copy
System.out.println(c1);
}
}
Test 1:
package core;
class Engine
{
private int speed;

public Engine(int speed) {


super();
this.speed = speed;
}

public int getSpeed() {


return speed;
}

public void setSpeed(int speed) {


this.speed = speed;
}
}
class Car implements Cloneable //clonable interface implements
{
private Engine ref;
private String name;
public Car(String name) {
super();
this.name = name;
this.ref=new Engine(100);
}
public Engine getRef() {
return ref;
}
public void setRef(Engine ref) {
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException
//compulsory
{
// TODO Auto-generated method stub
return super.clone(); //return to object
}

}
public class Test1
{

public static void main(String[] args)


{
Car c=new Car("Nano");
try {
c.clone();
}

catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done");
}

Test 2:

class Engine
{
private int speed;

public Engine(int speed) {


super();
this.speed = speed;
}

public int getSpeed() {


return speed;
}

public void setSpeed(int speed) {


this.speed = speed;
}

@Override
public String toString() {
return "Engine [speed=" + speed + "]";
}

}
class Car implements Cloneable
{
private Engine ref;
private String name;
public Car(String name) {
super();
this.name = name;
this.ref=new Engine(100);
}
public Engine getRef() {
return ref;
}
public void setRef(Engine ref) {
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone()
{
Car ob=null;
try {
ob=(Car)super.clone(); //super.clone() call and
downcat that clone in car and put it in ob
}
catch (CloneNotSupportedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return ob;
}
@Override
public String toString() {
return "[name=" + name + " ref=" + ref + "]";
} //aapn dilel print honr address print honr use nhi kel tar

}
public class Test2
{
public static void main(String[] args)
{
Car c=new Car("Nano");
Car c1=(Car)c.clone();//downcasting and copy created
System.out.println(c);
System.out.println(c1);
c1.getRef().setSpeed(400); //set speed 400 to engine and
getRef() from car

System.out.println("After Modification");

System.out.println(c);
System.out.println(c1);
}
}

Test 3:
class Engine
{
private int speed;

public Engine(int speed) {


super();
this.speed = speed;
}

public int getSpeed() {


return speed;
}

public void setSpeed(int speed) {


this.speed = speed;
}

@Override
public String toString() {
return "Engine [speed=" + speed + "]";
}

}
class Car implements Cloneable
{
private Engine ref;
private String name;
public Car(String name) {
super();
this.name = name;
this.ref=new Engine(100);
}
public Engine getRef() {
return ref;
}
public void setRef(Engine ref) {
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone()
{
Car ob=null;
try {
ob=(Car)super.clone();
}
catch (CloneNotSupportedException e)
{

e.printStackTrace();
}
ob.ref=new Engine(ref.getSpeed());//
return ob; //new engine created and deep copy copying and
speed changed
}
@Override
public String toString() {
return "[name=" + name + " ref=" + ref + "]";
}

}
public class Test3
{
public static void main(String[] args)
{
Car c=new Car("Nano");
Car c1=(Car)c.clone();
System.out.println(c);
System.out.println(c1);

c1.getRef().setSpeed(400);

System.out.println("After Modification");

System.out.println(c);
System.out.println(c1);
}
}
Immutablity

// 1. Don't provide "setter" methods — methods that modify fields

class base
{
private int num;
public base(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
}
public class Demo1
{
public static void main(String args[])
{
base b1=new base(100);
System.out.println(b1.getNum());
}
}
// 2.If the instance fields include references to mutable objects,
don't allow those objects to be changed:
// Don't provide methods that modify the mutable objects.

class MyClass
{
private int data;
public MyClass(int data)
{
this.data=data;
}
public void setData(int data)
{
this.data=data;
}
public int getData()
{
return data;
}
}
class base
{
private int num;
private MyClass ref=new MyClass(25);
public base(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public void dispRef()
{
System.out.println(ref.getData());
}
public void changeRef() // do not provide this _do not write
{
ref.setData(50);
}

}
public class Demo2
{
public static void main(String args[])
{
base b1=new base(100);
System.out.println(b1.getNum());
b1.dispRef();
b1.changeRef(); // Violation of Immutability
b1.dispRef();
}
}

//ek immutable class la mutable class change karu shakt nhi


// 3.If the instance fields include references to mutable objects,
don't allow those objects to be changed:
// Don't share references to the mutable objects.

class MyClass
{
private int data;
public MyClass(int data)
{
this.data=data;
}
public void setData(int data)
{
this.data=data;
}
public int getData()
{
return data;
}
}
class base
{
private int num;
private MyClass ref=new MyClass(25);
public base(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public void dispRef()
{
System.out.println(ref.getData());
}
public MyClass getRef() // do not provide this
{
return ref;
}

}
public class Demo3
{
public static void main(String args[])
{
base b1=new base(100);
System.out.println(b1.getNum());
b1.dispRef();
MyClass ref=b1.getRef(); // Violation of Immutability
ref.setData(-3);
b1.dispRef();
}
}

Don’t share ref to mutable object.


// 3.if necessary, create copies to avoid returning the originals in
your methods
class MyClass implements Cloneable
{
private int data;
public MyClass(int data)
{
this.data=data;
}
public void setData(int data)
{
this.data=data;
}
public int getData()
{
return data;
}
public MyClass clone()throws CloneNotSupportedException
{
return ((MyClass)super.clone()); //syntax of creating clone
}
}
class base
{
private int num;
private MyClass ref=new MyClass(25);
public base(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
public void dispRef()
{
System.out.println(ref.getData());
}
public MyClass getRef()throws CloneNotSupportedException
{
return ref.clone();
}
}
public class Demo4
{
public static void main(String args[])throws
CloneNotSupportedException
{
base b1=new base(100);
System.out.println(b1.getNum());
b1.dispRef();
MyClass ref=b1.getRef(); // No problem,as getRef returns
copy of mutable object
ref.setData(-3);
b1.dispRef();
}}
//if you want to provide ref we need to clone the class create copy and
give return to copy
//5. A subclass cannot actually modify the values of private properties
in its parent, but it could behave as though it has

class base
{
private int num;
public base(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
}
class sub extends base
{
private int num;
public sub(int num)
{
super(0);
this.num=num;
}
public void setNum(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
}

public class Demo5


{
static void perform(base ref)
{
System.out.println(ref.getNum());
}
static base getBase(int data)
{
/*base ob1=new base(data);
return ob1;*/

sub ob2=new sub(data);


ob2.setNum(200);
return ob2;

}
public static void main(String args[])
{
base ref1=getBase(100);
// invoke perform twice for "b1"
perform(ref1);
perform(ref1);
}
}
/*
to avoid above problem,
Ensure that the class can't be extended. This prevents careless or
malicious subclasses from compromising the immutable behavior of the
class by behaving as if the object's state has changed.
*/

//subclass base class chi private member function change kru


shakt nhi pn te aplyla as dkhvt ki value change keliye as
dkhvt.

1) Don't provide "setter" methods — methods that modify fields

2) If the instance fields include references to mutable objects, don't


allow those objects to be changed:
i.e. Don't provide methods that modify the mutable objects.

3) If the instance fields include references to mutable objects, don't


allow those objects to be changed:
Don't share references to the mutable objects.

4) if necessary, create copies to avoid returning the originals in your


methods

5) a class should be final

The standard argument for making immutable classes final is that if you
don't do this, then subclasses can add mutability, thereby violating
the contract of the superclass. Clients of the class will assume
immutability, but will be surprised when something mutates out from
under them.

Why immutable classes need to be final?

By declaring immutable classes final, we impose a guarantee that malicious subclasses capable of
changing the state of the object and violating assumptions that clients often make regarding
immutability, are not a concern.

Reflaction Api(application programming interface)

The reflection API represents, or reflects, the classes, interfaces,


and objects in the current Java Virtual Machine. You'll want to use the
reflection API if you are writing development tools such as debuggers,
class browsers, and GUI builders. With the reflection API you can:
1) Determine the class of an object.
2) Get information about a class's modifiers, fields, methods,
constructors, and superclasses.
3) Find out what constants and method declarations belong to an
interface.
4) Create an instance of a class whose name is not known until runtime.
5) Get and set the value of an object's field, even if the field name
is unknown to your program until runtime.
6) Invoke a method on an object, even if the method is not known until
runtime.
7) Create a new array, whose size and component type are not known
until runtime, and then modify the array's components

Reflection can be used to get information about classes,interfaces,their constructors, and methods during
runtime i.e. on the fly.
Through reflection, we can invoke methods at runtime irrespective of the access specifier used with them.

Imp:
reflection does not show parent class methods if parent class is in
different package.

Demo 1:
import java.lang.reflect.Constructor; //java.lang open to all there
is reflect is class need to mention and constructor is method
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionDemo1


{
public static void main(String args[])
{
Class c=null;
try {
c=Class.forName(args[0]); //returning object of
string class
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Method methods[]=c.getDeclaredMethods();//methods of class
class
for(int i=0;i<methods.length;i++)
{
System.out.println(methods[i]);
}
System.out.println();
System.out.println("Let's display constructors");
Constructor
constructors[]=c.getDeclaredConstructors();//constructor of class class
for(int i=0;i<constructors.length;i++)
{
System.out.println(constructors[i]);
}
System.out.println();
System.out.println("Let's display fields");
Field fields[]=c.getDeclaredFields();//Field of class class

for(int i=0;i<fields.length;i++)
{
System.out.println(fields[i]);
}
}
}

Reflection api

We create class and also there classes add in class Class and run on runtime
It is a technique where you get to know info about class that during runtime
Demo 5:3 and 4 are same only comments removed:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Sample
{
private int num1=200;
public int num2=400;
public Sample()
{
System.setSecurityManager(new SecurityManager());
}
private void disp1()
{
System.out.println("in disp1");
}
public void disp2()
{
System.out.println("in disp2");
}
public int getNum1()
{
return num1;
}}
public class ReflectionDemo5
{
public static void main(String args[])
{
try
{
Class c=Class.forName("Sample");//new sample
class loaded in instance of class Class

Method m=c.getDeclaredMethod("disp1",null);//find disp1 whose null

Sample s=new Sample();

m.setAccessible(true); //provide access to the


access private disp

m.invoke(s,null);//we call the disp1 by this

System.out.println("Before modifying\t"+s.getNum1());

Field value = c.getDeclaredField("num1");//find num1


value.setAccessible(true); //provide access to
the access private

value.set(s,120);//set new value to private num1

System.out.println("After modifying\t"+s.getNum1());

}
catch(Exception ee)
{
System.out.println(ee);
}}}
Demo 2:
import java.util.*;
class one
{
void disp1()
{
System.out.println("in disp1");
}
}
class two
{
void disp2()
{
System.out.println("in disp2");
}
}
class three
{
void disp3()
{
System.out.println("in disp3");
}
}

public class ReflectionDemo2


{
static Object createObject(String className)
{
Object object = null; //object created
try {
Class classDefinition = Class.forName(className);//instance
created in class class and className is loaded and information of
classname is stored in instance of class class
object = classDefinition.newInstance();
}
catch (InstantiationException e) // if there is no default constr
{
System.out.println(e);
}
catch (IllegalAccessException e) // if constr is not accessible
{
System.out.println(e);
}
catch (ClassNotFoundException e)//if class is not present
{
System.out.println(e);
}
return object;
}

public static void main(String args[])


{
try
{
System.out.println("Enter class name which you want to
instantiate");
Scanner sc=new Scanner(System.in);
String str=sc.next();
Object ob=createObject(str);
if(ob instanceof one)
{
((one)(ob)).disp1();
}
else if(ob instanceof two)
{
((two)(ob)).disp2();
}
else if(ob instanceof three)
{
((three)(ob)).disp3();
}
}
catch(Exception ee)
{
System.out.println(ee);
}

}
}
Day 10:
Invoking default and parameterized constructor:
// how to instantiate a class by invoking default constructor or
parameterized constructor with the help of Reflection API

package reflectionapi;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;//don’t know about
this

import java.lang.reflect.*;
class MyClass
{
private String message;
public MyClass() {
super();
}

public String getMessage() {


return message;
}

public void setMessage(String message) {


this.message = message;
}

public MyClass(String message)


{
super();
this.message = message;
}

@Override
public String toString() {
return "MyClass [message=" + message + "]";
}

}
public class Demo {

public static void main(String[] args) {


// TODO Auto-generated method stub
Class c=null;
try {
c=Class.forName("MyClass"); //created a instance of
class load myclass in it and give reference to c
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("instantiate MyClass using default constructor");

Object first=null;
try {
first=c.newInstance(); //load another instance of
myclass and store. //this time class not loaded bcoz already created
reference provide to
}
catch (InstantiationException | IllegalAccessException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
MyClass ref=null;
if(first instanceof MyClass)
{
ref=(MyClass)first;//load myclass by downcating
}
ref.setMessage("hello world");
System.out.println(ref.getMessage());
System.out.println("instantiate MyClass using parameterized
constructor");
Constructor ctor=null; //constructor class and instance is
ctor
try {
ctor=c.getDeclaredConstructor(String.class);
}//it will check constructor which will take string as a
argument
catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object second=null;
try {
second=ctor.newInstance("welcome");//constructor
created and add welcome
} catch (InstantiationException | IllegalAccessException
| InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(second);

Bridge method:
import java.lang.reflect.*;
class base
{
Object disp()
{
System.out.println("in base disp");
return null;
}
}
class sub extends base
{
String disp()//compile don’t knows both object disp() is same so
it will create object disp()and from object disp call string disp()
automatically(implicitly)
{
System.out.println("in sub disp");
return null;
}
}
public class BridgeDemo
{
public static void main(String args[])
{
base ref=new sub();
ref.disp();
try
{
Class c=Class.forName("sub");
Method arr[]=c.getDeclaredMethods();
System.out.println(arr.length);
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
System.out.println(arr[i].isBridge());//is bridge is
used to ceheck the method is bridge or not byf=default is false first
time is false then it become true
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}

Multi-Threading
Multi-tasking

performing more than one task simultaneously.

a) process-based multi-tasking
b) thread-based multi-tasking

process - is a program in execution.

thread - is one of the part of program in execution.

process-based multitasking:- more than one processes are running


simultaneously. e.g. word and excel applications are running
simultaneously.

thread-based multitasking :- more than one threads are running


simultaneously. e.g. within a word application, you can start
formatting as well as printing.

whether process-based or thread-based, a cpu can handle only one task


at a time, unless it is multiprocessor machine . It is just an
impression given to the user. what actually cpu does is context
switching , i.e. jump from one task to another and vice-versa.

//only one work at a time but everyone think that it can do more than
one work at a time

process-based vs thread-based

a) threads can share the memory, processes can not


b) context switching between threads is relatively cheaper as compare
to that between processes.
c) cost of communication bet'n threads is also low.

( cheaper or cost is low actually means less no. of system resources


are used.)

Java supports thread-based multitasking.

Application of multi-threading in java :- due to multithreading


feature, java has become effective on server side. e.g Servlet , JSP
etc.

Thread-Schedular
a) pre-emptive //do work of first and after complete it then second
b) time-slice. //provide time to each process

JVM can have any schedular , i.e. either pre-emptive or time-slice.


It is because JVM is different for different platforms.
Java has given certain mechanisms ( functions ) whereby u can make sure
, ur multi-threading application can run more or less same on any os.

Following are the imp. steps required for multithreading application.


1) create thread/s
2) define thread execution body
3) register thread with the thread schedular
4) thread schedular will execute the thread/s

Java's multi-threading support lies in

a) java.lang.Thread
b) java.lang.Runnable (interface)
c) java.lang.Object

Thread class:- this is the most imp. class required in order to create
multi-threading application.
Following are its methods.

a) start
is used to register thread with jvm schedular

b) run
is used by the programmer to define thread execution body, but
will be called by jvm schedular whenever it executes a particular
thread.
when the run method is over, thread is dead.

c) sleep (static)
is used to make thread sleep for some time

d) setName
to set the name of thread

e) getName
to get the name of thread

f) currentThread
returns the currently running thread

g) setPriority
to set the priority
in java priorities are numbers from 1 to 10
1 - minimum priority
5 - normal priority
10 - maximum priority

by default every thread created has normal priority.


( imp:- priorities are not guaranteed across different platforms. )

h) getPriority
to get the priority
i) join
join() method is used for waiting the thread in execution until
the thread on which join is called is not completed.

Runnable interface :- interface which contains abstract method

void run();

There are two ways to create multi-threading application.

1) extends Thread
2) implements Runnable

e.g.
extends Thread

public class Th1 extends Thread //it is important to extend thread


{
public void run() //2)define thread execution body
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[])
{
Th1 t1=new Th1(); //1)create thread
t1.start(); //3)register thread with thread shedualar
}
}

by def. every java application has main thread created by jvm. This
thread is used to execute main() function.
In the above code, there are 2 threads
main thread
user defined thread i.e. t1
Hence there are 2 call stacks in the above code. one for main() and
other for t1 ( run() method ).

when main function is over, main thread dies, but user defined thread/s
can continue. They will be taken care by JVM.
i.e. in the above code, after "t1.start()" when main() function is
over, main thread dies , but t1's execution will be managed by JVM.

public class Th2 extends Thread


{
public void run()
{
System.out.println(Thread.currentThread());//());//information in
thread class_name of the thread op[main,5,main][name ,priority, group]
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[]) //by default one thread
created of main and compiler call it

{
System.out.println(Thread.currentThread());
Th2 t1=new Th2();//t1 inform shedular to call main
t1.setName("first");
t1.start();
}
}

can we call run() directly ?

public class Th3 extends Thread


{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[])
{
Th3 t1=new Th3();
t1.setName("first");
t1.run(); //if we call directly it will run direct no tread
execution
}
}

we can call run() directly. But in that case it won't be thread


execution , it is a normal method call. That is different call stacks
won't be created.

more than one user defined-threads

public class Th4 extends Thread


{
public void run()
{
System.out.println(Thread.currentThread());//information in
thread class_name of the thread op[main,5,main][name ,priority, group]

//for user defined thread


for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[])
{
System.out.println(Thread.currentThread()); //for main thread
Th4 t1=new Th4();
Th4 t2=new Th4();
t1.setName("first");//two threads created
t2.setName("second");//two threads created
t1.start();
t2.start();
}
}

public class Th4_a extends Thread


{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Hello "+Thread.currentThread().getName()+"\t"+i);
try
{
Thread.sleep(100);//sleep used all thread should
execute simultaneously
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}

public static void main(String args[])


{
Th4 t1=new Th4();
Th4 t2=new Th4();
t1.setName("first");
t2.setName("second");
t1.start();
t2.start();
}
}

public class Th5 implements Runnable //when we extends there is all


method inherit,but using implement run method so we implement it
{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[])
{
Th5 ob=new Th5();
Thread t1=new Thread(ob);//
Thread t2=new Thread(ob);
t1.start();
t2.start();
}
}
a) define a class which implements Runnable
b) define run()
c) instantiate the class which impl. Runnable
d) instantiate Thread class by passing above instance (child of
Runnable)
e) register Thread class instance/s

class thread{
private runnable target;
public thread(Runnable target)//in implements we need to write ob bcoz
in upper class no def constructor only parameterized constructor
{
this.target=target;
}

public void run()


{
if(target!=null)
{
target.run();
}
}

thread implements runnable


Revise "extends Thread" and "implements Runnable"

how Thread class is related to Runnable interface?

ans- Thread class implements Runnable


Difference between extends Thread and implements Runnable

what is the use of implements Runnable ?


if your class is already extending some class, you can't say
extends Thread , because multiple inheritance is not allowed in java.
In that case you have to go for implements Runnable.

above program also proves that threads can share the memory.

when threads share the memory there is a risk of "race condition".

e.g.

There are 2 threads.


one thread is reading from a file
other thread is writing to a file.
Race condition means
while one thread is reading from a file, other thread might write
in a file or vice-versa.
Race condition always leads to Data Corruption.

How do we avoid Race condition ?


we will have to make sure that while one thread is working on a
data, other thread should not run. Only after first thread completes
its job, other thread should start its execution. In java we can
achieve this by using "synchronization".

"synchronization" is a solution to the race condition.

public class Th6 implements Runnable


{
synchronized public void run()//if you create method
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
public static void main(String args[])
{
Th6 ob=new Th6();
Thread t1=new Thread(ob); //when synchronization works
only when two objects is same
Thread t2=new Thread(ob);
t1.start();
t2.start();
}
}

public class Th7 implements Runnable


{
public void run()
{
synchronized(this) //if you create block
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
}
public static void main(String args[])
{
Th7 ob=new Th7();
Thread t1=new Thread(ob);
Thread t2=new Thread(ob);
t1.start();
t2.start();
}
}

synchronized keyword
method :- all the statements are protected.

block :- only those statements are protected which are given


inside synchronized block.

what exactly happens when we use synchronized keyword ?

There is a concept of object lock.

in java every object has a lock. This lock can be accessed by only one
thread at a time. The lock will be released as soon as the thread
completes its job and thus another thread can acquire the lock.
This lock comes into picture only when object has got non-static
synchronized method/s or block.
whichever thread executes the synchronized method first, it acquires
the lock. Other thread/s have to be in "seeking lock state".

Acquiring and Releasing lock happens automatically.

once a thread acquires a lock on an object , it can have control on all


the non-static synchronized methods of that object.

public class Th8 implements Runnable


{
public void run()
{
synchronized(this) //this calling constructor of same
class
//this is reference of ob here
//10 critical important statements need to call which will need to run
fast
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
//Non critical statements add here
}
public static void main(String args[])
{
Th8 ob=new Th8();
Th8 ob1=new Th8();
Thread t1=new Thread(ob);
Thread t2=new Thread(ob1);
t1.start();
t2.start();
}
}

Even though synchronized method or block is used to avoid "Race


Condition", there can be danger of "DeadLock" inside it.
e.g. if one thread is working inside synchronized block or method and
if it gets stuck up ! imagine what will happen ?
neither this thread can complete and release the lock, nor other thread
can acquire the lock.

Solution to this is to have a Communication bet'n threads.


i.e. if the thread realizes it can not continue, it should come out of
synchronized method or block and release the lock. Now other thread
will acquire the lock , execute the code and allow the first thread to
resume.

Following are the methods used for communication bet'n threads.methods


are defined java.lang.object

a) wait
it will make thread , release the lock and go to wait pool.//wait
kr bolto first la ani baher jaun ye

b) notify
it will make the thread to move from wait pool to seeking lock
state. //line mdhe hubar baherun yeun

c) notifyAll
it will make all the threads to move from wait pool to seeking
lock state. //sagle baherun yaa ni line mdhe hubara

These methods are defined in "java.lang.Object" class and are final so


u can not override them.

These methods must be called from synchronized method or block.

difference bet'n wait and sleep

wait releases the lock on an object , sleep does not.


//a sleep if they not solve code and if they will not solve code it
will go outside is wait
Thread-safety

Thread-safe classes are those classes, which contain synchronized non-


static methods.

Transection code:
-using interface reference all the methods of object class can be
invoked it is because interface will be implemented by some or the
other class and every class is derived from object class.

what is class lock ?

every class has a lock. It is actually a lock on an instance of class


Class. This is because , whenever any class is loaded in java, it is
represented by instance of class Class.

The class lock comes into picture in case of synchronized static


methods.
Thread which gives a call to synchronized static method can acquire a
class lock. Only after thread complete that static method, lock is
released.
when u want to ensure that non-static method/s should be called by only
one thread at a time, u apply lock on an object which is shared by more
than one threads. The technique to apply "object lock" is to have
synchronized non-static method/s or block/s.

What if u want to ensure that static method/s should be called by only


one thread at a time?
here object lock will not help at all because static methods are
not at all associated with the object. Hence u need to apply "class
lock" i.e. lock on an instance of class "Class". The technique to apply
"class lock" is to have synchronized static method/s or block/s.
ClassLock1:
public class ClassLock1 implements Runnable
{
synchronized static void disp1()
{
for(int i=0;i<5;i++)
{
System.out.println("static "+i);

}
}
public void run() //we cant apply static to run bcoz run is
overriding
{
disp1();
}
public static void main(String args[])
{
ClassLock1 c=new ClassLock1();
ClassLock1 c1=new ClassLock1();
Thread t1=new Thread(c);
Thread t2=new Thread(c1);
t1.start();
t2.start();
}}
ClassLock2:

public class ClassLock2 implements Runnable


{
static Class cs;
static void disp1()
{
synchronized(cs)//synchronized block is used
//cs is reference of that class from which we want to aquire the lock
{
for(int i=0;i<5;i++)
{
System.out.println("static "+i);
try
{
Thread.sleep(200);
}
catch(InterruptedException ie)
{
}
}
}
}
public void run()
{
disp1();
}
public static void main(String args[])throws Exception
{
cs=Class.forName("ClassLock2");
ClassLock2 c=new ClassLock2();
ClassLock2 c1=new ClassLock2();
Thread t1=new Thread(c);
Thread t2=new Thread(c1);
t1.start();
t2.start();
}
}

ClassLock 2a:
public class ClassLock2_a implements Runnable
{
static void disp1()
{
synchronized(ClassLock2_a.class)//reference of class class
instance which aquire the lock
{
for(int i=0;i<5;i++)
{
System.out.println("static "+i);
}
}
}
public void run()
{
disp1();
}
public static void main(String args[])
{
ClassLock2_a c=new ClassLock2_a();
ClassLock2_a c1=new ClassLock2_a();
Thread t1=new Thread(c);
Thread t2=new Thread(c1);
t1.start();
t2.start();
}
}

ClassLock3:

public class ClassLock3 implements Runnable


{
static Class cs;
static void disp1()
{
synchronized(cs)
{
for(int i=0;i<5;i++)
{
if(i==3) //wait after 3 and second run upto 2 and again 3 ND 4 RUN OF
BOTH
{
try
{
cs.wait();
}
catch(InterruptedException ie)
{
}
}
System.out.println("static "+i);
cs.notifyAll();
}
}
}

public void run()


{
disp1();
}
public static void main(String args[])throws Exception
{
cs=Class.forName("ClassLock3");
ClassLock3 c=new ClassLock3();
ClassLock3 c1=new ClassLock3();
Thread t1=new Thread(c);
Thread t2=new Thread(c1);
t1.start();
t2.start();
}
}

//first 012 second 012 first 34 second 34

In case of Class lock, When u say cs.wait() cs.nofify() or cs.notifyAll() what does it mean ?
It means that, wait(), notify() and notifyAll() are in Object class and they are final , so they cannot be
overridden.
Class class is a child of Object class.
When we say cs.wait(),cs.nofify() or cs.notifyAll() it means that these methods are inherited in Class
class which we are invoking.
//object lock-wait notify notifyall in object class the lock on any object derived from object class
Classlock-wait notify notifyall in object class derived in instance of class class
public class Th9 implements Runnable
{
public void run()
{
synchronized(this)
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
}
public static void main(String args[])
{
Th9 ob=new Th9();
Thread t1=new Thread(ob);
Thread t2=new Thread(ob);
t1.start();
t2.start();

System.out.println("Both the threads are over");//main


thread so run first
}
}

in the above code "Both the threads are over" will not be displayed in
the end because it is a statement of main. It is because as we know ,
main thread completes first and user defined thread are continue, they
are taken care by JVM.
if we want that "Both the threads are over" should be displayed at the
end, we have to make sure that main thread will complete only after the
completion of "t1" and "t2".

Solution is "join()" method.

join() method

join method makes caller thread (main thread) to wait for called thread
(t1 and t2) to complete.

how join works ?


public class Th9_a implements Runnable
{
public void run()
{
synchronized(this)
{
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
}
}
public static void main(String args[])
{
Th9 ob=new Th9();
Th9 ob1=new Th9();
Thread t1=new Thread(ob);
Thread t2=new Thread(ob1);
t1.start();
t2.start();
try
{
t1.join(); //so in that first this thread works and
then both threads are over work
t2.join();
}
catch(InterruptedException e)
{
}
System.out.println("Both the threads are over");
}
}

in the above code, when main() function calls "t1.join()" for example,
it says "join me at your end".
Since main() is calling "t1.join()" and "t2.join()" , it is added to
the end of both t1 and t2. That's why now the statement "Both the
threads are over" is getting executed at the end.

whenever thread is in a blocked(one thread sleep inside lab) state


ie.due to sleep, join or wait methods, it can get interrupted by
other threads. Whenever blocked thread gets interrupted, it throws
"InterruptedException". //interruptedException occurs when sleep
notify notifyall used
But this can not be predictable, hence java enforces you to either
handle or declare InterruptedException whenever you invoke the above
methods.

Thread states
Born
runnable
running
blocked
dead

User threads and Daemon threads

User threads
user defined threads
main thread

Daemon thread
e.g. garbage collection thread

Daemon threads are the threads which are at the mercy of user thread/s.
Their only purpose is to serve user defined thread/s. When there is no
user thread alive, Daemon thread will die.

Example of Garbage Collection Thread

public class Sample


{

public static void main(String[] args) {


Sample s1=new Sample();
s1=null;
System.gc(); //garbage collection
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}

//Runtime.getRuntime().gc();
System.out.println("Main function executed
By\t"+Thread.currentThread().getName());

protected void finalize()


{
System.out.println("inside finalized method");
System.out.println("finalize method invoked
by\t"+Thread.currentThread()); //from main garbage collector call so
finalized method called from main
System.out.println(Thread.currentThread().isDaemon());
Daemon tell is this garbage collector call or not

}
output:
inside finalized method
finalize method invoked by
Thread[Finalizer,8,system](name,priority,group)
true
Main function executed By main

Day 11:
Difference betn implicit and explicit lock
1) acquiring and releasing lock needs to be done explicitly.
2) extended feature like fairness, which can be used to provide lock to
longest waiting thread.
3) ability to trying for lock with or without timeout. Thread doesn’t
need to block infinitely, which was the case with implicit
synchronization.

Which thread wait longer that thread is execute first

Thread Pools in Java

Background
Server Programs such as database and web servers repeatedly execute requests from multiple clients
and these are oriented around processing a large number of short tasks. An approach for building a
server application would be to create a new thread each time a request arrives and service this new
request in the newly created thread. While this approach seems simple to implement, it has significant
disadvantages. A server that creates a new thread for every request would spend more time and
consume more system resources in creating and destroying threads than processing actual requests.
Since active threads consume system resources, a JVM creating too many threads at the same time
can cause the system to run out of memory. This needs to limit the number of threads being created.

What is ThreadPool in Java?


A thread pool contains previously created threads to execute a given task. These threads are
initially idle. Once any task comes a randomly selected thread from thread pool will be made
active and asked to perform the task. Once the task is over the thread is not destroyed but
simply sent back to the pool for reuse. Since the thread is already existing when the request arrives,
the delay introduced by thread creation is eliminated, making the application more responsive.
Without using thread pool

Using threadpool
When my task is completed manager provide second task

Under light to moderate load, thread per task approach is an improvement over sequential execution.
As long as the request arrival rate does not exceed the server’s capacity to handle the requests, this
approach offers better responsiveness.
Disadvantage of unbounded thread creation
For production use, however, the thread-per-task approach has some practical drawbacks, especially
when a large number of threads may be created.
Thread lifecycle overhead:- Thread creation and teardown are not free. The actual overhead varies
across platforms, but thread creation takes time, introducing lethargy into request processing, and
requires some processing activity by JVM and OS. If requests are frequent and lightweight, as in most
server applications, creating a new thread for each request can consume significant computing
resources.
Resource consumption:- Active threads consume system resources, especially memory. When there
are more runnable threads than available processors, threads sit idle. Having many idle threads can tie
up a lot of memory and having many threads competing for the CPUs can impose other performance
costs as well.

Executors
If your program creates a large number of short-lived threads, then it should instead use a thread pool.
A thread pool contains a number of idle threads that are ready to run. You give a Runnable to the pool
, and one of the threads calls the run method. When the run method exits, the thread doesn’t die but
stays around to serve the next request.
Executors simplify concurrent programming by managing Thread objects for you. Executors allow
you to manage the execution of asynchronous tasks without having to explicitly manage the lifecycle
of threads.
We can use an Executor instead of explicitly creating Thread objects . An ExecutorService ( an
Executor with a service lifecycle – e.g. shutdown ) knows how to build the appropriate context to
execute Runnable objects.
An Executor implementation is likely to create threads for processing tasks. But the JVM can’t exit
until all the threads have terminated, so failing to shutdown an Executor could prevent the JVM from
exiting. Since Executors provide a service to the applications, they should be able to shutdown as
well.
The call to shutdown() prevents new tasks from being submitted to that Executor. The current thread
( e.g. main thread ) will continue to run all tasks submitted before shutdown() was called. The
program will exit as soon as all the tasks in the Executor finish.
Executors Factory Methods
a) newCachedThreadPool :- a cached thread pool has more flexibility to reap idle threads
when the current size of the pool exceeds the demand for processing, and to add new
threads when demand increases, but places no bound on the size of the pool.

b) newFixedThreadPool :- a fixed-size thread pool creates threads as tasks are submitted, up


to the maximum pool size, and then attempts to keep the pool size constant (adding new
threads if a thread dies due to an unexpected Exception).

Executor demo1;

import java.util.concurrent.*;
class myapp implements Runnable
{
public void run()
{
perform();
}
void perform()
{
for(int i=0;i<5;i++) //5 tasks only three threads work on it
{
System.out.println("Hello\t"+I+"\t"+Thread.currentThread());
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
System.out.println(ie);
}
}
}
}
public class ExecutorDemo1
{
public static void main(String args[])
{
ExecutorService

exec=Executors.newCachedThreadPool(); //prior to java 8 it is static


method so call by classname.method name. threadpool is created and they
have thread
for(int i=0;i<3;i++)
{
exec.execute(new myapp());by this three new OBJEcTS—
and provide to runnable again and again
}
System.out.println("After submitting tasks");

System.out.println("After for loop");


exec.execute(new myapp());

/*
shutdown() prevents new tasks from being submitted to that Executor.
The current thread ( e.g. main thread ) will continue to run all tasks
submitted before shutdown() was called.
*/
exec.shutdown(); // if u don't invoke, then jvm will not
shutdown
System.out.println("done");
// exec.execute(new myapp()); don't give any task after
shutdown here rejectedExecutionException perform

}
}
Executor demo2:
/*
a FixedThreadPool uses a limited set of threads to execute the
submitted tasks.
*/
import java.util.concurrent.*;
class myapp implements Runnable
{
public void run()
{
perform();
}
void perform()
{
for(int i=0;i<5;i++)
{

System.out.println("Hello\t"+i+"\t"+Thread.currentThread());
}
}
}
public class ExecutorDemo2
{
public static void main(String args[])
{
ExecutorService exec=Executors.newFixedThreadPool(2);//2
THREAD fixed

for(int i=0;i<3;i++)
{
exec.execute(new myapp()); //THREE TASK CREATED
}
System.out.println("After submitting tasks");

exec.shutdown(); //after shutdown no any work


}
}
Executor demo3:
/*
with class lock
*/
import java.util.concurrent.*;
class myapp implements Runnable
{
synchronized static void disp()
{
for(int i=0;i<5;i++) //5 tasks work
{
System.out.println("Hello\t"+i

+"\t"+Thread.currentThread());
}
}

public void run()


{
disp();
}
}
public class ExecutorDemo3
{
public static void main(String args[])
{
//myapp m=new myapp();
ExecutorService
exec=Executors.newFixedThreadPool(2);//create threadpool with 2 threads
for(int i=0;i<3;i++)
{
// exec.execute(m);
exec.execute(new myapp()); //3 objects created
}
exec.shutdown();
}
}
Op

lo 0 Thread[pool-1-thread-2,5,main] //3 objects w threads work and 5 tasks


Hello 1 Thread[pool-1-thread-2,5,main]
Hello 2 Thread[pool-1-thread-2,5,main]
Hello 3 Thread[pool-1-thread-2,5,main]
Hello 4 Thread[pool-1-thread-2,5,main]
Hello 0 Thread[pool-1-thread-1,5,main]
Hello 1 Thread[pool-1-thread-1,5,main]
Hello 2 Thread[pool-1-thread-1,5,main]
Hello 3 Thread[pool-1-thread-1,5,main]
Hello 4 Thread[pool-1-thread-1,5,main]
Hello 0 Thread[pool-1-thread-2,5,main]
Hello 1 Thread[pool-1-thread-2,5,main]
Hello 2 Thread[pool-1-thread-2,5,main]
Hello 3 Thread[pool-1-thread-2,5,main]
Hello 4 Thread[pool-1-thread-2,5,main]

Executor means implicit and reentrant means explicit lock


Reentrant lock:
1) acquiring and releasing lock needs to be done explicitly.
2) extended feature like fairness, which can be used to provide lock to
longest waiting thread.
3) ability to trying for lock with or without timeout. Thread doesn’t
need to block infinitely, which was the case with implicit
synchronization.

When one thread is in lock state another thread do there work


Explicit lock use instead of synchronization

What is ReentrantLock in Java

ReentrantLock is mutual exclusive lock, similar to implicit locking provided by synchronized


keyword in Java, with extended feature like fairness, which can be used to provide lock to longest
waiting thread. Lock is acquired by lock() method and held by Thread until a call
to unlock() method. Fairness parameter is provided while creating instance of ReentrantLock in
constructor. ReentrantLock provides same visibility and ordering guarantee, provided by implicitly
locking, which means, unlock() happens before another thread get lock().

Difference between ReentrantLock and synchronized keyword in Java

Though ReentrantLock provides same visibility and orderings guaranteed as implicit lock, acquired
by synchronized keyword in Java, it provides more functionality and differ in certain aspect. main
difference between synchronized and ReentrantLock is ability to trying for lock with or without
timeout. Thread doesn’t need to block infinitely, which was the case with synchronized. Let’s see few
more differences between synchronized and Lock in Java.

In explicit lock thread check again and again is this first thread work is completed

1) Another significant difference between ReentrantLock and synchronized keyword


is fairness. synchronized keyword doesn't support fairness. Any thread can acquire lock once
released, no preference can be specified, on the other hand you can make ReentrantLock fair by
specifying fairness property, while creating instance of ReentrantLock. Fairness property provides
lock to longest waiting thread, in case of conflict.
Whose waiting time is high is call first
2) Second difference between synchronized and Reentrant lock is tryLock() method. ReentrantLock
provides convenient tryLock() method, which acquires lock only if its available or not held by any
other thread. This reduce blocking of thread waiting for lock in Java application.

Trylock checks again and again is this work completed of first

Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.

3) ReentrantLock also provides convenient method to get List of all threads waiting for lock.

In short, Lock interface adds lot of power and flexibility and allows some control over lock
acquisition process, which can be influenced to write highly scalable systems in Java.

Await
Signal
Signal all (condition interface available)

Disadvantages of ReentrantLock in Java

Major drawback of using ReentrantLock in Java is , wrapping method body inside try-finally
block, which makes code unreadable and error-prone. Another disadvantage is that, now programmer
is responsible for acquiring and releasing lock, which is a power but also opens gate for new subtle
bugs, when programmer forget to release the lock in finally block.

Things to remember:

 Release all locks in finally block.


 Beware of thread starvation! The fair setting in ReentrantLocks may be useful if you have
many readers and occasional writers that you don’t want waiting forever. It’s possible a writer
could wait a very long time (maybe forever) if there are constantly read locks held by other
threads.
 Use synchronized whereever possible. You will avoid bugs and keep your code cleaner.
 Use tryLock() if you don’t want a thread waiting indefinitely to acquire a lock.

Demo1:
import java.util.concurrent.locks.*;
public class Demo1 implements Runnable
{
ReentrantLock mylock=new ReentrantLock();//reertrantlock is class
public void run()
{
mylock.lock(); //lock
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
System.out.println(ie);
}
}
mylock.unlock(); //unlock
}
public static void main(String args[])
{
Demo1 ob=new Demo1();
Thread t1=new Thread(ob,"first");
Thread t2=new Thread(ob,"second");
t1.start();
t2.start();
}
}
Demo1A:
// combination of Thread pool and Explicit locking
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
public class Demo1_a implements Runnable
{
ReentrantLock mylock=new ReentrantLock();//we use import
java.util.concurrent.locks
public void run()
{
mylock.lock();
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
System.out.println(ie);
}
}
mylock.unlock();
}
public static void main(String args[])
{
Demo1 ob=new Demo1();
ExecutorService exec=Executors.newFixedThreadPool(2);
exec.execute(ob);
exec.execute(ob);
exec.shutdown();
}
}
Demo 2:
// class lock with ReentrantLock
import java.util.concurrent.locks.*;
public class Demo2 implements Runnable
{
static ReentrantLock mylock=new ReentrantLock(); //we lock the
instance of class Class
static void disp()
{
mylock.lock();
for(int i=0;i<5;i++)
{
System.out.println("Hello"+i);
}
mylock.unlock();
}
public void run()
{
disp();
}
public static void main(String args[])
{
Demo2 ob1=new Demo2();
Demo2 ob2=new Demo2();
Thread t1=new Thread(ob1);
Thread t2=new Thread(ob2);
t1.start();
t2.start();
}
}

Demo 3:
import java.util.concurrent.locks.*;
public class TryLockDemo1 implements Runnable
{
ReentrantLock mylock=new ReentrantLock();
public void run()
{
while(true)
{
if(mylock.tryLock()) //second obj check again and again
{
for(int i=0;i<8;i++)
{

System.out.println("Hello"+i+"\t"+Thread.currentThread().getName(
));

}
mylock.unlock();
break;
}
else
{
System.out.println(Thread.currentThread().getName()+"
doing something else");
}
}

}
public static void main(String args[])
{
TryLockDemo1 ob=new TryLockDemo1();
Thread t1=new Thread(ob,"first");
Thread t2=new Thread(ob,"second");
t1.start();
t2.start();
}
}

Op:
Hello 0 first
second doing something else
second doing something else
Hello 1 first
second doing something else
Hello 2 first
second doing something else
Hello 3 first
second doing something else
Hello 4 first
second doing something else
Hello 5 first
second doing something else
Hello 6 first
second doing something else
Hello 7 first
second doing something else
Hello 0 second
Hello 1 second
Hello 2 second
Hello 3 second
Hello 4 second
Hello 5 second
Hello 6 second
Hello 7 second
Demo 2:
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
public class TryLockDemo2 implements Runnable
{
ReentrantLock mylock=new ReentrantLock();
public void run()
{
while(true)
{
try
{
if(mylock.tryLock(2,TimeUnit.MILLISECONDS))//2 milisecons
is constant timeunit is enum
{
for(int i=0;i<18;i++)
{

System.out.println("Hello"+i+"\t"+Thread.currentThread().getName(
));

}
mylock.unlock();
break;
}
else
{
System.out.println(Thread.currentThread().getName()+"
doing something else");
}
}
catch(InterruptedException ie)
{
System.out.println("in catch\t"+ie);
}
}

}
public static void main(String args[])
{
TryLockDemo2 ob=new TryLockDemo2();
Thread t1=new Thread(ob,"first");
Thread t2=new Thread(ob,"second");
t1.start();
t2.start();
}
}

Day 12:
stream

stream is a communication path bet'n source and destination.

There are two types of streams


a) input stream :- for reading
b) output stream :- for writing

if u want to read, u need to open input stream on the source ( e.g.


file, array, network )

if u want to write ,u need to open output stream on destination ( e.g.


file, array, network )
Java has two categories of streams

byte streams and unicode character streams

byte streams :- for reading and writing bytes , image or sound files
also. It is also used to read and write java Objects.

unicode character streams :- for reading and writing unicode


characters.

File class in Java:


File class in java is used to get information about file such as
whether file exists or not, its length, date of last modification etc.

Entire io(file handling) support is available from "java.io" package.

For inputputstream

For outputstream

import java.io.*;
import java.util.*;
public class FileDemo
{
public static void main(String args[])
{
File f=new File("c:\\temp\\FileDemo.java");
System.out.println("File Name\t"+f.getName());
System.out.println("Path\t"+f.getPath());
System.out.println("Abs Path\t"+f.getAbsolutePath());
System.out.println(f.exists()?"Exists":"Doesn't Exists");
System.out.println(f.canWrite()?"Can Write":"Can Not
Write");
System.out.println(f.canRead()?"Can Read":"Can Not Read");
System.out.println(f.isDirectory()?"It is Directory":"It is
not Directory");
System.out.println(f.isFile()?"Yes File":"No File");
System.out.println(f.isAbsolute()?"is Absolute":"It is Not
Absolute");
System.out.println("File Last Modified\t"+new
Date(f.lastModified()));
System.out.println("File size is\t"+f.length());
}
}

First
package java8;
import java.io.*;
public class First
{
public static void main(String args[])
{
File f=new File("d:\\FileDemo.java\\fh1.txt");
if(!f.exists())
{
System.out.println("file does not exists");
System.exit(0);
}
try(FileInputStream fis=new FileInputStream(f))
{
byte b[]=new byte[((int)f.length())]; //bcoz bydefault
bytecode is long so we typecast
fis.read(b); //for read b
String ss=new String(b);
System.out.println(ss); //we need to convert it in string
to read
}
catch(Exception ee)
{
ee.printStackTrace();
}
}}

Second
package java8;
import java.io.*;
public class Second
{
public static void main(String args[])
{
try(FileOutputStream fos=new
FileOutputStream("d:\\abc1.txt",true))
//by default it is false so te override hot raht prt write vprl ki
mhnje lihlel ahe tyarvr prt ekda liht n phil ghlvt when true used
(append works) and te ky krt ki next line la enter krt jat
{
byte b[]=new byte[100]; //in that we read
System.out.println("Enter data");
int k=System.in.read(b);
fos.write(b,0,k); //by using this we write(array,0psun
start,k input+2 ( /n/r))

}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}
Third:
import java.io.*;
public class Third
{
public static void main(String args[])
{
char arr1[]=null;
try(FileWriter fw=new FileWriter("e:\\abc2.txt"))
{
char arr[]={'a','b','c','d','e'}; //unicode
fw.write(arr);
}
catch(IOException ie)
{
ie.printStackTrace();
}
try(FileReader fr=new FileReader("e:\\abc2.txt"))
{

arr1=new char[(int)new File("e:\\abc2.txt").length()];


fr.read(arr1);
}
catch(Exception ee)
{
ee.printStackTrace();
}

for(int i=0;i<arr1.length;i++)
{
System.out.println(arr1[i]);
}
}
}
Fourth:
import java.io.*;
// Program to write and read primitives in file
/* DataOutputStream lets an application write primitive Java data types
to an output stream in a portable way. An application can then use a
data input stream to read the data back in. */

/* DataInputStream lets an application read primitive Java data types


from an underlying input stream in a machine-independent way. An
application uses a data output stream to write data that can later be
read by a data input stream.
*/

public class Fourth


{
public static void main(String args[])
{
try(FileOutputStream fos=new
FileOutputStream("e:\\ab1.txt"))
//knows where to read
{
try(DataOutputStream dos=new DataOutputStream(fos))
//knows to read primitive but don’t know the where to read
{
dos.writeInt(10);
dos.writeChar('A');
dos.writeFloat(3.9f);
dos.writeBoolean(true);
dos.writeUTF("hello world");//universal text
format
}
}
catch(IOException ie)
{
ie.printStackTrace();
}

try(FileInputStream fis=new FileInputStream("e:\\ab1.txt"))


{
try(DataInputStream dis=new DataInputStream(fis))
{
System.out.println(dis.readInt());
System.out.println(dis.readChar());
System.out.println(dis.readFloat());
System.out.println(dis.readBoolean());
System.out.println(dis.readUTF());
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}

//we use datainput/dataoutput stream for read and write primitive bcoz
inputstram do not knows hot to read write stream

sixth
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

import java.io.*;
//Program to write and read in a file using RandomAccessFile

//class
public class Sixth
{
public static void main(String args[])
{
try(RandomAccessFile rf=new
RandomAccessFile("e:\\temp\\xy.txt","rw"))
{
rf.seek(rf.length()); //start from
System.out.println("Enter data");
byte b[]=new byte[200];
int k=System.in.read(b);
rf.write(b,0,k);
rf.seek(0); //start from 0
byte c[]=new byte[(int)rf.length()];
rf.read(c);
String ss=new String(c);
System.out.println(ss);
rf.seek(rf.length()); //start from after entered
length
System.out.println("Enter data again");
k=System.in.read(b);
rf.write(b,0,k);
System.out.println("Finally reading all data");
rf.seek(0);
c=new byte[(int)rf.length()];
rf.read(c);
ss=new String(c);
System.out.println(ss);
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}
1) File f=new File("d:\\FileDemo.java");
here we just create a File class object just to check wheather
file exists or not, since we r reading from file ,if file doesn't exist
we would like to exit.
if(!f.exists())
{
System.out.println("file does not exists");
System.exit(0);
}

FileInputStream fis=new FileInputStream(f)


here we open a file "FileDemo.java" in read mode.

byte b[]=new byte[((int)f.length())];


file contents can be read inside byte array , that's why we
create byte array equivalent to the length of file.

fis.read(b);
here we read the contents of file inside byte array.

String ss=new String(b);


since byte array can not be readable we convert into String.

System.out.println(ss);
here we display the contents of file.
2)
FileOutputStream fos=new FileOutputStream("d:\\abc1.txt",true)
above statement will create a file if file does not exist.
argument "true" inside FileOutputStream constructor indicates
that if file exists then it will get appended.

byte b[]=new byte[100];


byte array is created so that user input can be stored
inside it.

int k=System.in.read(b);
we accept input from user inside "b" which is byte array.
here "k" will hold number of bytes read.

fos.write(b,0,k);
here we write user input stored inside byte array to file.
write has 3 arguments:
1) byte array to be written
2) it should start with 0
3) how many exact no. of bytes we would like to write inside
file.

object persistence

it means saving the state of an object inside either filesystem or


database so that it can be retrieved back in future.

When we save the state of an object inside filesystem , it is known as


"Serialization".
in java there are two rules for Serialization:

a) a class has to implement either Serializable or Externalizable


interface.

b) class must have all the instance members of type serialized.


(Serialized type means which can be easily converted into sequence of
bytes) . By default all the primitives are of serialized type.
Reference type can be made serialized type by implementing either
Serializable or Externalizable interface.

Serializing object means writing Object inside filesystem as follows:


FileOutputStream fos=new FileOutputStream("filename");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(<object to be written>);

Deserializing object means reading object from filesystem as follows:


FileInputStream fis=new FileInputStream("filename");
ObjectInputStream ois=new ObjectInputStream(fis);
ois.readObject();

5 Different Ways to Create Objects in Java

There are five total ways to create objects in Java, which are explained below with their
examples followed by bytecode of the line which is creating the object.

Using new keyword } → constructor gets called

Using newInstance() method of Class class } → constructor gets called

Using newInstance() method of Constructor class } → constructor gets called

Using clone() method } → no constructor call

Using deserialization [ using Serializable interface ] } → no constructor call

1. Using new keywords


It is the most common and regular way to create an object and a very simple one also. By
using this method we can call whichever constructor we want to call (no-arg constructor as
well as parameterized).

Employee emp1 = new Employee();


0: new #19 // class org/programming/mitra/exerci
ses/Employee
3: dup
4: invokespecial #21 // Method org/programming/mitra/exerc
ises/Employee."":()V
2. Using newInstance() method of Class class
We can also use the newInstance() method of a Class class to create an object. This
newInstance() method calls the no-arg constructor to create the object.

We can create an object by newInstance() in the following way:

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exer


cises.Employee").newInstance();
Or

Employee emp2 = Employee.class.newInstance();


51: invokevirtual #70 // Method java/lang/Class.newInstance:()
Ljava/lang/Object;

4. Using newInstance() method of Constructor class


Similar to the newInstance() method of Class class, There is one newInstance() method in
the java.lang.reflect.Constructor class which we can use to create objects. We can also call
parameterized constructor, and private constructor by using this newInstance() method.

Constructor<Employee> constructor = Employee.class.getConstructor();


Employee emp3 = constructor.newInstance();
111: invokevirtual #80 // Method java/lang/reflect/Constructor.new
Instance:([Ljava/lang/Object;)Ljava/lang/Object;
Both newInstance() methods are known as reflective ways to create objects. In fact
newInstance() method of Class class internally uses newInstance() method of Constructor
class. That's why the later one is preferred and also used by different frameworks like Spring,
Hibernate, Struts etc.

4. Using clone() method:


Whenever we call clone() on any object, the JVM actually creates a new object for us and
copies all content of the previous object into it. Creating an object using the clone method
does not invoke any constructor.

To use clone() method on an object we need to implement Cloneable and define the clone()
method in it.

Employee emp4 = (Employee) emp3.clone();


162: invokevirtual #87 // Method org/programming/mitra/exercises/Em
ployee.clone ()Ljava/lang/Object;

Java cloning is the most debatable topic in Java community and it surely does have its
drawbacks but it is still the most popular and easy way of creating a copy of any object until
that object is full filling mandatory conditions of Java cloning.

5. Using deserialization:
Whenever we serialize and deserialize an object, the JVM creates a separate object for us. In
deserialization, the JVM doesn’t use any constructor to create the object.
To deserialize an object we need to implement a Serializable interface in our class.

ObjectInputStream in = new ObjectInputStream(new FileInputStream("da


ta.obj"));
Employee emp5 = (Employee) in.readObject();
261: invokevirtual #118 // Method java/io/ObjectInputStream.readO
bject:()Ljava/lang/Object;
As we can see in the above bytecode snippets, all 4 methods are called and get converted
to invokevirtual (object creation is directly handled by these methods) except the
first one, which got converted to two calls: one is new and other is invokespecial (call to
constructor).

Example

Let’s consider an Employee class for which we are going to create the objects:

class Employee implements Cloneable, Serializable {


private static final long serialVersionUID = 1L;
private String name;
public Employee() {
System.out.println("Employee Constructor Called...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCod
e());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Employee [name=" + name + "]";
}
@Override
public Object clone() {
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
In the below Java program we are going to create Employee objects in all 5 ways. You can
also find the source code at GitHub.

public class ObjectCreation {


public static void main(String... args) throws Exception {
// By using new keyword
Employee emp1 = new Employee();
emp1.setName("Naresh");
System.out.println(emp1 + ", hashcode : " + emp1.hashCode())
;
// By using Class class's newInstance() method
Employee emp2 = (Employee) Class.forName("org.programming.mi
tra.exercises.Employee")
.newInstance();
// Or we can simply do this
// Employee emp2 = Employee.class.newInstance();
emp2.setName("Rishi");
System.out.println(emp2 + ", hashcode : " + emp2.hashCode())
;
// By using Constructor class's newInstance() method
Constructor<Employee> constructor = Employee.class.getConstr
uctor();
Employee emp3 = constructor.newInstance();
emp3.setName("Yogesh");
System.out.println(emp3 + ", hashcode : " + emp3.hashCode())
;
// By using clone() method
Employee emp4 = (Employee) emp3.clone();
emp4.setName("Atul");
System.out.println(emp4 + ", hashcode : " + emp4.hashCode())
;
// By using Deserialization
// Serialization
ObjectOutputStream out = new ObjectOutputStream(new FileOutp
utStream("data.obj"));
out.writeObject(emp4);
out.close();
//Deserialization
ObjectInputStream in = new ObjectInputStream(new FileInputSt
ream("data.obj"));
Employee emp5 = (Employee) in.readObject();
in.close();
emp5.setName("Akash");
System.out.println(emp5 + ", hashcode : " + emp5.hashCode())
;
}
}
This program will give the following output:

Employee Constructor Called...


Employee [name=Naresh], hashcode : -1968815046
Employee Constructor Called...
Employee [name=Rishi], hashcode : 78970652
Employee Constructor Called...
Employee [name=Yogesh], hashcode : -1641292792
Employee [name=Atul], hashcode : 2051657
Employee [name=Akash], hashcode : 63313419

First:
import java.io.*;
public class First implements Serializable //need to implement
serilizable
{
String name="sachin";
int age=20;
//using serilize we print above instance using object
transient Thread t=new Thread(); //ignore it
public static void main(String args[])
{
First s=new First();
try(FileOutputStream fos=new
FileOutputStream("e:\\ab1.txt"))
{
try(ObjectOutputStream oos=new
ObjectOutputStream(fos))
//he knows how to write but don’t know where to write
{
oos.writeObject(s); //Serialization
}
}
catch(Exception ee)//if you don’t follow serilization
rules you got NotSerlizedException
{
ee.printStackTrace();
}
System.out.println(s.name+"\t"+s.age+"\t"+s.t);
s=null;

try(FileInputStream fis=new FileInputStream("e:\\ab1.txt"))


{
try(ObjectInputStream ois=new ObjectInputStream(fis))
{
First s1=(First)ois.readObject();//do downcasting with
using
// Deserialization
System.out.println(s1.name +"\t"+s1.age+"\t"+s1.t);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}

Does Object class implement Serializable?


no.
why?

Because had Java Founders made Object class implements Serializable,


each and every class in java would have become eligible for
serialization by default. They didn't want this. They wanted developers
to decide whether to go for serialization or not.
//same like cloanable

Second:
import static java.lang.System.*;
import java.io.*;
class base //implements Serializable
{
int num1=30;
base()
{
out.println("base const");
}
}
class sub extends base implements Serializable
{
int num2=60;
sub()
{
out.println("sub const");
}
}
public class Second
{
public static void main(String args[])throws Exception
{
sub s=new sub();
s.num1=100;//override 100 in base
s.num2=200;//override 200 in sub
out.println("Before Saving\t"+s.num1+"\t"+s.num2);
FileOutputStream fos=new FileOutputStream("my.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
s=null;
FileInputStream fis=new FileInputStream("my.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
sub ref=(sub)ois.readObject();//downcasting
out.println("After Retrieving\t"+ref.num1+"\t"+ref.num2);
}
}
Before saving 100 200
After retriving(parat object bnvto) 30 200//bcoz only child class
have serialized

Example 3
import java.io.*;
class base implements Serializable
{
public base()
{
System.out.println("base def");
}
int num1=30;
}
class sub extends base
{
public sub()
{
System.out.println("sub def");
}
int num2=40;
}
public class Third
{
public static void main(String args[])
{
sub s1=new sub();
s1.num1=60;
s1.num2=70;
System.out.println(s1.num1+"\t"+s1.num2);
try(FileOutputStream fos=new
FileOutputStream("a.txt"))
{
try(ObjectOutputStream oos=new
ObjectOutputStream(fos))
{
oos.writeObject(s1);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}

try(FileInputStream fis=new FileInputStream("a.txt"))


{
try(ObjectInputStream ois=new ObjectInputStream(fis))
{
sub temp=(sub)ois.readObject();
System.out.println(temp.num1+"\t"+temp.num2);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
}
Before 60 70
After 60 70
In developer client using file handling:
In developer side we need to write
And in client side we need to read
Example
Devloper:
Student:
package pack1;
import java.io.Serializable;

/**
*
*/

/**
* @author Sriram
*
*/
public class Student implements Serializable
{
public Student()
{
System.out.println("inside Student default constructor");
}

static
{
System.out.println("inside Student class static block");
}

private int rollno,age;


private String name;
/**
* @return the rollno
*/
public int getRollno() {
return rollno;
}
/**
* @param rollno the rollno to set
*/
public void setRollno(int rollno) {
this.rollno = rollno;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Student [rollno=" + rollno + ", age=" + age + ",
name=" + name + "]";
}

StudentDemo:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import pack1.Student;

public class StudentDemo {

public static void main(String[] args)


{
Student s1=new Student();
s1.setRollno(1);
s1.setName("Sachin");
s1.setAge(30);
FileOutputStream fos=null;
ObjectOutputStream oos=null;

try {
fos=new FileOutputStream("e:\\temp.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos=new ObjectOutputStream(fos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos.writeObject(s1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Client code:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import pack1.Student;

public class ClientApp {

public static void main(String[] args) {


// TODO Auto-generated method stub
FileInputStream fis=null;
ObjectInputStream ois=null;
Student ref=null;

try {
fis=new FileInputStream("D:\\forclient\\temp.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois=new ObjectInputStream(fis);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ref=(Student) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

System.out.println("Student info\t"+ref);
}

}
Why we use externizable:

public class Vehicle implements Serializable


{
}
public class FourWheeler extends Vehicle//in is a we don’t make
serialize
{
}
public class Model implements Serializable //in has a we make
serialize
{
}
public class Engine implements Serializable
{
private Model model=new Model();
}
public class Car extends FourWheeler
{
Engine ref=new Engine();
}

Car c=new Car();

Lets talk about object graph related to "c".


Serial_VersionInfo:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used
during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are
compatible with respect to serialization. If the receiver has loaded a class for the object that has a
different serialVersionUID than that of the corresponding sender's class, then deserialization will result in
an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field
named serialVersionUID that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a
default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object
Serialization Specification. However, it is strongly recommended that all serializable classes explicitly
declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may
vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during
deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations,
a serializable class must declare an explicit serialVersionUID value.

SerialversionUID:

As per java docs, during serialization, runtime associates with each serializable class a version number, called a
serialVersionUID, which is used during de-serialization to verify that the sender and receiver of a serialized object have
loaded classes for that object that are compatible with respect to serialization.

Simply put, the serialVersionUID is a unique identifier for Serializable classes. This is used during the deserialization of an
object, to ensure that a loaded class is compatible with the serialized object. If no matching class is found, an
InvalidClassException is thrown.

what exactly happens when you serialize an object?

serialization mechanism generates serialversionuid (if you have not defined it explicitly) for the class , of which
object you are trying to serialize. This serialversionuid is then stored inside the file.

what exactly happens when you deserialize an object?

during deserialization the class of which object you want to deserialize , needs to be loaded.
Here, deserialization mechanism generates serialversionuid (if you have not defined it explicitly) for the class , of
which object you are trying to deserialize. This serialversionuid is then checked with the serialversionuid stored inside file. if
they match then deserialization becomes successful else you get an exception "InvalidClassException" and deserialization
fails.
Since the default serialVersionUID computation differs on different JVM implementations, it is highly recommended for a
class which implements Serializable interface to declare serialversionuid explicitly in order to ensure successful
deserialization across all the platforms.

Without using serialversion uid:


With using serialVersionUid:
Day 13:
Generic background
Before Java5

public class StorageClass


{
private Object ref;
public void store(Object ref)
{
this.ref=ref;
}
public Object get()
{
return ref;
}
}

How will you use above class?

StorageClass s=new StorageClass();

s.store(100);

Integer ref1=(Integer)s.get(); //we do downcasting bcoz get() is object


type so do downcasting
System.out.println(ref1);

what is the risk involved in the above code?


what if we don't remember what type of data we have passed to the
"store()" method?

suppose we have passed "String"


i.e.
s.store("hello");
and while invoking "get()" if we don't remember what we had passed in
the "store()" method, we might say:

Integer ref1=(Integer)s.get();

now here compiler will not give any error as this statement is
syntactically correct. But during runtime "String" will be returned
which we are trying to cast with "Integer" and this will result into
"ClassCastException".

So this is the risk with the code prior to java5.

JAVA5 introduced the concept of "Generics" according to which you can


say

StorageClass<Integer> s=new StorageClass<Integer>();//all wrapper


classes allowed
when you create object this way, for the compiler reference "s"
is only for the type "Integer". If you try to pass type other than
Integer, compiler will give error which makes program safe. e.g.

s.store(100); will work


s.store("hello"); compilation error

while invoking "get()"

Integer ref1=s.get(); no need to do typecasting

String ref2=s.get(); compilation error

Generic 1
import static java.lang.System.*;
public class Generic1<T>//conventional type parameter
{
private T first; //private object first
void setVal(T first) //(object first)
{
this.first=first;
}
T getVal() //objext getVal
{
return first;
}
public static void main(String args[])
{
Generic1<String> g1=new Generic1<String>();
g1.setVal("Hello Generic");
out.println(g1.getVal());

Generic1<Integer> g2=new Generic1<Integer>();


g2.setVal(420);
out.println(g2.getVal());

Generic1<Boolean> g3=new Generic1<Boolean>();


g3.setVal(true);
out.println(g3.getVal());

}
}
Jvm don’t know the generic so compiler convert it to object by using
type earaser

Generic is same like1


Only pa
import static java.lang.System.*;
public class Generic2<W>
{
private W first;
Generic2()
{
}
Generic2(W first)
{
this.first=first;
}
void setVal(W first)
{
this.first=first;
}
static void fun()
{
out.println("in fun static");
}
W getVal()
{
return first;
}
public static void main(String args[])
{
Generic2<String> g1=new Generic2<String>();
g1.setVal("Hello Generic");
out.println(g1.getVal());

Generic2<Integer> g2=new Generic2<Integer>(1000);//we


provide parameterized constructor
out.println(g2.getVal());

Generic2<Boolean> g3=new Generic2<Boolean>();


g3.setVal(true);
out.println(g3.getVal());

Generic2.fun();

}
}

Generic 3:
import static java.lang.System.*;
import java.util.*;
class shape
{
shape draw()
{
return this;
}
}
class triangle extends shape //this extends is inheritance vala
{
shape draw()
{
return this;
}
}
class rect extends shape
{
shape draw()
{
return this;
}
}
class common<T extends shape> // this extends is different -check t is
type of shape
{
T ob;
public common(T ob)
{
this.ob=ob;
}
public T fun()
{
return ob;
}
}
public class Generic3
{

public static void main(String args[])


{
common<rect> c1=new common<rect>(new rect());
rect r=c1.fun();
out.println("in main "+r);

common<triangle> c2=new common<triangle>(new triangle());


triangle t=c2.fun();
out.println("in main "+t);

}
}

Generic 3a:
import static java.lang.System.*;
interface shape
{
void draw();

}
class triangle implements shape
{
public void draw()
{
out.println("in draw of triangle");
}
}
class rect implements shape
{
public void draw()
{
out.println("in draw of rect");
}
}
class common<T extends shape> //t is of type of shape
{
T ob;
public common(T ob)
{
this.ob=ob;
}
public void fun()
{
ob.draw();
}
}
public class Generic3a
{

public static void main(String args[])


{
common<rect> c1=new common<rect>(new rect());
c1.fun();

common<triangle> c2=new common<triangle>(new triangle());


c2.fun();
}
}

Generic 4:
class a{}
class b extends a{}
class MyClass
{
<T>void accept(T t) //method generic banadiya//void accept(Object
t)
{
System.out.println(t);
}
public<T extends a>void disp(T t) //public void disp(a t)a is
parent <a,b is of type a>every child Is type of parent
{
System.out.println(t);
}
}
public class Generic4
{
public static void main(String args[])
{
MyClass m1=new MyClass();
m1.accept(20);
m1.accept(m1);
Generic4 tr=new Generic4(); //provide any name to cllass
m1.accept(tr);

b ob=new b();
m1.disp(ob);
// m1.disp(tr); Error
}

}
Generic 5:
class a{}
class b extends a{}
class MyClass
{
<T>void accept(T t)
{
System.out.println(t);
}
public<T extends a, K> M disp(T t,B ref) //K is another generic
//and M is ref of object
//(a t,Object ref)
{
System.out.println(t);
return ref;
}
}
public class Generic4
{
public static void main(String args[])
{
MyClass m1=new MyClass();
m1.accept(20);
m1.accept(m1);
Generic4 tr=new Generic4();
m1.accept(tr);

b ob=new b();
m1.disp(ob,tr);
// m1.disp(tr); Error
}
}

Type Eraser:
public class Generic1<T>
{
private T first;
void setVal(T first)
{
this.first=first;
}
T getVal()
{
return first;
}

when u compile above class, compiler will remove all the generic
information because JVM can't understand Generics. This is known as
"Type Erasure". So after compilation the above class will be as
follows:

public class Generic1


{
private Object first;
void setVal(Object first)
{
this.first=first;
}
Object getVal()
{
return first;
}
}

Collection Api:

Why Collection API?

Arrays are fixed in size. To change use collection api

Collection API provides us


Containers
They are dynamic
Some of them are sorted
Some of them allow only unique elements
some of them are thread-safe
some of them are not thread-safe , so they are efficient
Some of them allow u to store key and value
all the containers implement Serializable so that they can
be easily
persisted inside file system.

Iterator
allows u to traverse through containers.
Algorithms
sort,count,max,min etc.

Entire support for Collection API has been given inside "java.util"
package.
List
index based, duplicates allowed

Set
unique, sometimes sorted

Map
key - value pair
put using key and value
get using only key

key must be unique and sometimes sorted.

ArrayList
good for traversal,random access
Vector
slow, thread-safe, legacy class
LinkedList
doubly linked list, good for insertion and deletion from middle.

HashSet
fast, order not guaranteed
TreeSet
slow, sorted
HashMap
fastest map implementation
TreeMap
slow, sorted keys
Hashtable
slow,thread-safe,legacy class

Demo1:
import java.util.*;
import static java.lang.System.*;
public class ArrayListDemo
{
public static void main(String args[])
{
List <String>a1=new ArrayList<String>();//list is parent of
arraylist array list is a implementation of List(interface)
out.println("Initial size of a1: "+a1.size());//
a1.add("c");//add is method of List interface
a1.add("a");
a1.add("e");
a1.add("b");
a1.add("d");
a1.add("f");
a1.add(1,"a2"); //1 position pe add a2
out.println("After adding size of a1: "+a1.size());
out.println("Contents of a1: "+a1);
a1.remove("f"); //in that remove f
a1.remove(2); //in that 2nd pos element is removed
out.println("After removing size of a1: "+a1.size());
out.println("Contents of a1: "+a1);
}

In ArrayList when element added in middle then next element phoode


phoode srktat
In linkedList phoode list srkat nhi fkt te consider krt tyala mdhe
Demo 2:

import java.util.*;
import static java.lang.System.*;
public class ArrayListDemo1
{
public static void main(String args[])
{
List <Integer>a1=new ArrayList<Integer>();
out.println("Initial size of a1: "+a1.size());
a1.add(5);
a1.add(10);
a1.add(15);
a1.add(20);
//a1.add(2);
a1.add(30);
out.println("After adding size of a1: "+a1.size());
out.println("Contents of a1: "+a1);
//a1.remove(2); // remove element at index 2
a1.remove(new Integer(2)); // remove element "2"
out.println("After removing size of a1: "+a1.size());
out.println("Contents of a1: "+a1);
}
}
Linkedlist:
import java.util.*;
import static java.lang.System.*;
public class LinkedListDemo
{
public static void main(String args[])
{
List <String>l=new LinkedList<String>();
l.add("f");
l.add("b");
l.add("d");
l.add("e");
l.add("c");
((LinkedList)l).addLast("z");//add last and add first is
methods of Linkedlist we do downcasting
((LinkedList)l).addFirst("a");
l.add(1,"a2");
out.println("Original contents of l "+l);
l.remove("f");
l.remove(2);
out.println("Contents after deletion "+l);
((LinkedList)l).removeFirst();
((LinkedList)l).removeLast();
out.println("contents after deleting first and last "+l);
String val=l.get(2);
out.println("element at second index is "+val);
}
}

Iterator:
Demo 1:
import java.util.*;
public class IteratorDemo
{
public static void main(String args[])
{
List<String> mylist=new ArrayList<String>();
mylist.add("hello");
mylist.add("welcome");
mylist.add("all the best");
// now let's create iterator

Iterator itr=mylist.iterator();//arraylist contains


.iterator() method

//Iterator-interface
//.iterator-method

while(itr.hasNext())
{
System.out.println(itr.next());
}
}}
/* "hasNext()" method checks whether there are elements inside list
for traversal. it returns true or false. */ check krt ki element
ahet ka list mdhe

/* "next()" method returns the current element and places the record
pointer on the next element */ //return current and next la jato

ArrayList <String>a1=new ArrayList<String>();


out.println("Initial size of a1: "+a1.size());
a1.add("c");
a1.add("a");
a1.add("e");
a1.add("b");

// how to use iterator

Iterator itr=a1.iterator();
here "iterator()" is a method of ArrayList which returns the
child class of
Iterator interface.

while(itr.hasNext())
// hasNext() returns boolean i.e. it returns true as long as
elements are there in ArrayList for traversal.

{
S.o.p(itr.next());
next() method will return the current element and place the
record pointer on next element.
}

/*
The Arrays class in java.util package is a part of the Java Collection
Framework. This class provides static methods to dynamically create and
access Java arrays.
*/

import java.util.Arrays;
import java.util.List;

public class Demo


{
public static void main(String args[])
{
int arr[]= {8,2,5,3,9,7};
System.out.println("Let's print array using foreach");
for(int i:arr)//syntactical sugar for each loop
{
System.out.println(i);
}
System.out.println("Let's print array using Arrays class");
System.out.println(Arrays.toString(arr));//this toString
method is different this method is of belongs to array it print[8, 2,
5…..]
Arrays.sort(arr);
System.out.println("After sorting");
for(int i:arr)
{
System.out.println(i);
}

List<int[]>mylist=Arrays.asList(arr);//by using this int


list me array mdhe janar
System.out.println("Traversing from the list");
for(int k:mylist.get(0))
{
System.out.println(k);
}
}
}

Arraylist vs copy on array list

Difference between ArrayList and CopyOnWriteArrayList

There are four concrete implementation of List interface:-

 Vector
 ArrayList
 LinkedList
 CopyOnWriteArrayList

Different between Vector,ArrayList and LinkedList is quite clear but difference between ArrayList and
CopyOnWriteArrayList doesn’t seems to be clear at first glance. Here I am trying to explain between difference between
ArrayList and CopyOnWriteArrayList , with one simple example.As we all know ArrayList is not thread safe so any
simultaneous thread can access and modify the content of list simultaneously.Here lies the dangerous,
ConcurrentModificationException. When one thread is Iterating over an ArrayList and any other thread(which may be the
same thread) modify the content of list and when we again call next() on the iterator ,we get this exception. Which means
that no thread can modify the ArrayList while an Iterator is iterating over this. We can solve this by surrounding the code that
try to modify this list in a synchronized block with some lock so that the thread trying to modify the ArrayList wait for the
iterator to complete.
This seems simple solution but not a efficient one where there are many threads iteration over an ArrayList because each
thread have to wait for a considerable time.

Another possible solution could be to use CopyOnWriteArrayList instead of ArrayList. This is same as ArrayList with one
difference. All operations that change the contents of aCopyOnWriteArrayList collection cause the underlying array to be
replaced with a copy of itself before the contents of the array are changed. Any active iterators will continue to see the
unmodified array, so there is no need for locks. Iterators created by a CopyOnWriteArrayList object cannot change the
underlying array. Though these iterators do have methods for changing the underlying collection, their implementations
throw an UnsupportedOperationException instead of modifying the underlying collection.

Demo 1:
import java.util.*;
import java.util.concurrent.*;
public class First
{
public static void main(String args[])
{
List<String> list= new ArrayList<String>();
list.add("vivek");
list.add("kumar");
Iterator i =list.iterator();
while(i.hasNext())
{
System.out.println(i.next());
//list.add("abhishek"); // ConcurrentModificationException
bcoz it is ArrayList
//iteration veli add hot nahi
}
}
}
Demo 2:
import java.util.*;
import java.util.concurrent.*;
public class Second
{
public static void main(String args[])
{
List<String> list= new CopyOnWriteArrayList<String>();
list.add("vivek");
list.add("kumar");
System.out.println("Before modification\t"+list);
Iterator i =list.iterator();
while(i.hasNext())
{
System.out.println(i.next());
list.add("abhishek");//now showing correct
//i.remove();// UnsupportedOperationException
}
System.out.println("after modification\t"+list);
System.out.println("After modification:");
Iterator i2 =list.iterator();
while(i2.hasNext())
{System.out.println(i2.next());
}}}

When you apply iterator on CopyOnWriteArrayList then snapshot is created

Demo 3:
We does not do remove in CopyOnWriteArrayList

public class Third {

public static void main(String[] args) {


List<Integer> mylist=new CopyOnWriteArrayList<>();
mylist.add(10);
mylist.add(20);
mylist.add(30);
mylist.add(40);
System.out.println("Using Iterator");
Iterator<Integer> itr=mylist.iterator();
while(itr.hasNext())
{
int k=itr.next();
if(k==20)
{
itr.remove(); // UnsupportedOperationException
}
System.out.println(k);
}}}
HashMap()

Constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75).

An instance of HashMap has two parameters that affect its performance: initial capacity and load factor. The capacity is
the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created.
The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased.

When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table
is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of
buckets.

//if capacity go out of 12 maps capacity get double

Concurrent hashmap:
-hashtable complete synchronized
-slow

put operation

hashCode() is invoked to determine the bucket.

hashcode - first entry

subsequent entries

hashcode - different - different bucket

same [ hash collision case]


== - true - overwrite the value
false
equals - true - overwrite the value
false - linked list will be formed within a
bucket i.e. same bucket having different Entries [Entry]

Get operation

hashcode -
bucket is determined for search
==
- true - get the value
false
equals - true - get the value
false - linked list will be traverse and
subsequently == and equals are invoked.

Hashmapbasic working:

import java.util.HashMap;

import java.util.Map;

public class HashMapBasicWorkingDemo


{
public static void main(String[] args) {
Map<Integer,String> mymap=new HashMap<>();
mymap.put(10,"Anil");
mymap.put(20,"Sunita");
mymap.put(30,"Vishal"); //by using put we enter entries
System.out.println("Map is\t"+mymap);
String name=mymap.get(30); //by using get we return

System.out.println(name);
name=mymap.get(40); //we get null
System.out.println(name);
mymap.put(10,"Reena");
System.out.println("Map is\t"+mymap);
}

Hashmapdemo1:

package datatypes_pro;

// when u call get, the sequence is "hashCode()","=="


// if == returns false , it checks "equals"
import java.util.*;
class Employee
{
private String empid;
private int deptcode;
private int citycode;

public Employee(String empid,int deptcode,int citycode)


{
this.empid=empid;
this.deptcode=deptcode;
this.citycode=citycode;
}
@Override
public int hashCode()
{
System.out.println("in hashcode"); //dept code override
return deptcode;
}
@Override
public boolean equals(Object ref)
{
boolean flag=citycode==((Employee)ref).citycode; //city code
override
//return citycode==((employee)ref).citycode _internally works
System.out.println("in equals\t"+flag);
return flag;
}
@Override
public String toString()
{

return empid+"\t"+deptcode+"\t"+citycode;
}
}
public class HashMapDemo1
{
public static void main(String args[])
{
Employee e1=new Employee("e001",1,10);
Employee e2=new Employee("e002",1,12);
Employee e3=new Employee("e003",2,10);
Employee e4=new Employee("e004",1,13);

Map<Employee,String> map=new HashMap<Employee,String>();


map.put(e1,"first");
map.put(e2,"second");
map.put(e3,"third");
map.put(e4,"fourth");
System.out.println(map);

String val=map.get(e2);
System.out.println(val);}}
Check flow in ppt at address:
D:\java\Day_13.zip\Day_13\Generics_and_Collection\Collection_API\Map_Im
plementations on that address

First check e1 and e2 hashcode is same e.g 1 so check equal to in equal


to check e1 and e2 is same or not so not then false and then again
equals check on values so if it is different

Demo1:

//package datatypes_pro;

// when u call get, the sequence is "hashCode()","=="


// if == returns false , it checks "equals"
import java.util.*;
class Employee
{
private String empid;
private int deptcode;
private int citycode;
public Employee(String empid,int deptcode,int citycode)
{
this.empid=empid;
this.deptcode=deptcode;
this.citycode=citycode;
}
@Override
public int hashCode()
{
System.out.println("in hashcode");
return deptcode;
}
@Override
public boolean equals(Object ref)
{
boolean flag=citycode==((Employee)ref).citycode;
System.out.println("in equals\t"+flag);
return flag;
}
@Override
public String toString()
{

return empid+"\t"+deptcode+"\t"+citycode;
}
}
public class HashMapDemo1_a
{
public static void main(String args[])
{
Employee e1=new Employee("e001",1,10);
Employee e2=new Employee("e002",1,12);
Employee e3=new Employee("e003",2,10);
Employee e4=new Employee("e004",1,13);
Employee e5=new Employee("e005",1,12); //In that overwrite
in position of whose value is same
Employee e6=e3;

Map<Employee,String> map=new HashMap<Employee,String>();


map.put(e1,"first");
map.put(e2,"second");
map.put(e3,"third");
map.put(e4,"fourth");
map.put(e5,"fifth");
map.put(e6,"sixth");
System.out.println(map);

String val=map.get(e2);
System.out.println(val);

val=map.get(e3);
System.out.println(val);
}
}
Tree Map:
1)
import java.util.Map;
import java.util.TreeMap;

public class TreeMapDemo1


{
public static void main(String[] args) {
Map<Integer,String>mymap=new TreeMap<Integer,String>();
mymap.put(3,"hello");
mymap.put(2,"welcome");
mymap.put(1,"hi");
mymap.put(2,"good bye"); //on 2 overwrite
System.out.println(mymap);
}

//keys sort automatically


2)
import java.util.*;
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age=age;
}
public String toString()
{
return "["+name+"\t"+age+"]";
}
}
public class TreeMapDemo2
{
public static void main(String[] args)
{
Person p1=new Person("abc",20);
Person p2=new Person("xyz",17);
TreeMap<Person,Integer>ref1=new TreeMap<Person,Integer>();

//in reference provide class cast exception bcoz p1 and p2 is reference


so he don’t know konla sort kru name la ki age la sorting so we get
class cast exception

ref1.put(p1, 100);
ref1.put(p2, 200);
System.out.println(ref1);
}
}

Comparable:
3)
import java.util.*;
class Person implements Comparable<Person>
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age=age;
}
public int compareTo(Person ref)//solution fir previous code
//method of comparable interface //if same both then 0 if first less
then negative if some is higher then positive
{
return name.compareTo(ref.name);//string vala comapreTo
}
public String toString()
{
return "["+name+"\t"+age+"]";
}
}
public class TreeMapDemo3
{
public static void main(String[] args)
{
Person p1=new Person("abc",20);
Person p2=new Person("xyz",17);
TreeMap<Person,Integer>ref1=new TreeMap<Person,Integer>();
ref1.put(p1, 100);
ref1.put(p2, 200);
System.out.println(ref1);
}
}

4)
import java.util.*;
class Person implements Comparable<Person>
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age=age;
}
public int compareTo(Person ref)
{
if(age>ref.age)
{
return 1;
}
else if(age<ref.age)
{
return -1;
}
else
{
return 0;
}
}
public String toString()
{
return "["+name+"\t"+age+"]";
}
}
public class TreeMapDemo4
{
public static void main(String[] args)
{
Person p1=new Person("abc",20);
Person p2=new Person("xyz",17);
TreeMap<Person,Integer>ref1=new TreeMap<Person,Integer>();
ref1.put(p1, 100);
ref1.put(p2, 200);
System.out.println(ref1);
}
}

comparator
//comparable demo have drawbacks of only one key is sorted
//and maintainance drawback n krnya sthi
//so for that comparator interface

import java.util.*;
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age=age;
}
public String toString()
{
return "["+name+"\t"+age+"]";
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class NameComparator implements Comparator<Person>
{
public int compare(Person ref1,Person ref2)
{
return ref1.getName().compareTo(ref2.getName());
}
}
public class TreeMapDemo5
{
public static void main(String[] args)
{
Person p1=new Person("abc",20);
Person p2=new Person("xyz",17);
TreeMap<Person,Integer>ref1=new TreeMap<Person,Integer>(new
NameComparator());
ref1.put(p1, 100);
ref1.put(p2, 200);
System.out.println(ref1);
}
}

Treemap 6:

import java.util.*;
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age=age;
}
public String toString()
{
return "["+name+"\t"+age+"]";
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class NameComparator implements Comparator<Person>
{
public int compare(Person ref1,Person ref2)
{
return ref1.getName().compareTo(ref2.getName());
}
}
class AgeComparator implements Comparator<Person>
{
public int compare(Person ref1,Person ref2)
{
if(ref1.getAge()>ref2.getAge())
{
return 1;
}
else if(ref1.getAge()<ref2.getAge())
{
return -1;
}
else
{
return 0;
}
}
}
public class TreeMapDemo6
{
public static void main(String[] args)
{
Person p1=new Person("abc",20);
Person p2=new Person("xyz",17);
TreeMap<Person,Integer>ref1=new TreeMap<Person,Integer>(new
AgeComparator());
ref1.put(p1, 100);
ref1.put(p2, 200);
System.out.println(ref1);
}
}

Serializable in arraylist:

/*class Student implements Serializable


rollno
name

create 2 objects of Student , store them inside ArrayList and store


that ArrayList inside the file.

now read from file , the ArrayList and traverse it using Iterator
*/

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class Student implements Serializable


{
private int rollno;
private String name;

public int getRollno() {


return rollno;
}

public void setRollno(int rollno) {


this.rollno = rollno;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}
@Override
public String toString() {
return "Student [rollno=" + rollno + ", name=" + name + "]";
}

}
public class ArrayList_Serialization_Demo
{
public static void main(String args[])
{
List<Student>mylist=new ArrayList<Student>();
Student s1=new Student();
Student s2=new Student();
s1.setRollno(1);
s1.setName("Abc");
s2.setRollno(2);
s2.setName("Xyz");
mylist.add(s1);
mylist.add(s2);
FileOutputStream fos=null;
FileInputStream fis=null;
ObjectOutputStream oos=null;
ObjectInputStream ois=null;

try {
fos=new
FileOutputStream("e:\\temp1\\examples\\temp.txt");
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos=new ObjectOutputStream(fos);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos.writeObject(mylist);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // serialization

// now reading list from file

try {
fis=new FileInputStream("e:\\temp1\\examples\\temp.txt");
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois=new ObjectInputStream(fis);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<?> ref=null;
try {
ref=(List<?>) ois.readObject();//ref mdhe jaat list
jati
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Iterator<?> itr=ref.iterator();
while(itr.hasNext())
{
System.out.println(itr.next());
}
}
}

Using #map:

import java.util.*;
import java.io.*;
class MyClass implements Serializable
{

private static final long serialVersionUID = 1L;


int num;
MyClass(int num)
{
this.num=num;
}
}
public class HashMap_Serialization_Demo
{
public static void main(String args[])
{
try
{
Map<String,MyClass>h=new HashMap<String,MyClass>();

FileOutputStream fos=new
FileOutputStream("e:\\temp1\\examples\\temp.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);

MyClass m1=new MyClass(100);


System.out.println(m1.num); // 100
h.put("first",m1);

//m1.num=200;

oos.writeObject(h); // copy of h and m1


oos.close();
fos.close();

m1.num=300;

System.out.println(m1.num); // 300

FileInputStream fis=new
FileInputStream("e:\\temp1\\examples\\temp.txt");
ObjectInputStream ois=new ObjectInputStream(fis);

Map<?,?> map=(Map<?,?>)ois.readObject();

MyClass ref=(MyClass) map.get("first");

System.out.println(ref.num); // 100
}
catch(Exception ee)
{
System.out.println(ee);
}

}
}

Using map and set: set is unique

import java.util.*;
import java.io.*;
class MyClass implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
int num;
MyClass(int num)
{
this.num=num;
}
}
public class HashMap_Serialization_Demo
{
public static void main(String args[])
{
try
{
Map<String,MyClass>h=new HashMap<String,MyClass>();

FileOutputStream fos=new
FileOutputStream("e:\\temp1\\examples\\temp.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);

MyClass m1=new MyClass(100);


System.out.println(m1.num); // 100
h.put("first",m1);

//m1.num=200;

oos.writeObject(h); // copy of h and m1


oos.close();
fos.close();

m1.num=300;

System.out.println(m1.num); // 300

FileInputStream fis=new
FileInputStream("e:\\temp1\\examples\\temp.txt");
ObjectInputStream ois=new ObjectInputStream(fis);

Map<?,?> map=(Map<?,?>)ois.readObject();

MyClass ref=(MyClass) map.get("first");

System.out.println(ref.num); // 100
}
catch(Exception ee)
{
System.out.println(ee);
}

}
}

Properties file:
Demo1:
Read properties file:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo1


{
public static void main(String args[])
{
FileReader reader=null;
try {
reader = new FileReader("e:\\my.properties");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// create properties object


Properties p = new Properties();

// Add a wrapper around reader object


try {
p.load(reader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// access properties data


System.out.println(p.getProperty("user"));
System.out.println(p.getProperty("password"));
}
}

Set properties:
package threadrpo;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo2


{
public static void main(String args[])
{
Properties p = new Properties();

// add properties to it
p.setProperty("name", "Sachin");
p.setProperty("email",
"[email protected]");//both dtrings key
value
// store the properties to a file
try {
p.store(new FileWriter("e:\\info.properties"),
"Basic properties example");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Synchronized and collections:

List<String> mylist=new ArrayList<String>(); // non-thread safe list

List<String> mylist1=Collections.synchronizedList(mylist);//collections
class in which they have synchronizedlist method to make safe

mylist1- Thread safe list

Map<String,Integer> mymap=new HashMap<String,Integer>(); // non-


thread safe map

Map<String,Integer> mymap1=Collections.synchronizedMap(mymap);

mymap1 - Thread safe map

/*

when u say

List arrayList=Collections.synchronizedList(new ArrayList());

we think that the resulting List will be synchronized, and therefore


can be considered safe.

Not really.

Well, individual method calls of synchronized List and Vector are


synchronized. In the following example,as soon as size() method is
completed by one thread (lock will be released), other thread can
invoke remove() method. Now when first thread will try to invoke get()
"IndexOutOfBoundsException" will come because there is no element
exists.

Solution:
size() as well as get() methods invocation must happen together as one
unit, no interference from other threads should be there, or else we’ll
get the above exception.The fact that the individual methods are
synchronized is irrelevant. In fact, we can go back to using the non-
synchronized ArrayList, and the program ill work, as long as we
synchronize properly to make thesize() and get() calls happen as one
atomic, indivisible unit of execution:

*/
import java.util.*;
class HelloThread
{

int i=1;

public void go()


{
List arrayList=Collections.synchronizedList(new ArrayList());
arrayList.add("hello");

Thread thread1=new Thread(new Runnable() {

public void run()


{
int size=arrayList.size();
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
System.out.println(arrayList.get(size-1));
}
});
thread1.start();
Thread thred2=new Thread(new Runnable()
{
public void run()
{
arrayList.remove(0);
}
});
thred2.start();
}
}

public class test


{
public static void main(String[] args)
{
HelloThread hello=new HelloThread();
hello.go();
}
}
//Indexoutofbound exception got bcoz phila thread complete vhycha
adhich dusra call hoto ani remove krto to get krycha adhich
/*
size() as well as get() methods invocation must happen together as one
unit, no interference from other threads should be there, or else we’ll
get the above exception.The fact that the individual methods are
synchronized is irrelevant. In fact, we can go back to using the non-
synchronized ArrayList, and the program ill work, as long as we
synchronize properly to make thesize() and get() calls happen as one
atomic, indivisible unit of execution:

*/

import java.util.*;
class HelloThread
{

int i=1;

public void go()


{
List arrayList=Collections.synchronizedList(new ArrayList());
arrayList.add("hello");

Thread thread1=new Thread(new Runnable() {

public void run()


{
synchronized(arrayList) //use synchronized block so it get locked
{
int size=arrayList.size();
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
System.out.println(arrayList.get(size-1));
}
}
});
thread1.start();
Thread thread2=new Thread(new Runnable()
{
public void run()
{
synchronized(arrayList)
{
arrayList.remove(0);
}
}
});
thread2.start();

try
{
thread1.join();
thread2.join();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
System.out.println("ArrayList is\t"+arrayList);
}
}

public class test1


{
public static void main(String[] args)
{
HelloThread hello=new HelloThread();
hello.go();
}
}

Mixing in generic:
Test1:
import java.util.*;
public class Test1
{
void disp(List mylist)
{
Iterator it=mylist.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
public static void main(String args[])
{
List<Integer>m=new ArrayList<Integer>();
m.add(20);
m.add(40);
Test1 t=new Test1();
t.disp(m);

}
}
Test 2:
import java.util.*;
public class Test2
{
void disp(List mylist) //non generic
{
Iterator it=mylist.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
mylist.add(0,"hello");
}
public static void main(String args[])
{
List<Integer>m=new ArrayList<Integer>(); //generic
//use generic and non generic so it is mixing
m.add(20);
m.add(40);
Test2 t=new Test2();
t.disp(m);
System.out.println("in main\t"+m); //[“hello” ,20,40]
}
}

Test 3:
import java.util.*;
public class Test3
{
void disp(List mylist)
{
Iterator it=mylist.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
mylist.add(0,"hello");
}
public static void main(String args[])
{
List<Integer>m=new ArrayList<Integer>();
m.add(20);
m.add(40);
Test3 t=new Test3();
t.disp(m);
Integer ob=m.get(0); // risk involved
//in integer it trying to add string so it exception
System.out.println(ob);

}
}

Arraystore except demo:

import java.util.*;
class base
{
}
class sub extends base
{
}
class sub1 extends base
{
}
public class ArrayStoreExcepDemo
{

public static void main(String args[])


{
base arr[]=new sub[3];
arr[0]=new sub();
arr[1]=new sub();
arr[2]=new sub1(); //sub1 is not joint with sub so bhau bhau
don’t knows only knows his father
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}

Upcasting in generic:
Animal arr[]=new Dog[2]; // allowed because during runtime if you say

arr[1]=new Cat();
There is a JVM to check what is illegal and give you
ArrayStoreException.

But

List<Animal> mylist=new ArrayList<Dog>(); not allowed because if you


say

mylist.add(new Cat())
even though it is illegal,JVM will not be able to detect it because it
doesn't know anything about generics. All generic information compiler
removes at the time of compilation. ( Type Erasure )
Hence in case of generics compiler itself has to consider all possible
scenarios of runtime and guide you accordingly.

you can do following


List<Animal>mylist=new ArrayList<Animal>();
mylist.add(new Dog());
mylist.add(new Cat());

e.g.

void disp(List<Animal> arr)


{
arr.add(new Dog());
arr.add(new Cat());
}

disp(new ArrayList<Animal>());

test1:

import java.util.*;
class Animal
{
void eat()
{
}
public String toString()
{
return getClass().getName();
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog eat");
}
public String toString()
{
return getClass().getName();
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("Cat eat");
}
public String toString()
{
return getClass().getName();
}
}
public class Test1
{
static void disp(List<Animal> arr) //if we make animal generic
then all child become generic
{
arr.add(new Dog());
arr.add(new Cat());
System.out.println(arr);
}
public static void main(String args[])
{
disp(new ArrayList<Animal>());
}
}

Test 1_a
import java.util.*;
class Animal
{
void eat()
{
}
public String toString()
{
return getClass().getName();
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog eat");
}
public String toString()
{
return getClass().getName();
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("Cat eat");
}
public String toString()
{
return getClass().getName();
}
}
public class Test1_a
{
static void disp(List<Animal> arr)
{
arr.add(new Dog());
arr.add(new Cat());

for(Animal ref:arr) // programmer would like to do this


{
ref.eat();
}
}
public static void main(String args[])
{
// why programmer wants to pass "list of Dog" to the method which
accepts "list of Animal" ?
// what is his intention ?

disp(new ArrayList<Dog>()); // won't compile


//jar dog tkl tr dog che child fkt pthva or animal taka

}
}
Test 2:
import java.util.*;
class Animal
{
void eat()
{
}
public String toString()
{
return getClass().getName();
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog eat");
}
public String toString()
{
return getClass().getName();
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("Cat eat");
}
public String toString()
{
return getClass().getName();
}
}
public class Test2
{
static void disp(List<? extends Animal> arr)
{
for(Animal l:arr)
{
l.eat();
}
}
public static void main(String args[])
{
Dog d[]={new Dog(),new Dog()};
List<Dog>l=new ArrayList<Dog>();
l.add(d[0]);
l.add(d[1]);
disp(l);

// now with cat


Cat c[]={new Cat(),new Cat()};
List<Cat>l1=new ArrayList<Cat>();
l1.add(c[0]);
l1.add(c[1]);
disp(l1);
}
}

Test 3
import java.util.*;
class Animal
{
void eat()
{
}
public String toString()
{
return getClass().getName();
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog eat");
}
public String toString()
{
return getClass().getName();
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("Cat eat");
}
public String toString()
{
return getClass().getName();
}
}
public class Test4
{
static void disp(List<? super Dog> arr) //parent only
{
arr.add(new Dog());
arr.add(new Dog());
for(Object d:arr)
{
if(d instanceof Dog)
{
((Dog)d).eat();
}
else if(d instanceof Cat)
{
((Cat)d).eat();
}
}
System.out.println(arr);
}
public static void main(String args[])
{
Dog d[]={new Dog(),new Dog()};
List<Animal>l=new ArrayList<Animal>();
l.add(new Cat());
disp(l);
List<Dog>l1=new ArrayList<Dog>();
l1.add(new Dog());
disp(l1);

}
}

Test 4
Test 6
import java.util.*;
class Animal
{
void eat()
{
}
public String toString()
{
return getClass().getName();
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog eat");
}
public String toString()
{
return getClass().getName();
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("Cat eat");
}
public String toString()
{
return getClass().getName();
}
}
public class Test6
{
static void disp(List<Object> arr)//fkt object chalel child nhi
chlnr
{
arr.add(new Dog()); // allowed
arr.add(200); // allowed
System.out.println(arr);
}
public static void main(String args[])
{
List<Object>ob=new ArrayList<Object>();
disp(ob);
List<Integer>ob1=new ArrayList<Integer>();
// disp(ob1); // error, not allowed//show error in child
}
}

<? Super class_name> here class will invoke parent


<? Extends class_name> here class will invoke the child and itself
<?> only itself
Java 8 features

Why we need Default Methods?

Before Java8 interfaces were too tightly coupled with their implementation classes. I.e. it was not possible to add a method
in interface without breaking the implementer class. Once you add a method in an interface, all its implemented classes had
to define method body of this new method. e.g. if you add a single method in an interface List, it breaks everything. You
need to add its implementation in every class that implements List interface. Imagine in real world how many custom
classes would change if you add method declarations in interfaces like this.

So for backward compatibility, Java 8 introduced Default Methods.

A default method is a method defined and not just declared in an interface whose method header begins with the default
keyword. Every class that implements the interface inherits the interface's default methods and can override them.

Demo1:

interface emp
{
String disp1();
default String disp2()
{
return "in disp2"; //in interface we use concrete method we use
default.
}
}
class MyClass implements emp
{
public String disp1()
{
return "in disp1";
}
}
public class Demo1
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo2:

// error: Duplicate default methods named disp2 with the parameters () and ()
are inherited from the types emp1 and emp

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp,emp1//show error bcoz both have duplicate disp2
method
{
public String disp1()
{
return "in disp1";
}
}
public class Demo2
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo3:
interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp,emp1
{
// must be public
public String disp2() //in that disp2() of class wins
{
return "in overridden method of MyClass";
}
public String disp1() /
{
return "in disp1";
}
}
public class Demo3
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo3_a:

package trial;

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class xyz //that class method will wins
{
public String disp2()
{
return "in disp2 of xyz";
}
}
class MyClass extends xyz implements emp,emp1
{

public String disp1()


{
return "in disp1";
}
}
public class Demo3_a
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo3_b:

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class xyz
{
public String disp2()
{
return "in disp2 of xyz";
}
}
class MyClass extends xyz implements emp,emp1
{
String disp2() // error/ error bcoz need to make it public bcoz in
parent it is by default public

{
return "in disp2 of MyClass";
}
public String disp1()
{
return "in disp1";
}
}
public class Demo3_b
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo 3_c:
package trial;

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class xyz
{
public String disp2()
{
return "in disp2 of xyz";
}
}
class MyClass extends xyz implements emp,emp1
{
public String disp2() //error is solved by providing public
{
return "in disp2 of MyClass";
}
public String disp1()
{
return "in disp1";
}
}
public class Demo3_c
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo 4:
interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp //extend interface
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
public String disp1()
{
return "in disp1";
}
}
public class Demo4
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());//jvlchyala call kel
}
}’

Demo 5
interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
// must be public
public String disp2()
{
return "in overridden method of MyClass";
}
public String disp1()
{
return "in disp1";
}
}
public class Demo5
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo 6:

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
// must be public
public String disp2()
{
System.out.println(emp1.super.disp2());
//System.out.println(emp.super.disp2()); // Illegal reference to super type
emp, cannot bypass the more specific direct super type emp1
//ekch pappa vrch cl kru shkto

return "in overridden method of MyClass";


}
public String disp1()
{
return "in disp1";
}
}
public class Demo6
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
}
}

Demo 6_a:

interface emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp
{
String disp1();
default String disp2()
{
System.out.println(emp.super.disp2());//disp 2 call of emp
// System.out.println(super.disp2()); // super reference is
illegal in interface context
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
// must be public
public String disp2()
{
System.out.println(emp1.super.disp2());
//System.out.println(super.disp2()); // error: The method disp2()
is undefined for the type Object
//System.out.println(emp.super.disp2()); //Illegal reference to super type
emp, cannot bypass the more specific direct super type emp1

return "in overridden method of MyClass";


}
public String disp1()
{
System.out.println(emp1.super.disp2());
return "in disp1";
}
}
public class Demo6_a
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());}}

Demo 7:
package core1;
interface emp
{
int k=10; // public static and final
// private int g=40; modifier private not allowed
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp
{
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
// must be public
public String disp2()
{
System.out.println(emp1.super.disp2());
//System.out.println(emp.super.disp2()); not an enclosing class: emp

return "in overridden method of MyClass";


}
public String disp1()
{
return "in disp1";
}
}
public class Demo7
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
System.out.println("emp data is\t"+emp.k);
System.out.println("emp1 data is\t"+emp1.k);
System.out.println("MyClass data is\t"+MyClass.k);//implement and
extend kel mhnun sglyt te print jhl
//emp.k=20; error
}
}
Demo 7_a
package core1;
interface emp
{
int k=10; // by default public static and final
// private int g=40; modifier private not allowed
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1 extends emp
{
String k="hello";
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp1
{
// must be public
public String disp2()
{
System.out.println(emp1.super.disp2());
//System.out.println(emp.super.disp2()); not an enclosing class: emp

return "in overridden method of MyClass";


}
public String disp1()
{
return "in disp1";
}
}
public class Demo7_a
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
System.out.println("emp data is\t"+emp.k);
System.out.println("emp1 data is\t"+emp1.k);
System.out.println("MyClass data is\t"+MyClass.k);
//emp.k=20; error
}
}

O/p
in disp1
in disp2 of emp1
in overridden method of MyClass
emp data is 10
emp1 data is hello
MyClass data is hello
Demo 7b
interface emp
{
int k=10; // public static and final
// private int g=40; modifier private not allowed
String disp1();
default String disp2()
{
return "in disp2 of emp";
}
}
interface emp1
{
String k="hello"; //this is String and in parent it is int so it not
override
String disp1();
default String disp2()
{
return "in disp2 of emp1";
}
}
class MyClass implements emp,emp1
{
// must be public
public String disp2()
{
System.out.println(emp1.super.disp2());
//System.out.println(emp.super.disp2()); not an enclosing class: emp

return "in overridden method of MyClass";


}
public String disp1()
{
return "in disp1";
}
}
public class Demo7_b
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp1());
System.out.println(m.disp2());
System.out.println("emp data is\t"+emp.k);
System.out.println("emp1 data is\t"+emp1.k);
System.out.println("MyClass data is\t"+MyClass.k); // ambiguity
error
//emp.k=20; error
}
}
Demo 8
/*
This is the “class wins” rule.
The “class wins” rule ensures compatibility with Java 7. If you add default
methods to an interface, it has no effect on code that worked before java8.

*/

interface emp
{
default String disp2()
{
return "in disp2 of emp";
}
}
class base
{
// must be public
public String disp2()
{
return "in disp2 of base"; //always class wins
}
}
class MyClass extends base implements emp
{

}
public class Demo8
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp2());
}
}

Demo 8_a
package trial;
interface emp
{
default String disp2()
{
return "in disp2 of emp";
}
}
class base
{
// must be public
String disp2()
{
return "in disp2 of base";
}
}
// error : The inherited method base.disp2() cannot hide the public abstract
method in emp
class MyClass extends base implements emp
{

}
public class Demo8_a
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp2());
}
}

Demo 8b
package trial;
interface emp
{
default String disp2()
{
return "in disp2 of emp";
}
}
class base
{
// must be public
String disp2()
{
return "in disp2 of base";
}
}

class MyClass extends base implements emp


{
public String disp2()
{
return "in disp2 of MyClass"; //this is called by overriding by
late binding
}
}
public class Demo8_b
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp2());
}
}

Demo 9
/*

This is the “class wins” rule.


The “class wins” rule ensures compatibility with Java 7. If you add default
methods to an interface, it has no effect on code that worked before java8.

*/
interface emp
{
default String disp2()
{
return "in disp2 of emp";
}
}
class base
{
// must be public
public String disp2()
{
return "in disp2 of base";
}
}
class MyClass extends base implements emp
{
void perform()
{
System.out.println(emp.super.disp2());
}
}
public class Demo9
{
public static void main(String args[])
{
MyClass m=new MyClass();
System.out.println(m.disp2());
m.perform();
}
}

Demo 10
package trial;
interface emp1
{
default void disp()
{
System.out.println("in emp1 disp");
}
}
interface emp2
{
void disp();
}
// error:
// The default method disp() inherited from emp1 conflicts with another method
inherited from emp2
abstract class EmpImpl implements emp1,emp2 // error he don’t know which disp
is implement
{
}
public class Demo10
{
public static void main(String args[])
{
System.out.println("done");
}
}

Demo 11
//package trial;
interface emp1
{
default void disp()
{
System.out.println("in emp1 disp");
}
}
interface emp2
{
void disp();
}
abstract class EmpImpl implements emp1,emp2
{
public void disp()
{
System.out.println("inside EmpImp disp");
}
}
public class Demo11
{
public static void main(String args[])
{
System.out.println("done");
}
}

Demo 12:
package trial;
interface emp1
{
default void disp()
{
System.out.println("in emp1 disp");
}
}
interface emp2
{
void disp();
}
abstract class EmpImpl implements emp2
{
/*public void disp() // not required
{
}*/
}
public class Demo12
{
public static void main(String args[])
{
System.out.println("done");
}
}

Demo 13:
package trial;
interface A
{
default void fun()
{
System.out.println("A fun");
}
}
interface B
{
default void fun()
{
System.out.println("B fun");
}
}
class C implements A
{

}
// error:
//Duplicate default methods named fun with the parameters () and () are
inherited from the types A and B
class D extends C implements B // error
{

}
public class Demo13
{
public static void main(String args[])
{
D ob=new D();
ob.fun();
}
}

Demo 14:
package trial;
interface A
{
default void fun()
{
System.out.println("A fun");
}
}

interface B
{
default void fun()
{
System.out.println("B fun");
}
}

class C implements A
{

}
class D extends C implements B
{
public void fun()
{
System.out.println("D fun");
}
}
public class Demo14
{
public static void main(String args[])
{
D ob=new D();
ob.fun();
}
}

Demo 15:
package trial;
interface A
{
default void fun()
{
System.out.println("A fun");
}
}

interface B
{
default void fun()
{
System.out.println("B fun");
}
}

class C implements A
{
public void fun()
{
System.out.println("C fun"); //always class wins
}
}
class D extends C implements B
{
}
public class Demo15
{
public static void main(String args[])
{
D ob=new D();
ob.fun(); }}
Static method:

A static method is a method that's associated with the class in which it's defined, rather than with any
object created from that class. Every instance of the class shares the static methods of the class. Java 8
also lets static methods be defined in interfaces where they can assist default methods. For example,
the java.util.Comparator interface defines the following static method:

static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T>


keyExtractor)

As well as being directly invocable, comparingDouble() is invoked from this default method of
Comparator:

default Comparator<T> thenComparingDouble(ToDoubleFunction<? super


T> keyExtractor)

When you implement an interface that contains a static method, the static method is still part of the
interface and not part of the implementing class. For this reason, you cannot prefix the method with
the class name. Instead, you must prefix the method with the interface name, which I demonstrate in
Listing 3.

Listing 3 Z.java.

interface X
{
static void foo()
{
System.out.println("foo");
}
}

class Y implements X
{
}

public class Z
{
public static void main(String[] args)
{
X.foo(); //direct call like interfacename.method
// Y.foo(); // won't compile
}
}

Expression Y.foo() will not compile because foo() is a static member of interface X and not a
static member of class Y.

Compile Listing 3 as follows:

javac Z.java
Run the Z application as follows:

java Z

You should observe the following output:

foo

Before Java 8 made it possible to declare static methods in interfaces, it was common practice to place
these methods in companion utility classes. For example, the java.util.Collections class is a
companion to the java.util.Collection interface, and declares static methods that would be
more appropriate in the relevant Java Collections Framework interfaces.

For example, the Collections class declares a static <T> Collection<T>


synchronizedCollection(Collection<T> c) method that could be declared in the
Collection interface. Similarly, Collections declares a static <T> Set<T>
singleton(T o) method that would be a more appropriate member of the java.util.Set
interface. Instead of having to specify Collections.synchronizedCollection(...) and
Collections.singleton(...), you could specify
Collection.synchronizedCollection(...) and Set.singleton(...), and it
would be clear that these methods are returning a Collection and a Set, respectively.

Although these and similar changes will probably never be made to the Java Collections Framework
(too much legacy code depends on the current placement of such methods), you no longer need to
provide your own companion utility classes. Instead, you can place static methods in the appropriate
interfaces, which is a good habit to cultivate.

Imp about static method in java:

1. Interface static methods are part of interface, we can’t use it for implementation class objects.
2. Interface static methods are good for providing utility methods, for example null check,
collection sorting etc.
3. Interface static method helps us in providing security by not allowing implementation classes
to override them.
4. We can’t define static methods for Object class methods, we will get compiler error as “This
static method cannot hide the instance method from Object”. This is because it’s not allowed
in java, since Object is the base class for all the classes and we can’t have one class level
static method and another instance method with same signature.
5. We can use static interface methods to remove utility classes such as Collections and move all
of it’s static methods to the corresponding interface, that would be easy to find and use.

Info about static:

In addition to default methods, you can define static methods in interfaces. (A static method is a method that is
associated with the class in which it is defined rather than with any object. Every instance of the class shares its
static methods.) This makes it easier for you to organize helper methods in your libraries; you can keep static
methods specific to an interface in the same interface rather than in a separate class.

Like static methods in classes, you specify that a method definition in an interface is a static method with the
static keyword at the beginning of the method signature. All method declarations in an interface, including
static methods, are implicitly public, so you can omit the public modifier.
Background for static methods inside interface:

When collection API was designed there was a need to define utility methods or algorithms. Utilitiy methods or
algorithms are basically static methods. Entire collection API had only interfaces ( List, Set and Map ) at the top
level , static methods couldn’t be added inside these interfaces. This is because at that time static methods were
not allowed inside interfaces. So founders of Java had to define a separate class Collections and define all static
methods as utility methods or algorithms inside it.

In Java8 when interfaces were modified to add default methods , Java people decided to make one more change
and that is to allow static methods as well inside an interface so that in future if there is a need to define
algorithms or utility methods , they can be easily added inside an interface.

Demo1:

interface emp1
{
static void disp1()
{
System.out.println("in disp1 of emp1");
}
default void disp2()
{
System.out.println("in disp2 of emp1");
}
}
public class Demo1 implements emp1
{
void disp1()
{
emp1.disp1();
System.out.println("in disp1 of Demo1");
}
public void disp2() // must be public
{
emp1.super.disp2();
System.out.println("in disp2 of Demo1");
}
public static void main(String args[])
{
Demo1 d=new Demo1();
d.disp1();//class method call
d.disp2();
Emp.disp1()//to call disp1 of emp
}
}

Demo2:

interface emp1
{
static void disp1()
{
System.out.println("in disp1 of emp1");
}
default void disp2()
{
System.out.println("in disp2 of emp1");
}
}
interface emp2 extends emp1
{
/*static void disp1()
{
System.out.println("in disp1 of emp2");
}*/
}
public class Demo2 implements emp1
{
/*void disp1()
{
emp1.disp1();
System.out.println("in disp1 of Demo2");
}*/
public void disp2() // must be public
{
emp1.super.disp2();
System.out.println("in disp2 of Demo2");
}
public static void main(String args[])
{
Demo2 d=new Demo2();
// d.disp1(); error //static disp1 so not call
emp1.disp1();
d.disp2();
// emp2.disp1(); error bcoz not static
}
}

Demo 2_a:

//static interface methods can be accessed only with the help of same
interface in which they are declared.

interface emp1
{
static void disp1()
{
System.out.println("in disp1 of emp1");
}
default void disp2()
{
System.out.println("in disp2 of emp1");
}
}
interface emp2 extends emp1
{
static void disp1()
{
System.out.println("in disp1 of emp2");
}
}
public class Demo2_a implements emp1
{
void disp1()
{
emp1.disp1();
System.out.println("in disp1 of Demo2");
}
public void disp2() // must be public
{
emp1.super.disp2();
System.out.println("in disp2 of Demo2");
}
public static void main(String args[])
{
Demo2_a d=new Demo2_a();
d.disp1();
emp1.disp1();
d.disp2();
emp2.disp1();
}
}

Scoket:
To connect to another machine, we need a socket connection. By the way, what's a connection? A relationship between two
machines, where two pieces of software know about each other. Those two pieces of software know how to communicate
with each other. In other words, they know how to send bits to each other.
A socket connection means the two machines have information about each other, including network location (IP
address) and TCP port.

A socket is a resource assigned to the server process.

There are several different types of socket that determine the structure of the transport layer. The most common types
are stream sockets and datagram sockets.

 Stream Sockets
Stream sockets provide reliable two-way communication similar to when we call someone on the phone. One side
initiates the connection to the other, and after the connection is established, either side can communicate to the
other.
In addition, there is immediate confirmation that what we said actually reached its destination.
Stream sockets use a Transmission Control Protocol (TCP), which exists on the transport layer of the Open
Systems Interconnection (OSI) model. The data is usually transmitted in packets. TCP is designed so that the
packets of data will arrive without errors and in sequence.
Webservers, mail servers, and their respective client applications all use TCP and stream socket to communicate.

 Datagram Sockets
Communicating with a datagram socket is more like mailing a letter than making a phone call. The connection
is one-way only and unreliable.
If we mail several letters, we can't be sure that they arrive in the same order, or even that they reached their
destination at all. Datagram sockets use User Datagram Protocol (UDP). Actually, it's not a real connection, just
a basic method for sending data from one point to another.
Datagram sockets and UDP are commonly used in networked games and streaming media.
Network layer=refer ppt for info
TCP

Transmission Control Protocol

It is similar to telephone service. i.e. when sender sends the message


he gets to know whether receiver received the message or not.

It is reliable. i.e. it gives guarantee that all the packets will be


delivered at the other end and that too in the order in which they are
delievered. However this reliability comes at the cost of performance.

UDP
User Datagram Protocol

it is similar to postal service where sender does not know whether


message is received by receiver or not.

it is not reliable as TCP. i.e. it does not give you guarantee of


delivery of packets. However it is faster than TCP.

UDP:
TCP:

Pass object over network:

Using serialization we pass object


Day 16:
NIO: nio also read and write also

Only stream(normal stream no nio used)

NIO Channels:
Channels are similar to Streams in traditional Java I/O API with the exceptions that they can provide
three modes: input, output or bi-directional.

Streams on the other hand, are uni-directional (you were either using InputStream or OutputStream).

Channels interact directly with buffers and the native IO source, that is, file, or socket.

Channel working:

for reading purpose

we read channel's data (file's data) into buffer


program converts buffer to String.

for writing purpose


program writes data into buffer
buffer is written to channel(file).

Channel wraps the file

uSing NIO
-buffer register is inside java application and it is fast so works faster.

Channels and nio channels are two different concept related to ip and
output concepts
Nio give implicitly provide demon thread so that thread works the task and
main thread work on other task
In previous channel no only main thread works

In Io only read only or write only ,but in nio we do multiple task at same
time

Asynchronus:
Pending
Path vs Paths and get
Path is an interface and Paths is a final class of java.nio.file API. Path has been introduced in JDK
7. The use of Path is to locate a file in file system. Path has flexibility to locate the file by proving
path in parts. Path provides file path attribute like file name, file system, parent name and root.
Paths are used to get Path instance by its static method. Path returns java.io.File when we call
Path.toFile().The instance of Path can be obtained by FileSystems and Paths class.

Create Path Instance by Paths

If we have a file located in the path as c:\temp\test.txt. We can get this path in many ways.

Path path = Paths.get("c:/temp/test.txt" );


Path path = Paths.get("c:/temp","test.txt" );
Path path = Paths.get("c:","temp/test.txt" );
Path path = Paths.get("c:","temp","test.txt");

This is because Paths.get(String first, String more...) can accept one or more than one argument.

public interface CompletionHandler<V,A>

A handler for consuming the result of an asynchronous I/O operation.

The asynchronous channels defined in this package allow a completion handler


to be specified to consume the result of an asynchronous operation.
The "completed()" method is invoked when the I/O operation completes
successfully.

The "failed()" method is invoked if the I/O operations fails.

You might also like