Java OOP Teaching Guidelines 2023
Java OOP Teaching Guidelines 2023
Duration: 112 hours (50 theory hours + 50 lab hours + 12 revision/practice hours)
Objective: To reinforce knowledge of Object Oriented Programming concepts using Core Java.
Text Book:
Core and Advanced Java Black Book / Dreamtech Press
References:
Java 8 Programming Black Book / Dreamtech Press
Core Java : Volume 1 - Fundamentals by Cay S. Horstmann / Prentice Hall
Core Java : Volume 2 - Advanced Features by Cay S. Horstmann / Prentice Hall
Programming in Java by Sachin Malhotra, Saurabh Choudhary / Oxford University Press
Java The Complete Reference by Herbert Schildt / McGraw Hill
Core Java 8 for Beginners by Sharanam Shah, Vaishali Shah / Shroff Publishers
Murach’s Java Programming by Joel Murach / Mike Murach
Object-Oriented Analysis and Design with applications by Grady Booch / Pearson
Session 4:
Lecture:
Static variables and methods
Accessing static variables and methods of different class
Introduction to reference data types
Reference variables and methods
Difference between reference data types and primitive data types
Difference between reference variable and static variable
Session 5:
Lecture:
Constructors, initializing reference variables using constructors.
Pass by value v/s pass by reference.
Re-assigning a reference variable.
Passing reference variable to method
Initializing reference variable of different class
Heap memory and stack memory
Lab 3 & 4:
Print default values of static & instance variables for different data types.
Build a class Employee which contains details about the employee and compile and run its
instance.
Build a class which has references to other classes. Instantiate these reference variables and
invoke instance methods.
Tutorial:
Understand role of stack and heap memory in method invocation and object creation.
Session 6:
Lecture:
Inheritance: single & multilevel
Inheritance: Hierarchical
Association, Aggregation and Composition
Polymorphism: Compile time and runtime polymorphism
Rules of overriding and overloading of methods
super and this keyword
Lab 5 & 6:
Create a class Employee and encapsulate the data members.
Create demo applications to illustrate different types of inheritance.
Session 7:
Lecture:
Upcasting &down casting of a reference variable
Abstract class and abstract methods
Interface (implementing multiple interfaces)
Session 8:
Lecture:
Final variables, final methods and final class
Functional interface
New interface features (Java 8 & 11)
Lambda Expression
Inner Class (Regular, Method local, Anonymous & static inner class)
Enum
Lab 7 & 8:
Create an Array of Employee class and initialize array elements with different employee objects.
Try to understand the no of objects on heap memory when any array is created.
Session 9:
Lecture:
Access modifiers (public, private, protected and default)
Packages and import statements.
Static imports
Constructor chaining (with and without packages)
Accessing protected variables and methods outside the package
Session 10:
Lecture:
Garbage collection in java
Requesting JVM to run garbage collection.
Different ways to make object eligible for garbage collection: (Nulling a reference variable, Re-
assigning a reference variable & island of isolation)
Finalize method.
Lab 9 & 10:
Create a demo application to understand the role of access modifiers.
Implement multilevel inheritance using different packages.
Access/invoke protected members/methods of a class outside the package.
Override finalize method to understand the behavior of JVM garbage collector.
Sessions 11 & 12:
Wrapper Classes and String Class
Lecture:
Wrapper classes and constant pools
String class, StringBuffer& StringBuilder class
String pool
Lab 11 & 12:
Create sample classes to understand boxing & unboxing.
Use different methods of java defined wrapper classes.
Create StringDemo class and perform different string manipulation methods.
Tutorial:
Session 15:
[Link] & [Link] Package
Lecture:
Brief introduction to InputStream, OutputStream, Reader and Writer interfaces
NIO package
Serialization and de-serialization
Shallow copy and deep copy
Session 16:
Lecture:
Object Class & [Link] Package
Date, DateTime, Calendar class
Converting Date to String and String to Date using SimpleDateFormat class
Object Class: Overriding to String, equals &hashcodemethod
Lab 15 & 16:
Create a Demo class to Read & write image/text files.
Create SerializationDemo class to illustrate serialization and de-serialization process.
Create a demo class for Date, Time and Calendar
Collections
Sessions 17, 18 & 19:
Lecture:
Introduction to collections: Collection hierarchy
List, Queue, Set and Map Collections
List Collection:
o ArrayList, LinkedList
o Vector (insert, delete, search, sort, iterate, replace operations)
Collections class
Comparable and Comparator interfaces
Queue collection
Labs 17, 18 & 19:
Create DateManipulator class to convert String to date, date to String and to find out number of
days between two dates.
Create a list of java defined wrapper classes and perform insert/delete/search/iterate/sort
operations.
Create a collection of Employee class and sort objects using comparable and comparator
interfaces.
Implement Queue data structure using LinkedList and Queue collection.
Session 22:
Lecture:
MultiThreading : Thread class and Runnable Interface
sleep, join, yield, setPriority, getPrioritymethods.
ThreadGroup class
Lab 22:
Create multiple threads using Thread class and Runnable interfaces.
Assign same task and different task to multiple threads.
Understand sleep, join, yield methods.
Sessions 23 & 24:
Lecture:
Synchronization
Deadlock
Wait, notify and notifyAllmethods.
Producer & Consumer problem
Lab 23 & 24:
Create a Deadlock class to demonstrate deadlock in multithreading environment.
Implement wait, notify and notifyAll methods.
Demonstrate how to share threadlocal data between multiple threads.
section .data
msg db 'Hello World!!',0
section .text
global _start
_start:
; Write the string to stdout
mov eax, 4 ; System call for "write"
mov ebx, 1 ; File descriptor for stdout
mov ecx, msg ; Pointer to the message
mov edx, 13 ; Length of the message
int 0x80 ; Call the kernel
• Reference: [Link]
Application Programming Interface
Day 2
Java Documentation
Contents of package
Sub package
Interface
Nested Type
Constant Fields
Abstract Methods
Default Methods
Static Interface Methods
Class
Nested Types( Interface / Class / Enum )
Fields
Constructor
Method
Enum
Exception
Error
Annotation Type
Modifiers in Java
PUBLIC
PRIVATE
PROTECTED
STATIC
FINAL
SYNCHRONIZED
VOLATILE
TRANSIENT
NATIVE
INTERFACE
ABSTRACT
STRICT
Reference: [Link]
Access Modifiers
Modifiers which are used to control visibility of members of the class is called access modifier.
Access modifiers
private
Package level private( also called as default )
protected
public
More about main method
In java, main method is considered as entry point method.
With the help of main thread, JVM invoke main method.
Syntax:
public static void main(String args[] )
public static void main(String[] args )
public static void main(String... args )
We can define main method inside class as well as interface.
class Program{
public static void main(String[] args ) {
[Link]("Hello World!!!");
}
}
interface Program{
public static void main(String[] args ) {
[Link]("Hello World!!!");
}
}
Reference: [Link]
Java Comments
To maintain documentation of source code we should use comments:
Types of comments:
Implementation Comments
Block comments / multiline comments
class Program{
/* public static void main(String args[] ) {
[Link]("Hello World!!!");
} */
public static void main(String[] args ) {
[Link]("Hello World!!!");
}
}
class Program{
public static void main(String[] args ) {
//[Link]("Hello World!!!");
[Link]("Good Morning");
}
}
/**
Author is Sandeep Kulange
*/
class Program{
/**
Entry point method of class Program
*/
public static void main(String[] args ) {
[Link]("Hello World!!!");
}
}
Reference: [Link]
Java OOPS concepts
Consider following code:
class Test{
//Fields
private int num1; //Instance variable
private static int num2; //Class level variable
//Methods
public void setNum1( int num1 ){ //Instance method
this.num1 = num1;
}
public static void setNum2( int num2 ){ //Class level method
this.num2 = num2;
}
}
In Java, to access static members ( class level members ) of the class, we must use class name and
dot operator.
To access non static members( instance members ) of the class, we must use instance of the class.
class Program{
public static void main(String[] args) {
[Link]("Hello World!!");
}
}
A class from which we can not create child / sub class is called as final class.
We can instantiate final class.
Example:
[Link]
[Link]
If method in parent /super class is final then we can not redefine / override that method in child / sub
class.
What is [Link]?
package [Link];
public final class System {
//Fields
public final static InputStream in = null;
package [Link];
public class PrintStream extends FilterOutputStream implements
Appendable, Closeable{
class Program{
public static void main1(String[] args ) {
[Link]("Hello ");
[Link](" World");
[Link]("!!");
}
}
[Link] method print output on console but it moves cursor to the next line.
class Program{
public static void main(String[] args ) {
[Link]("Hello ");
[Link](" World");
[Link]("!!");
}
}
Data Types
Data type of any variable describe following things:
( Memory ) How much memory is required to store the data.
( Nature ) Which type of data is allowed to store inside allocated memory.
( Range ) How much data is allowed to store inside allocated memory.
( Operation ) Which operations are allowed to perform / execute on the data stored inside
memory.
Types of data type
Primitive data type
Variable of primitive data type contains value. Hence primitive type is also called as value
type.
There are 8 primitive / value types in Java:
boolean
byte
char
short
int
float
double
long
Non Primitive data type
Variable of non primitive data type contains reference of the instance. Hence non
primitive type is also called as reference type.
There are 4 non primitive / reference types in Java
Interface
Class
Enum
Array
If we declare variable inside method then it is called as method local variable.
In Java, we can not declare method local variable static.
class Program {
public static void main(String[] args) {
int number; //Non Static Method Local Variable //OK
}
}
class Program {
public static void main(String[] args) {
int number; //Non Static Method Local Variable
[Link]( number ); //error: variable number might not
have been initialized
}
}
If we want to use any method local variable( primitive / non primive ) then we must store some value
inside it.
class Program {
public static void main(String[] args) {
int number = 10; //Initialization
[Link]( number ); //OK
}
}
class Program {
public static void main(String[] args) {
int number;
number = 10; //Assignment
[Link]( number ); //OK
}
}
Reference: [Link]
Wrapper classes
In Java, primitive types are not classes. But Sun/Oracle developers has written classes for it. Such
classes are called as Wrapper classes.
All the Wrapper classes are final and declared in [Link] package.
Class Hierarchy
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Initialization
Process of storing value inside variable during its declaration is called initialization.
If the string does not contain a parsable numeric value then parseXXX() method throws
NumberFormatException. Reference:
[Link]
Commandline arguments
Consider code in C language
int sum( int num1, int num2 ){ //num1, num2 <= Function parameters
int result = num1 + num2;
return result;
}
int main( void ){
int result = sum( 10, 20 ); //10, 20 <= Function arguments
return 0;
}
class Program {
//args is a method parameter
public static void main(String[] args) {
[Link]("Hello,"+args[ 0 ]);
}
}
class Program {
public static void main(String[] args) {
int num1 = [Link](args[ 0 ]);
float num2 = [Link](args[ 1 ]) ;
double num3 = [Link](args[ 2 ]) ;
double result = num1 + num2 + num3;
[Link]("Result : "+result);
}
public static void main1(String[] args) {
int num1 = [Link](args[ 0 ]);
int num2 = [Link](args[ 1 ]) ;
int result = num1 + num2;
[Link]("Result : "+result);
}
}
Day 3
Stream
It is an abstraction( object /instance ) which is used to produce( write ) or consume( read )
information from source to destination.
Console = Keyboard + Monitor
Keyboard => Console Input
Monitor => Console Output
class Program{
public static void main( String[] args ){
[Link] sc = null; //reference
sc = new [Link]( [Link] ); //Instance
}
}
class Program{
public static void main( String[] args ){
[Link] sc = new [Link]( [Link] );
//Instance
}
}
import [Link];
class Program{
public static void main( String[] args ){
Scanner sc = new Scanner( [Link] ); //Instance
}
}
import [Link];
class Program {
public static void main(String[] args) {
Scanner sc = new Scanner( [Link] );
[Link]("Name : ");
String name = [Link]();
[Link]("Empid : ");
int empid = [Link]();
[Link]("Salary : ");
float salary = [Link]();
Reference: [Link]
Java language Features / buzzwords / ( Sun Microsystems Marketing Keywords )
Simple
Object oriented
Architecture neutral
Portable
Robust
Multithreaded
Dynamic
Secure
High Performance
Distributed
What is the meaning of Deprecated?
In Java, the term "Deprecated" is used to indicate that a particular method, class, or interface should
no longer be used because it is either obsolete, flawed, or has been replaced by a better alternative.
Instance creation in Java
In Java, we can create instance using 3 ways:
Using new operator
Using factory method
Using reflection
Manipulating system date and time using Date, Calendar, LocalDate, LocalTime, LocalDateTime
System Date using [Link] class
import [Link];
class Program {
public static void main(String[] args) {
Date date = new Date();
int day = [Link]();
int month = [Link]() + 1;
int year = [Link]() + 1900;
[Link](day+" / "+month+" / "+year);
}
}
The Calendar class should be used to convert between dates and time fields and the DateFormat
class should be used to format and parse date strings. The corresponding methods in Date are
deprecated.
Calendar is abstract class declared in [Link] package.
LocalDate ld = [Link]();
import [Link];
class Program {
public static void main(String[] args) {
LocalDate ld = [Link]();
int day = [Link]();
int month = [Link]();
int year = [Link]();
[Link](day+" / "+month+" / "+year);
}
}
LocalTime lt = [Link]();
import [Link];
import [Link];
class Program {
public static void main(String[] args)throws Exception {
String pattern = "dd/MM/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat( pattern);
String source = "23/07/1983";
Date date = [Link]( source );
import [Link];
import [Link];
class Program {
public static void main(String[] args) {
Date date = new Date( );
//SimpleDateFormat sdf = new SimpleDateFormat( "dd-MM-yyyy");
//SimpleDateFormat sdf = new SimpleDateFormat( "dd/MMM/yyyy");
SimpleDateFormat sdf = new SimpleDateFormat( "dd/MMMM/yyyy");
String strDate = [Link](date);
[Link]( strDate );
}
}
Reference: [Link]
Phases of software development life cycle
Requirement
Analysis
Design
Coding / implementation
Testing
Deployment / installation
mentainance
Procedure orineted programming language
Write a program to accept, strore and print information of employeee
name : char[ 30 ]
empid : int
salary : float
A programming methodology in which we can solve real world problems using structure and global
function.
Object oriented programming in C++
//File Name: [Link]
#include<stdio.h>
class Employee{
private:
char name[ 30 ];
int empid;
float salary;
public:
void acceept_record( /* struct Employee *this */ ){
printf("Name : ");
scanf("%s", this->name);
printf("Empid : ");
scanf("%d", &this->empid);
printf("Salary : ");
scanf("%f", &this->salary);
}
void print_record( /* struct Employee *this */ ){
printf("%-30s%-5d%-10.2f\n", this->name, this->empid, this->salary);
}
};
int main( void ){
Employee emp;
emp.accept_record( ); //emp.accept_record( &emp );
emp.print_record( ); //emp.print_record( &emp );
return 0;
}
A programming methodology, in which we can solve real world problem using class and object is
called object oriented programming.
Object oriented programming in Java
Write a program to strore and print date information.
day : int
month : int
year : int
Analyze problem statement and define the class.
class Date{
//TODO
}
Analyze the problem statement, decide and declare field inside class.
Variable declare inside class / class scope is called as field.
Variable declare inside method / method scope is called as method local variable.
class Date{
//Fields
int day;
int month;
int year;
}
To store values, create instance of the class.
Process of creating instance of a class is called as instantiation.
A class from which we can create instance is called as concrete class. In other words, we can
instantiate concrete class.
In Java, to create instance, we should use new operator.
If we use new operator to allocate memory then it gets space of heap memory area.
new Date();
new Date();
new Date();
After instantiation, if we want to process( accept/print/get/set) state of the instance then we should
call method on instance.
• Object oriented
Ø This feature helps to break complex code into easy to understand classes.
Ø It also helps to manage high complexity programs in distributed team environment.
• Memory management
Ø In traditional programming language like C, C++ user has to manage memory by allocating and deallocating memory
which leads to memory leaks in the program.
Ø In Java, memory management is taken care by the Java Virtual Machine and safe from memory crashes. All the
allocation and deallocation of the memory is done automatically.
• Exception Handling
Ø In Java, developers are forced to handle the exception during the development time. All the possible exception are
errored out during the compilation of the program. This way when the exception occurs during runtime, there is proper
exception handling mechanism already coded in the program.
Multithreaded
• If we start execution of Java application then Java Virtual Machine start execution of main thread and
garbage collector.
• Main Thread
1. It is a user thread( also called as non daemon thread ).
2. It is responsible for invoking main method.
3. Its priority in Java is 5( It means Thread.NORM_PRIORITY )
• Garbage Collector( Also called as finalizer )
1. It is a daemon thread( also called as background thread )
2. It is responsible for deallocating memory of unused objects.
3. Its priority in Java is 8( It means Thread.NORM_PRIORITY + 3 )
• Due to main thread and garbage collector, every Java application is multithreaded.
Multithreaded
• The Java platform supports multithreading at the language level.
Multithreaded
• If we want to utilize hardware resources concurrently and efficiently then we should use thread.
• Thread is non Java resource. In other words it is operating system resource.
• Java Native Interface( JNI ) is a Java language feature, which allows us to use operating system
thread into Java program.
• Sun/Oracle came with Thread class and other frameworks, which implicitly use JNI and reduces
developers effort. Now Instead of thinking about OS thread ,JNI and multitasking solution, Java
application developer can think about logic only.
• Java’s libraries are also thread safe.
Secure
• Java technology is designed to operate in distributed environments, which means that security is of
paramount importance.
• When Java applications are executed they don’t instruct commands to the machine directly. Instead
Java Virtual machine reads the program and convert it into the machine instructions. This way any
program tries to get illegal access to the system will not be allowed by the JVM.
• Allowing Java application to be executed by the JVM makes Java application fully secured.
• Java security technology includes a large set of APIs, tools, and implementations of commonly used
security algorithms, mechanisms, and protocols. The Java security APIs span a wide range of areas,
including cryptography, public key infrastructure, secure communication, authentication, and access
control.
Dynamic
• In java, except constructor and non static method, all the methods are by default virtual.
• It was designed to adapt to an evolving environment( Operating System and Hardware).
• While the Java Compiler is strict in its compile-time static checking, the language and run-time
system are dynamic in their linking stages. Classes are linked only as needed.
• Libraries can freely add new methods and instance variables without any effect on their clients.
• In Java, finding out runtime type information is straightforward.
High Performance
• Performance of Java application is slower then C/C++ application.
• The Java platform achieves superior performance by adopting a scheme by which the interpreter can
run at full speed without needing to check the run-time environment. The automatic garbage
collector runs as a low-priority background thread, ensuring a high probability that memory is
available when required, leading to better performance.
• Applications requiring large amounts of compute power can be designed such that compute-
intensive sections can be rewritten in native machine code as required and interfaced with the Java
platform.
• In general, users perceive that interactive applications respond quickly even though they're
interpreted.
Distributed
Distributed
• A distributed application consists of one or more local or remote clients that communicate with one or
more servers on several machines linked through a network. With this type of application, business
operations can be conducted from any geographical location.
• Remote Method Invocation (RMI) is a Java language feature.
• RMI system allows an object running in one Java virtual machine to invoke methods on an object
running in another Java virtual machine.
• Due to RMI Java is considered as distributed.
Questions?
Day 4
How to find size of instance in Java?
Reference: [Link]
Object oriented programming in Java
Write a program to strore and print date information.
day : int
month : int
year : int
Analyze problem statement and define the class.
class Date{
//TODO
}
Analyze the problem statement, decide and declare field inside class.
Variable declare inside class / class scope is called as field.
Variable declare inside method / method scope is called as method local variable.
class Date{
//Fields
int day;
int month;
int year;
}
new Date();
new Date();
new Date();
After instantiation, if we want to process( accept/print/get/set) state of the instance then we should
call method on instance.
String s1 = "";
String s2 = "Sandeep Kulange";
//"Sandeep Kulange" => String literal / literal
To access instance members of the class inside method, use of this keyword is optional.
void acceptRecord( /*Employee this*/ ){
Scanner sc = new Scanner([Link]);
[Link]("Name : ");
name = [Link](); //OK
[Link]("Empid : ");
empid = [Link](); //Ok
[Link]("Salary : ");
salary = [Link](); //OK
}
Definition:
this reference is implicit reference variable which is available in every non static method /
instance method of class which is used to store reference of current / calling instance.
Consider code in C
In C/C++, if name of local & global variable is same then preference is always given to the local
variable.
Consider code in java:
class Date{
int day, month, year;
void setDay( /* Date this,*/int day ){
//day = day; //Assignment to self
[Link] = day;
}
}
class Program{
public static void main(String[] args) {
Date date = new Date( );
[Link]( 23 ); //[Link]( date, 23 );
}
}
If name of method local variable / method paramater and name of field is same then preference is
always given to the local variable. In this case, If we want to give preference to field then we should
use this referene before field. For the reference consider above code.
Static method do not get this reference.
enum ShapeType{
LINE, RECTANGLE, CIRLE, TRIANGLE
}
Characteristics of instance
State
Value stored inside instance is called as state of that instance.
Value stored inside field represents state of the instance.
Behavior
Number / set of operations( behaviors/methods) which are allowed to perform/call on instance
represents behavior of the instance.
Methods defined inside class represents behavior of the instance.
Identity
Value of any field which is used to indentify instance uniquely is called its identity.
Reference:
[Link]
[Link]
What is class and instance?
Class
Definition:
Class is a collection of fields and methods.
Structure and behavior of the instance depends on class hence class is considered as a
template model or blueprint for an insrance.
Class represents set of instances which is having common structure and common behavior.
Example: Car, Book, Laptop, Mobile Phone etc.
Class is imaginary / logical entity.
Class implementation represents encapsulation.
Reference:
[Link]
[Link]
Instance
Definition:
An entity which is having physical existance is called as instance.
In C++, physical entity is called as object and in Java it is called instance.
An entity which is having state, behavior and identity is called as instance.
Example: Tata Nano, "Java Certification-Khalid Mughal", "MacBook Air", "iPhone-14"
Process of creating instance is called as instantiation.
By creating instance we are achieving abstraction.
null literal and NullPointerException
#define NULL ((void*)0) //C
#define NULL 0 //C++
If reference contains, null value then reference variable is called as null reference variable / null
object.
Consider following code:
class Program{
public static void main(String[] args) {
Employee emp;
[Link](); // error: variable emp might not have been
initialized
[Link]();
}
}
Solution:
class Program{
public static void main(String[] args) {
Employee emp = null; //emp is null object
[Link](); //[Link]
[Link]();
}
}
Using null object, if we try to access any instance member of the class then JVM throws
NullPointerException.
Reference: [Link]
Difference between value type and reference types
Reference: [Link]
Value type
Primitive type is also called as value type.
There are 8 value/primitive types in java.
boolean, byte, char, short, int, float, double, long
Variable of value type contains value.
class Date{
int day; //0
int month; //0
int year; //0
}
Variable of value type get space on Java stack( by considering it as method local variable ).
Reference type
Not primitive type is also called as reference type.
There are 4 reference/non primitive types in java.
interface, class, enum, array
Variable of reference type contains reference.
class Employee{
String name; //null
Date joinDate; //null
}
class Program {
static void sum( int num1, int num2 ){ // 2 method parameters
int result = num1 + num2;
[Link]("Result : "+result);
}
static void sum( int num1, int num2, int num3 ){ // 3 method
parameters
int result = num1 + num2 + num3;
[Link]("Result : "+result);
}
public static void main(String[] args) {
[Link]( 10, 20 );
[Link]( 10, 20, 30 );
}
}
If we want to give same name to methods and if number of parameters passed to the method
are same then type of at least one parameter must be different.
class Program {
static void sum( int num1, int num2 ){ // 2 method parameters
int result = num1 + num2;
[Link]("Result : "+result);
}
static void sum( int num1, double num2 ){ // 2 method
parameters
double result = num1 + num2;
[Link]("Result : "+result);
}
public static void main(String[] args) {
[Link]( 10, 20 );
[Link]( 10, 20.5 );
}
}
If we want to give same name to the methods and if number of parameters passed to the
method are same then order of type of parameters must be different.
class Program {
static void sum( int num1, float num2 ){ // 2 method
parameters
float result = num1 + num2;
[Link]("Result : "+result);
}
static void sum( float num1, int num2 ){ // 2 method
parameters
float result = num1 + num2;
[Link]("Result : "+result);
}
public static void main(String[] args) {
[Link]( 10, 20.2f );
[Link]( 10.1f, 20 );
}
}
Only on the basis of different return type, we can not give same name to methods.
class Program {
static void sum( int num1, int num2 ){ // 2 method
parameters
int result = num1 + num2;
[Link]("Result : "+result);
}
static int sum( int num1, int num2 ){ // 2 method parameters
int result = num1 + num2;
return result;
}
public static void main(String[] args) {
[Link]( 10, 20 );
[Link]( 10, 20 );
}
}
When we define multiple methods with same name using above rules then it is called as method
overloading.
In other words, process of defining methods with same name and different signature is called as
method overloading.
Methods, which are taking part in method overloading are called as overloaded methods.
If implementation of methods are functionally equivalilent / same then we should overload method i.e.
we should give same name to the methods.
Return type is not considered in method overloading.
return value from method as well as catching value from method is optional hence return type
is not considered in method overloading.
Constructor
Constructor chaining
Instance initialization block
Need of getter and setter methods
Day 5
Coding conventions:
Camel Case
Camel case is a naming convention in which the first letter of each word in a compound word is
capitalized, except for the first word.
Example: showInputDialog
Pascal Case
Pascal case is a naming convention in which the first letter of each word in a compound word is
capitalized.
Example: ArrayIndexOutOfBoundsException
Snake Case
Snake case combines words by replacing each space with an underscore (_).
Example:MAX_VALUE
Kebab Case
Kebab case is the way to write compound words separated by hyphens (-) instead of using
space. Generally, everything is written in lowercase.
Example: “what-is-kebab-case”
Declaration and Definition
According to Dennis Ritchie, declaration refers to the place where nature of the variable is stated but
no storage is allocated.
Initialization( Revision )
Process of providing value to the variable during its declaration is called as initialization.
class Date{
int day;
int month;
int year;
Date( ){ //Constructor
LocalDate ld = [Link]();
[Link] = [Link]();
[Link] = [Link]();
[Link] = [Link]();
}
}
import [Link];
import [Link];
class Date{
int day;
int month;
int year;
Date( ){ //Constructor
[Link]("Inside constructor");
LocalDate ld = [Link]();
[Link] = [Link]();
[Link] = [Link]();
[Link] = [Link]();
}
}
class Program{
public static void main(String[] args) {
Date dt1 = new Date(); //Here constructor will call implicitly
//[Link]( ); //Not allowed
}
public static void main1(String[] args) {
//Date dt1 = null; //Here construcor will not be call
//new Date( ); //Here constructor will call on anonymous
instance
Date dt2 = new Date(); //Here constructor will call on only once
}
}
Reference: [Link]
Types of constructor
There are 3 types of constructor in Java:
Parameterless constructor
Parameterized constructor
Default constructor
Parameterless constructor
It is also called as zero argument constructor / programmer defined default constructor.
Consider example:
If we create instance without passing arguments( i.e. we are passing 0 arguments ) then
Parameterless constructor gets called.
Parameterized constructor
A constructor which take parameter is called as Parameterized constructor.
Consider example:
class Date{
int day;
int month;
int year;
Date( ){
[Link]("Inside parameterless constructor");
[Link] = 0;
[Link] = 0;
[Link] = 0;
}
Date( int day, int month, int year ){ //Constructor
[Link]("Inside parameterized constructor");
[Link] = day;
[Link] = month;
[Link] = year;
}
}
class Program{
public static void main(String[] args) {
Date dt1 = new Date( 23, 7, 1983 );
class Date{
int day;
int month;
int year;
}
class Program{
public static void main(String[] args) {
Date dt1 = new Date( ); //OK
//Here on instance, default constructor will call
}
}
class Date{
int day;
int month;
int year;
class Date{
int day;
int month;
int year;
Date( ){
//Explicit call to the construcor
this( 1, 4, 2023); //Constructor chaining
}
Date( int day, int month, int year ){
[Link] = day;
[Link] = month;
[Link] = year;
}
}
class Stack{
int top;
int[] arr;
Stack( ){
this( 5 ); //Constructor chaining
}
Stack( int size ){
[Link] = -1;
[Link] = new int[ size ];
}
}
Reference: [Link]
Stack
Data structure describes two things:
How to organize data in ram.
Which operations should be used to organise data inside RAM.
Types of data structure:
Linear / sequential data structure
Array, Stack, Queue, LinkedList etc.
Non Linear data structure
Tree, Graph, Hashtable etc.
Stack is a linear data structure in which we can manage elements in Last In First Out order( LIFO ).
We can perform following operations on Stack:
boolean empty( );
void push( int element );
int peek( );
boolean full( );
void pop();
Value stored inside data structure is called element.
Consider syntax of array:
class Stack{
int top;
int[] arr;
{//Instance initialization block
[Link] = -1;
}
Stack( ){
//[Link] = -1;
[Link] = new int[ 5 ];
}
Stack( int size ){
//[Link] = -1;
[Link] = new int[ size ];
}
}
Reference: [Link]
Access Modifier
In Java, parent class is called as super class and child class is called as sub class.
The modifiers, which are used to control visibility of the members of the class is called access
modifiers.
There are 4 access modifiers in Java:
private
package level private ( no modifier / default means --> package level private )
protected
public
Reference: [Link]
Need of Getter and Setter method
Process of declaraing fields of the class private is called as data hiding.
class Student{
//Data hiding
private String name;
private int rollNumber;
private float marks;
}
class Student{
private String name;
private int rollNumber;
private float marks;
public void setMarks( float marks ){
if( marks > 100 )
throw new IllegalArgumentException("Invalid marks.");
[Link] = marks;
}
//acceptRecord
}
class Program{
public static void main(String[] args) {
Student s1 = new Student();
[Link]( 101 );
}
}
Final modifier
Absolute path and relative path
Reference: [Link]
Path and classpath
Reference: [Link]
[Link] class
Reference: [Link]
Use below command on terminal to get more details:
javap [Link]
toString method
Day 6
class Employee{
//TODO : Fields
//TODO : Ctor
//TODO : Getters and Setters
}
class EmployeeTest{
/* Employee emp;
public EmployeeTest(){
emp = new Employee();
} */
private Employee emp = new Employee( );
//TODO: acceptRecord()
//TODO: printRecord()
}
class Program{
public static void main(String[] args) {
EmployeeTest test = new EmployeeTest( );
//TODO: accept and print
}
}
Final Modifier
Final method local variable
class Program{
public static void main(String[] args) {
int number = 10; //Initialization
number = number + 5;
[Link]("Number : "+number); //15
}
}
After storing value inside variable, if we dont want to modify its value then we should use final
modifier.
In java, we can declare local variable final.
class Program{
public static void main(String[] args) {
final int number = 10; //Initialization
number = number + 5; //error: cannot assign a value to final
variable number
[Link]("Number : "+number);
}
}
class Program{
public static void main(String[] args) {
final int number;
number = 10; //Assignment
//number = number + 5; //error: variable number might already
have been assigned
[Link]("Number : "+number); //10
}
}
class Program{
private static Scanner sc = new Scanner([Link]);
public static void main(String[] args) {
[Link]("Number : ");
final int number = [Link](); // //Initialization
//number = 20; //error: cannot assign a value to final variable
number
[Link]("Number : "+number); //10
}
}
We can provide value to final variable before compilation as well as after compilation.
Final field
We can declare fiel final.
After initialization, if we dont want to modify value of any field inside any method of the class
including constructor body then we should declare field final.
We must provide value to the final field either inside constructor body or at the time of declaration.
class Test{
//Field
private final int number; //NOT OK
}
class Test{
//Field
private final int number = 10; //OK
}
class Test{
//Field
private final int number;
public Test( ){
[Link] = 10; //OK
}
}
class Test{
//Field
private final int number = 10; //OK
public Test( ){
[Link] = 20; //Not OK
}
}
class Test{
private final int NUMBER = 10; //Field
public void showRecord( ){
//[Link] = [Link] + 1; //Not OK
[Link]("Number : "+[Link]);
}
public void printRecord( ){
//[Link] = [Link] + 1; //Not OK
[Link]("Number : "+[Link]);
}
}
class Program{
public static void main(String[] args) {
Test t = new Test();
[Link](); //10
[Link](); //10
[Link](); //10
}
}
We will discuss final method and final class in inheritance.
We can declare method final.
We can not redfine/override final method inside sub class.
We can declare class final.
We can not create sub class of final class.
What is the meaning of "final Complex c1 = new Complex( 10, 20);" statement?
class Complex{
private int real;
private int imag;
public Complex( ){
this( 0, 0);
}
public Complex( int real, int imag ){
[Link] = real;
[Link] = imag;
}
public int getReal() {
return [Link];
}
public void setReal(int real) {
[Link] = real;
}
public int getImag() {
return [Link];
}
public void setImag(int imag) {
[Link] = imag;
}
}
class Program{
public static void main(String[] args) {
final Complex c1 = new Complex( 10, 20);
[Link](100); //OK
[Link](200); //OK
[Link]("Real Number : "+[Link]()); //100
[Link]("Imag Number : "+[Link]()); //200
In Java, parent class is called as super class and child class is called as sub class.
Object is a concrete class declared in [Link] package.
[Link] do not extend any class or do not implement any interface. In other words, it is super
class of all the classes( not interfaces ) in core Java.
It is also called as ultimate base class / super cosmic base class / root of java class hierarchy.
There are 11 methods( 5 non final( 2 native + 3 non native ) + 6 final methods( 4 native + 2 non native
methods)) in [Link] class.
Use following command to check signature of methods:
javap [Link]
5 Non final methods of [Link] class( we can override these methods inside sub class
)
public String toString( );
public boolean equals( Object obj );
public native int hashCode( );
protected native Object clone( )throws CloneNotSupportedException
protected void finalize( )throws Throwable
6 Final methods of [Link] class
public final native Class<?> getClass()
public final void wait( ) throws InterruptedException
public final native void wait( long timeout ) throws InterruptedException
public final void wait( long timeout, int nanos ) throws InterruptedException
public final native void notify();
public final native void notifyAll();
Overriding toString method
toString is a non final method of [Link] class
public String toString( );
If we want to return state of the instance in String form then we should use toString method.
If we do not define toString() method inside class then super class's toString method will call. If any
super class do not contain toString() method then Object class's toString() method will call.
Consider definition of toString method from [Link] class:
Hashcode is not an address / reference of the instance. It is a logical integer number which can
be generated by processing state of the instance.
According to client's requirement, If implementation of super class method is partially complete the
we should redefine/override method inside sub class.
If we dont want hashCode then we should override toString() method inside sub class.
The result in toString() method should be a concise but informative that is easy for a person to read.
Static Field
If we create instance of the class then all the fields get space inside instance.
class Test{
private int num1;
private int num2;
private int num3;
public Test( int num1, int num2 ){
this.num1 = num1;
this.num2 = num2;
this.num3 = 500;
}
}
class Program {
public static void main(String[] args) {
Test t1 = new Test( 10, 20 ); //10,20,500
Test t2 = new Test( 30, 40 ); //30,40,500
Test t3 = new Test( 50, 60 ); //50,60,500
}
}
If we want to share, value of any field inside all the instances of same class then we should declare
field static.
A field of the class, which get space inside instance is called as instance variable. In other words, only
non static field get space inside instance. Hence non static field is also called as instance variable.
Instance variable get space once per instance on heap memory.
To use instance variable we must use object reference.
A field of the class which do not get space inside instance is called as class level variable. In other
words, static fields do not get space inside instance. Hence static field is also called as class level
variable.
Class level variable get space during class loading once per class on method area.
To access class level variable we should use class name and dot operator.
class X{
private int num1;
private int num2;
private static int count = 500;
}
X x1 = new X(10,20); //10,20, 500
X x2 = new X(30,40);//30,40,500
X x3 = new X(50,60);//50,60,500
class Y{
private int num3;
private int num4;
private static int count = 600;
}
Y y1 = new Y(11,12); //11,12,600
Y y2 = new Y(13,14); //13,14,600
Y y3 = new Y(15,16); //15,16,600
class Z{
private int num5;
private int num6;
private static int count = 700;
}
Z z1 = new Z(21,22); //21,22,700
Z z2 = new Z(23,24); //23,24,700
Z z3 = new Z(25,26); //25,26,700
class Test{
private int num1;
private int num2;
private static int num3;
class Test{
private int num1;
private int num2;
private static int num3;
class Program{
public int num1 = 10;
public static int num2 = 20;
public static void main(String[] args) {
//[Link]( num1 ); //Not OK
Program p = new Program();
[Link]( p.num1 );
[Link]( num2 ); //OK
}
}
Using instance, we can access non static members inside static method.
Count instances of the class
Singleton class
Day 7
static method
Inside method, if there is need to use this reference then method should be non static otherwise
method should be static.
class Program{
/* public double power( double base, int index ){
double result = 1;
for( int count = 1; count <= index; ++ count )
result = result * base;
return result;
} */
public static double power( double base, int index ){
double result = 1;
for( int count = 1; count <= index; ++ count )
result = result * base;
return result;
}
public static void main(String[] args) {
//Program p = new Program();
//double result = [Link](2, 3);
If constructor is public then we can create instance of the class inside method of same class as well
as method of different class.
class Complex{
private int real;
private int imag;
public Complex( ){
[Link]("Inside constructor.");
[Link] = 10;
[Link] = 20;
}
public static void test( ){
Complex c2 = new Complex(); //OK
}
}
class Program{
public static void main(String[] args) {
Complex c1 = new Complex(); //OK
[Link]();
}
}
class Complex{
private int real;
private int imag;
private Complex( ){
[Link]("Inside constructor.");
[Link] = 10;
[Link] = 20;
}
public static void test( ){
Complex c2 = new Complex(); //OK
}
}
class Program{
public static void main(String[] args) {
//Complex c1 = new Complex(); //NOT OK
[Link]();
}
}
Instance Counter
class InstanceCounter{
private static int count;
public InstanceCounter( ){
[Link] = [Link] + 1;
}
public static int getCount() {
return [Link];
}
}
class Program{
public static void main(String[] args) {
InstanceCounter c1 = new InstanceCounter();
InstanceCounter c2 = new InstanceCounter();
[Link]("Instance Count : "+[Link]());
}
}
In Java, we can declate local variable final but we can not declare it static.
Static variable is also called as class level variable. According to oops, class level variable should be
declared inside class scope. Hence we can not declare local variable static. But we can declare field
static.
class Program{
private static int count = 0;
public static void printRecord( ){
count = count + 1;
[Link]("Count : "+count);
}
public static void main(String[] args) {
[Link](); //1
[Link](); //2
[Link](); //3
}
}
Design pattern
Reusable solution which is used to solve common problems during development is called as design
pattern.
Creational
Abstract factory
Builder
Factory method
Prototype
Singleton
Structural
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Behavioral
Chain of responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State
Strategy
Template method
Visitor
Singleton class
A class from which we can create only one instance is called as singleton class.
Method 1:
class Singleton{
private Singleton( ){
//TODO
}
private static Singleton reference;
public static Singleton getReference( ){
if( reference == null )
reference = new Singleton( );
return reference;
}
}
class Program{
public static void main(String[] args) {
Singleton s1 = [Link]();
Singleton s2 = [Link]();
}
}
Method 2
class Singleton{
private int num1;
private int num2;
private static Singleton reference;
static{
reference = new Singleton();
}
public static Singleton getReference() {
return reference;
}
private Singleton( ){
this.num1 = 10;
this.num2 = 20;
}
}
class Program{
public static void main(String[] args) {
Singleton s1 = [Link]();
Singleton s2 = [Link]();
}
}
Package
It is a Java language feature which is used:
To avoid name clashing/collision/ambiguity/conflict
[Link]
[Link]
[Link]
//java : main package
//lang : sub package
//Object : Type name( interface, class....etc)
In Java
class Complex{
//TODO: Member declaration
};
package p1; //Not OK
If we do not define any class inside package then it is considered as a member of default
package.
class Complex{
//TODO: Member declaration
};
Java compiler maps pakage name with the folder.
If we want to use any type(class/interface) in different package then
Either we should use import statement
Or fully qualified type name
Consider following code:
If we do not specify access modifier then default modifier of class is always package level private.
If access modifier of type is package level private then we can not access it outside the package.
If we want to use any type outside the package then type must be public.
According to Java Language Specification(JLS), name of the public class and name of the .java file
must be same.
Since name of the public class and name of the .java file must be same, we can not define multiple
public classes in single .java file.
We can not declare class private or protected. In other words, access modifier of a class can be
either package level private or public only.
Demo 1
Consider code in [Link]
import [Link];
class Program{
public static void main(String[] args) {
//[Link] c1 = new [Link]();
Complex c1 = new Complex();
[Link]( [Link]());
}
}
Compile [Link]
set classpath=.\bin;
javac -d .\bin .\src\[Link]
java Program
Conclusion: we can access packaged class inside unpackaged class.
Demo 2
Consider [Link]
Compile [Link]
Consider [Link]
package p1;
class Program{
public static void main(String[] args) {
Complex c1 = new Complex();
[Link]( [Link]());
}
}
Compile [Link]
set classpath=.\bin;
javac -d .\bin .\src\[Link] //error: cannot find symbol Complex
If we define any class without package then it is considered as a member of default package.
Conclusion: Since we can not import default package, It is impossible to use unpackged class inside
packaged class.
Demo 3
Consider [Link]
package p1;
public class Complex {
public String toString() {
return "[Link]( )";
}
}
Compile [Link]
Consider [Link]
package p2;
import [Link];
class Program{
public static void main(String[] args) {
Complex c1 = new Complex();
[Link]( [Link]());
}
}
Compile [Link]
set classpath=.\bin;
javac -d .\bin .\src\[Link]
java Program //Error: Could not find or load main class Program
java [Link] //OK
Demo 4
Consider [Link]
package p1;
public class Complex {
public String toString() {
return "[Link]( )";
}
}
Compile [Link]
package p1;
//import [Link]; //Optional
class Program{
public static void main(String[] args) {
Complex c1 = new Complex();
[Link]( [Link]());
}
}
Compile [Link]
set classpath=.\bin;
javac -d .\bin .\src\[Link]
java [Link]
Demo 5
Consider [Link]
package p1.p2;
public class Complex {
public String toString() {
return "[Link]( )";
}
}
Compile [Link]
Consider [Link]
package p1.p3;
import [Link];
class Program{
public static void main(String[] args) {
Complex c1 = new Complex();
[Link]( [Link]());
}
}
Compile [Link]
set classpath=.\bin;
javac -d .\bin .\src\[Link]
java [Link]
Without class name, if we want to access static members of the class then we should use static
import.
If we want to use any type( interface, class, enum, error, exception, annotation) outside package then
we should use import statement.
If we want to use static members of the class, without class outside class name, then we should use
static import.
naming conventions for package
[Link]
[Link]
[Link]
oracle. jdbc. driver.
[Link]
Reference: [Link]
Eclipse introduction
Day 8
Which are non primitive types in Java?
Interface
Class
Enum
Array
Array
How will you store 3 integer values in Java program?
First approach
Second approach
Instantiation of array
length is a property of array data structure which returns size/length of the array.
int[] arr3 = new int[ ]{ 10, 20, 30, 40, 50, 60, 70 }; //OK
[Link]( arr3 );
}
How will accept and print record of array
[Link]( arr );
[Link](arr);
}
}
Using illeagal index, if we try to access elements of array then JVM throws
ArrayIndexOutOfBoundsException.
package [Link];
import [Link];
import [Link];
class Date{
private int day;
private int month;
private int year;
public Date() {
LocalDate ld = [Link]();
[Link] = [Link]();
[Link] = [Link]();
[Link] = [Link]();
}
@Override
public String toString() {
return [Link]+" / "+[Link]+" / "+[Link];
}
}
public class Program {
public static void main(String[] args) {
Date[] arr = new Date[ 3 ]; //Array of references
[Link]( [Link](arr)); //[null, null,
null]
}
}
//int a = x;
//int b = y;
void swap( int a, int b ){
int temp = a;
a = b;
b = temp;
}
int main( void ){
int x = 10;
int y = 20;
//int *a = &x;
//int *b = &y;
void swap( int *a, int *b ){
int temp = *a;
*a = *b;
*b = temp;
}
int main( void ){
int x = 10;
int y = 20;
In Java, we can pass any argument( primitive / non primitive ) to the method by value only.
Consider code:
package [Link];
public class Program {
If we want to simulate pass by reference mechanisam then we should use array in Java.
Consider following code:
[Link]( arr );
x = arr[ 0 ];
y = arr[ 1 ];
import [Link];
public class Program {
private static Scanner sc = new Scanner([Link]);
public static void acceptRecord( int[] number ) {
[Link]("Enter number : ");
number[ 0 ] = [Link]();
}
private static void printRecord(int[] number) {
[Link]("Number : "+number[ 0 ]);
}
public static void main(String[] args) {
int[] number = new int[ 1 ];
[Link]( number );
[Link]( number );
}
}
Instantiation:
import [Link];
Reference declaration:
Instantiation
import [Link];
[Link]( 10, 20 );
[Link]( 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 );
}
}
Enum
If we want to improve readability of the source code then we should use enum in C/C++/java.
Consider code in C programming language:
#include<stdio.h>
enum ArithmeticOperation{
EXIT, SUM, SUB,MULTIPLICATION, DIVISION // Enum Constants
//EXIT = 0, SUM = 1, SUB = 2,MULTIPLICATION = 3, DIVISION = 4 //
Enum Constants
};
enum Day{
MON = 1, TUES = 2, WED = 3, THURS = 4, FRI = 5, SAT = 6, SUN = 7
}
enum Day{
MON( 1 ), TUES( 2 ), WED( 3), THURS ( 4 ), FRI( 5 ), SAT( 6 ),
SUN( 7 );
// 1,2,3,4,5,6,7 : Literals
//MON, TUES, WED, THURS, FRI, SAT, SUN : Name of enum constants
//0,1,2,3,4,5,6 : Ordinals
}
enum Color{
RED( 255,0,0), GREEN(0,255,0), BLUE(0,0,255)
//RED = 0, GREEN = 1, BLUE = 2
}
//(255,0,0),(0,255,0),(0,0,255)
//RED, GREEN, BLUE : Name of enum constants
//0,1,2 : Ordinals
enum Day{
MON( 1, "Monday"), SUN( 7, "SunDay");
}
//( 1, "Monday"), ( 7, "SunDay"); //Literals
//MON, SUN : Name of enum constants
//0, 1 : Ordinal values
Using enum, we can give name to the single literal as well group of literals of same type / different
type.
[Link] is considered as super class of all the enums in Core Java language.
enum Color{
}
Since enum is implicitly considered as final class, we can not extend enum. In other words we can not
create sub type of enum.
Consider code to demonstrate name()/ordinal() and values() method.
enum Color{
RED, GREEN, BLUE
}
public class Program {
public static void main(String[] args) {
Color[] colors = [Link]();
for( Color color : colors )
[Link]( [Link]()+" "+[Link]());
}
public static void main4(String[] args) {
Color color = [Link];
[Link]( [Link]()+" "+[Link]());
color = [Link];
[Link]( [Link]()+" "+[Link]());
color = [Link];
[Link]( [Link]()+" "+[Link]());
}
public static void main3(String[] args) {
[Link]( [Link]()); //BLUE
[Link]( [Link]()); //2
}
public static void main2(String[] args) {
[Link]( [Link]()); //GREEN
[Link]( [Link]()); //1
}
public static void main1(String[] args) {
[Link]( [Link]()); //RED
[Link]( [Link]()); //0
}
}
package [Link];
enum Day {
MON("Monday"), TUES("TuesDay"), WED("WednesDay");
enum Day {
MON(1), TUES(2), WED(3);
enum Day {
MON(1, "MonDay"), TUES(2,"TuesDay"), WED(3,"WednesDay");
[Link]([Link]());//1
[Link]([Link]()); //MonDay
}
}
Menu driven code using enum
package [Link];
import [Link];
import [Link];
enum ArithmeticOperation{
EXIT, SUM, SUB, MULTIPLICATION, DIVISION
}
class ArithmeticOperationTest{
public static int sum( int num1, int num2 ) {
return num1 + num2;
}
public static int sub( int num1, int num2 ) {
return num1 - num2;
}
public static int multiplication( int num1, int num2 ) {
return num1 * num2;
}
public static int division( int num1, int num2 ) {
return num1 / num2;
}
public static void printRecord( int result ) {
[Link]("Result : "+result);
}
private static Scanner sc = new Scanner([Link]);
public static ArithmeticOperation menuList( ) {
[Link]("[Link]");
[Link]("[Link]");
[Link]("[Link]");
[Link]("[Link]");
[Link]("[Link]");
[Link]("Enter choice : ");
int choice = [Link]();
return [Link]()[ choice ];
}
}
public class Program {
public static void main(String[] args) {
ArithmeticOperation choice;
while( ( choice = [Link]( ) ) !=
[Link] ) {
int result = 0;
switch( choice ) {
case SUM:
result = [Link](100, 20);
break;
case SUB:
result = [Link](100, 20);
break;
case MULTIPLICATION:
result = [Link](100, 20);
break;
case DIVISION:
result = [Link](100, 20);
break;
}
[Link](result);
}
}
}
OOPS
Object oriented programming structure/system
OOPS is not a syntax. It is a programming methodology which is used to solve real world problems
using classes and objects.
Dr Alan kay is inventor of OOPS.
Grady Booch is inventor of UML.
Author of "Object Oriented Analysis and Design with Applications"
According to Grady Booch there should be some major and minor features in the oops.
4 Major Elements / Features / Parts /Pillars
By major, we mean that a language without any one of these elements is not object oriented.
Abstraction - To achive simplicity
Encapsulation - To hide data and to achieve security
Modularity - To reduce module dependency
Hierarchy - To achieve reusability
Types of hierarchy
Has-a - represents Association( Specialized form => Composition/Aggregation)
Is-a - represents generalization( also called as inheritance )
Use-a - represents dependency
Creates-a - represents instantiation
3 Minor Elements / Features / Parts /Pillars
By minor, we mean that each of these elements is a useful, but not essential.
Typing / Polymorphism - To reduce maintenance of the system
Concurrency - To utilize h/w resources( Memory/CPU ) efficiently
Persistance - To maintain state of the instance of secondary storage.
Abstraction
Abstraction is a major element / pillar of oops.
Process of getting essesntials things from object/instance is called as abstraction.
Abstraction focuses on outer behavior of an instance.
Abstraction in java:
class Program{
public static void main(String[] args) {
Complex c1 = new Complex( );
[Link]();
[Link]();
}
}
import [Link];
class Program{
public static void main(String[] args) {
Scanner sc = new Scanner( [Link] );
String name = [Link]( );
}
}
interface Printtable{
void print();
}
class Complex{
private int real;
private int imag;
public Complex( ){
[Link] = 0;
[Link] = 0;
}
public void acceptRecord( ){
Scanner sc = new Scanner( [Link] );
[Link]("Real Number : ");
[Link] = [Link]();
[Link]("Imag Number : ");
[Link] = [Link]();
}
public void printRecord( ){
[Link]("Real Number : "+[Link]);
[Link]("Imag Number : "+[Link]);
}
}
Class definition represents encapsulation.
Abstraction and encapsulation are complementary concepts: Abstraction focuses on the observable
behavior of an object, whereas encapsulation focuses on the implementation that gives rise to this
behavior.
Day 10
Major and minor elements / pillars /parts of oops
Abstraction
It is a major pillar of oops.
Process of getting essential things from instance / system is called as abstraction.
Abstraction focuses on external behavior of the instance.
Abstraction changes from entity to entity.
Abstraction helps to achive simplicity.
In Java, if we want to achieve abstraction then we should create instance and invoke method on it.
For Example:
class Program{
public static void main(String[] args) {
Complex c1 = new Complex( );
[Link]( );
[Link]( );
}
}
Encapsulation
Definition:
Binding of data and code together is called as encapsulation.
Implementation of abstraction is called as encapsulation.
Abstraction and encapsulation are complementry concepts. In other words abstraction focuses on
external behavior whereas encapsulation focuses internal behavior.
Using encapsulation:
We can achieve abstraction
We can hide data from user:
Process of declararing fields private is called as data hiding. Data hiding is also called as
data encapsulation.
Data hiding helps us to achive data security.
To achive encapsulation we should define class. Hence class is considered as a basic unit of
encapsulation.
For Example:
class Complex{
private int real;
private int imag;
public Complex( ){
[Link] = 0;
[Link] = 0;
}
public void acceptRecord( ){
//TODO
}
public void printRecord( ){
//TODO
}
}
Modularity
It is a major pillar of oops.
It is the process of developing complex system using small parts.
Modularity helps us to minimize module dependency.
In Java, we can achieve Modularity using packages and .jar file.
Hiearchy
It is a major pillar of oops.
Level / order / ranking of abstraction is called as hierarchy.
class Engine{
//Fields
//Constructors
//Methods
}
class Car{
//Car has a engine
private Engine e = new Engine(); //Association
}
class Wheel{
//TODO
}
class Engine{
}
class Car{
private Wheel[] wheels; //Association --> Composition
private Engine e; //Association --> Composition
}
class Student{
//TODO
}
class University{
private Stundet[] students; //Association --> Aggregation
//TODO
}
class Employee{
private String name;
private int age;
private int empid;
private float salary;
public Employee() {
this("",0,0,0.0f);
}
}
class Employee extends Person{ //Child class / Sub class
//Here Employee class can reuse fields/constructors/methods and
nested types of Person class
}
}
class Employee extends Person {
Now class Person is direct super class of class Employee and class Object is indirect super
class of class Employee.
In Java, any class can extend only one class.
class A{ } //OK
class B{ } //OK
class C extends B{ } //OK
class D extends A, B{ } //Not OK
During inheritance, members of sub class do not inherit into super class. Hence using super class
instance, we can access members of super class only.
}
}
During inheritance, members of super class inherit into sub class. Hence using sub class instance, we
can access members of super class as well as sub class.
int empid;
float salary;
If we create instance of sub class then all the non static fields declared in super class and sub class
get space inside it. In other words, non static fields of super class inherit into sub class.
Using sub class name, we can use/access static fields of super class. It means that static field of
super class inherit into sub class.
All( static and non static ) the fields of super class inherit into sub class but only non static fields get
space inside instance of sub class.
We can call/invoke, non static method of super class on instance of sub class. In other words, non
static method of super class inherit into sub class.
We can invoke, static method of super class on sub class name. In other words, static method of
super class inherit into sub class.
Except constructor, all(static and non static ) the methods of super class inherit into sub class.
If we create instance of sub class then first super class constrcutor gets called and then sub class
constructor gets called.
From any constructor of sub class, by default, super class's parameterless constructor gets called.
If we want to call any constructor of super class from constructor of sub class then we should use
super statement.
super is keyword in java.
super statement must be first statement inside constructor body.
Except constrcutor, all the members of super class inherit into sub class.
Definition of Inheritance
Journey from generalization to specialization is called inheritance.
Process of acquiring/accessing members of parent class into child class is called as
inheritance.
Interface inheritance:
During inheritance, if super type and sub types are interfaces then it is called as interface
inheritance.
Implementation inheritance
During inheritance, if super type and sub type is class then it is called as implementation
inheritance.
interface A{ }
interface B{ }
interface C extends A, B{ } //OK: Multiple interface inheritance
interface A{ }
interface B{ }
class C implements A, B{ } //OK: Multiple interface implementation
inheritance
class A{ }
class B{ }
class C extends A, B{ } //Not OK: Multiple Implementation inheritance
In C++, combination of two or more than two types of inheritance is called hybrid inheritance.
If we combine hierarchical inheritance and multiple inheritance then it becomes diamond
inheritance, which creates some problems.
To avoid diamond problem, Java do not support multiple implementation inheritance / multiple
class inheritance.
Conclusion: In Java, class can extend only one class.
Consider following code:
class Object{
public String toString( );
public boolean equals( Object obj )
public native int hashCode( );
protected native Object clone( )throws CloneNotSupportedException;
protected void finalize()throws Throwable;
public final native Class<?> getClass( );
public final void wait( )throws InterruptedException;
public final native void wait( long timeOut )throws
InterruptedException;
public final void wait( long timeOut, int nanos )throws
InterruptedException;
public final void notify();
public final void notifyAll();
}
class Person extends Object{
//TODO
}
class Employee extends Person{
//TODO
}
In above code, class Person will extend [Link] class and class Employee will extend
only Person class( Not [Link] class ).
class Person is direct super class and class [Link] is indirect super class of Employee
class.
Types of inheritance
Single inheritance
In case of inheritance, if single super type is having single sub type then it is called as single
inheritance.
For example: Car is a vehicle.
Syntax:
class Vehicle{
//TODO
}
class Car extends Vehicle{ //Single inheritance( implementation
inheritance )
//TODO
}
interface Iterable<T>{
//TODO
}
interface Collection<E> extends Iterable<T>{ //Single inheritance(
interface inheritance )
//TODO
}
Multiple inheritance
In case of inheritance, If multiple super types are having single sub type then it is called multiple
inheritance.
For Example: Fax-Copier machine is a fax machine and Fax-Copier machine is also Copier machine.
Syntax:
interface List<E>{ }
interface Queue<E>{ }
class LinkedList implements List<E>, Queue<E>{ } //OK: Multiple
Inheritance
Hierarchical inheritance
In case of inheritance, If single super type is having multiple sub types then it is called as hierarchical
inheritance.
For Example: SavingsAccount is Account, CurrentAccount is a Account.
Syntax:
//Hierarchical inheritance
class Account{ }
class SavingsAccount extends Account{ } //Single inheritance
class CurrentAccount extends Account{ } //Single inheritance
interface Collection<E>{ }
interface List<Collection> extends <Collection<E>{ }
interface Queue<E> extends Collection<E>{ }
interface Set<E> extends Collection<E>{ }
Multilevel inheritance
In case of inheritance, if single inheritance is having multiple levels then it is called as multilevel
inheritance.
For Example: Employee is a Person; Manager is a Employee; Salesanager is a Manager;
Syntax:
//Multilevel inheritance
class Person{ };
class Employee extends Person{ } //Single inheritance
class Manager extends Employee{ } //Single inheritance
class SalesManager extends Manager{ } //Single inheritance
//Multilevel inheritance
interface Iterable<T>{ }
interface Collection<E> extends Iterable<T>{ }
interface Queue<E> extends Collection<E>{ }
interface Deque<E> extends Queue<E>{ }
Reference: [Link]
Private members( fields/methods/nested types ) inherit into sub class. If we want to access value of
private field inside sub class then we should use getter and setter methods of super class.
class A{
private int num1;
public A( ) {
this.num1 = 10;
}
public int getNum1() {
return this.num1;
}
}
class B extends A{
}
public class Program {
public static void main(String[] args) {
B b = new B();
//[Link](b.num1); //The field A.num1 is not visible
[Link]( b.getNum1() ); //10
}
public static void main1(String[] args) {
A a = new A();
//[Link](a.num1); //The field A.num1 is not visible
[Link]( a.getNum1() );
}
}
Accessing members using super keyword
According, clients requirement, if implementation of super class method is logically incomplete /
partially complete then we should redefine method inside sub class. In other words, we should
override method inside sub class.
If name of super class method and sub class method is same and if we try to invoke such
method on instance of sub class then preference will be given to the sub class method. It is
called as method shadowing.
If we want to use any member of super class inside method of sub class then we should use super
keyword.
class Complex{
private int real;
private int imag;
public Complex( ) {
[Link] = 10;
[Link] = 20;
}
public void setReal(int real) {
real = real; //Shadowing : Local variable is assigned to itself
}
public void setImag(int imag) {
[Link] = imag;
}
@Override
public String toString() {
return [Link]+" "+[Link];
}
}
public class Program {
public static void main(String[] args) {
Complex c1 = new Complex( ); //10,20
[Link](50);
[Link]([Link]()); //10,20
}
}
In case of fields
class A{
int num1 = 10;
int num3 = 30;
}
class B extends A{
int num2 = 20;
int num3 = 40;
public void printRecord( ) {
[Link]("Num1 : "+num1); //OK: 10
[Link]("Num1 : "+this.num1); //OK: 10
[Link]("Num1 : "+super.num1); //OK: 10
In case method
class A{
public void showRecord( ) {
[Link]("[Link]()");
}
public void printRecord( ) {
[Link]("[Link]()");
}
}
class B extends A{
public void displayRecord( ) {
[Link]("[Link]()");
}
public void printRecord( ) {
[Link]("[Link]()");
}
}
public class Program {
public static void main(String[] args) {
B b = new B();
[Link](); //[Link]()
[Link](); //[Link]()
[Link](); //[Link]() => Shadowing
}
}
Since members of super class inherit into sub class, using sub class instance we can access
members of super class as well as sub class.
Final conclusion:
Person p = new Person(); //OK
Person p = new Employee(); //OK
Employee emp = new Employee(); //OK
Employee emp = new Person(); //Not OK
Upcasting
Definition
Process of converting reference of sub class into reference of super class is called as
upcasting.
Super class reference can contain reference of sub class instance. It is also called as
upcasting.
If we want to minimize object/instance dependency in the code then we should use upcasting.
Downcasting
Process of converting reference of super class into reference of sub class is called as downcasting.
In case of upcasting, explicit type casting is optional but in case of dowcasting explicit typecasting is
manadatory.
class Person{
public void printRecord( ){
[Link]("[Link]");
}
}
class Employee extends Person{
public void printRecord( ){
[Link]("[Link]");
}
}
class Program{
public static void main(String[] args) {
Person p = new Employee(); //Upcasting
[Link](); //Dynamic method dispatch
}
}
Note: In case of upcasting we can not access fields and non overriden methods of sub class. If we
want to access it the we should do downcasting.
Rules of method overriding
Below are the rules of method overriding
Access modifier of sub class method should be same or it should be wider.
Return type in sub class method should be same or it should be sub type.
Method name, number of paramaters and type of parameters in sub class method must be
same.
Checked exception list in sub class method should be same or it should be sub set.
Override is annotation declared in [Link] package. It helps developer to override method using
above rules. If we make any mistake then it generates metadata for the compiler to generate error.
class Person{
public void printRecord( ){
[Link]("[Link]");
}
}
class Employee extends Person{
@Override
public void printRecord( ){
[Link]("[Link]");
}
}
class Program{
public static void main(String[] args) {
Person p = new Employee(); //Upcasting
[Link](); //Dynamic method dispatch
}
}
instanceof operator
ArrayStoreException
operator== versus equals method
Day 12
If we want to reduce object/instance dependency in the code then we should use upcasting.
In case of upcasting, using super class reference variable, we can access :
. Fields of super class( if it is non private )
. Methods of super class
. Overriden method of sub class
In case of upcasting, if we want to access fields of sub class and non overriden method of sub class
then we should do downcasting.
instanceof
process of calling method of sub class on reference of super class is called as dynamic method
dispatch.
Boxing:
Process of converting value of primitive type into non primitive type is called as boxing.
For example:
If we want to compare state/value of variable of primitive type then we should use operator ==.
If we do not define equals() method inside class then super class's equals method will call.
Consider implementation of equals method from [Link] class:
class Employee{
private String name;
private int empid;
private float salary;
public Employee(String name, int empid, float salary) {
[Link] = name;
[Link] = empid;
[Link] = salary;
}
}
public class Program {
public static void main(String[] args) {
Employee emp1 = new Employee("Sandeep", 3778, 45000.50f );
Employee emp2 = new Employee("Sandeep", 3778, 45000.50f );
if( [Link](emp2) )
[Link]("Equal");
else
[Link]("Not Equal");
//Not Equal
}
public static void main1(String[] args) {
Employee emp1 = new Employee("Sandeep", 3778, 45000.50f );
Employee emp2 = new Employee("Sandeep", 3778, 45000.50f );
if( emp1 == emp2 ) //OK: Comparing state of references
[Link]("Equal");
else
[Link]("Not Equal");
//Not Equal
}
}
class Employee{
private String name;
private int empid;
private float salary;
public Employee(String name, int empid, float salary) {
[Link] = name;
[Link] = empid;
[Link] = salary;
}
//Employee this = emp1;
//Object obj = emp; //Upcasting
@Override
public boolean equals( Object obj ) {
if( obj != null ) {
Employee other = (Employee) obj; //Downcasting
if( [Link] == [Link] )
return true;
}
return false;
}
}
public class Program {
public static void main(String[] args) {
Employee emp1 = new Employee("Sandeep", 3778, 45000.50f );
Employee emp2 = new Employee("Sandeep", 3778, 45000.50f );
//Employee emp2 = null;
if( [Link](emp2) )
[Link]("Equal");
else
[Link]("Not Equal");
//Equal
}
}
Day 13
Project Lombok
Reference [Link]
External system resources
Following are the operating system resources that we can use for the application development:
Memory
Processor
Input and Output devices
File
Socket
Network Connections
Database connections
Operating System API
In the context of Java, all above resources are non Java resources. These are also called as
unmanaged resources(except memory).
In the context of Java, resource is any external system resource that we can use in the application.
Since operating system resources are limited, we should use it carefully.
Exception Concept
Definition
Exception is an issue / unexpected event / instance which occurs during execution of
application.
Exception is an instance which is used to acknowledge user of the system if any exeption
situation occurs in the code.
If we want to manages OS resources carefully then we should use exception handling in Java.
Throwable class Hierarchy
[Link] is ultimate super class of all the classes in Java language.
Methods of [Link] class:
public String toString( );
public boolean equals( Object obj );
public native int hashCode();
protected native Object clone( )throws CloneNotSupportedException
protected void finalize( )throws Throwable;
public final native Class<?> getClass();
public final void wait( )throws InterruptedException
public final native void wait( long timeOut )throws InterruptedException
public final void wait( long timeOut, int nanos)throws InterruptedException
public final native notify( );
public final native notifyAll( );
[Link]:
The Throwable class is the superclass of all errors and exceptions in the Java language.
Only objects that are instances of Throwable class (or one of its subclasses) are thrown by the Java
Virtual Machine or can be thrown by the Java throw statement.
Consider code in C++
int num2;
cout<<"Enter number : ";
cin>>num2;
try{
if( num2 == 0 ){
//throw 0; //OK
//throw ArithmeticException( "Divide by zero exception");
//OK
throw "Divide by zero exception"; //OK
}else
int result = num1 / num2;
cout<<"Result : "<<result<<endl;
}
}catch( string &ex ){
cout<<ex<<endl;
}
return 0;
}
Consider code in Java
class MyException{
private String message;
public MyException(String message) {
[Link] = message;
}
}
public class Program {
public static void main(String[] args){
int num1 = 10;
int num2 = 0;
try {
if( num2 == 0 )
//throw 0; //No exception of type int can be thrown; an
exception type must be a subclass of Throwable
//throw "/ by 0"; //No exception of type String can be
thrown; an exception type must be a subclass of Throwable
throw new MyException("/ by 0");//No exception of type
MyException can be thrown; an exception type must be a subclass of
Throwable
int result = num1 / num2;
[Link]("Result : "+result);
}catch( Exception ex ) {
//TODO
}
}
}
}
}
Similarly, only Throwable class or one of its subclasses can be the argument type in a catch clause.
Consider following code:
}
}
}
Constructor Summary
public Throwable()
Method Summary
public String getMessage()
public Throwable initCause(Throwable cause)
public Throwable getCause()
public final void addSuppressed(Throwable exception)
public void printStackTrace()
public void printStackTrace(PrintStream s)
public void printStackTrace(PrintWriter s)
public StackTraceElement[] getStackTrace()
Error versus Exception
Error and Exception are direct sub classes of [Link] class.
Error
An Error is a subclass of Throwable that indicates serious problems that a reasonable application
should not try to catch.
Most such errors are abnormal conditions.
Runtime error which gets generated due to environmental condition( hardware failure / OS failure /
JVM failure etc ) is considered as error in java programming language.
Consider following code:
We can write try-catch block to handle errros. But we can not recover from errors hence it is not
recommended to use try catch block for the errors.
Example:
OutOfMemoryError
StackOverflowError
VirtualMachineError
Exception
The class Exception and its subclasses are a form of Throwable that indicates conditions that a
reasonable application might want to catch.
Runtime error which gets generated due to application is considered as exception in java
programming language.
We can use try-catch block to handle exception.
Example:
CloneNotSupportedException
InterrupedException
NumberFormatException
NullPointerExcption
NegativeArraySizeException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
ArithmeticException
Checked versus unchecked exception
Checked exception and unchecked exception are types of exception in Java, which are designed for
Java compiler( Not for JVM ).
Unchecked Exception
[Link] is considered as super class of all the unchecked exception.
[Link] and all its sub classes are considered as unchecked exception.
Examples of unchecked exception
RuntimeException
NumberFormatException
NullPointerExcption
NegativeArraySizeException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
ArithmeticException
Compiler do not force developer to handle or to use try-catch block for unchecked exception.
Checked Exception
[Link] is considered as super class of all the checked exception.
[Link] and all its sub classes except [Link](and its sub classes )
are considered as checked exceptions
Examples of checked exception
[Link]
[Link]
[Link]
[Link]
Compiler force developer to handle or to use try-catch block for checked exception.
AutoCloseable and Closeable
Closeable is an interface which is delcared in [Link] package.
Method: void close() throws IOException
It is introduced in JDK 1.5
Consider following code:
import [Link];
import [Link];
import [Link];
}
public class Program {
public static void main(String[] args) {
try {
Test t = new Test();
[Link]();
} catch (IOException e) {
// TODO Auto-generated catch block
[Link]();
}
}
}
@Override
public void close() throws Exception {
[Link]();
}
}
public class Program {
public static void main(String[] args) {
try {
Test t = new Test(); //new Test() => Resource
[Link]();
} catch (Exception e) {
// TODO Auto-generated catch block
[Link]();
}
}
Any class which implements AutoCloseable / Closeable interface is called as resource type and its
instance is called resource.
If we use try with resource then close() method gets called automatically.
Exception handling using try catch throw throws and finally
If we want to handle exception then we should use 5 keywords in java:
try
catch
throw
throws
finally
While performing arithmetic operation, if we get any exception condition like "divide by zero" then
JVM throws ArithmeticException.
try
It is a keyword in Java.
If we want to keep watch on single statement or group of statements for exception then we should
use try block / handler.
we can not define try block after catch/finally block.
Try block must have at least one catch block or finally block or resource statement.
Consider following syntax:
throw
It is a keyword in java.
If we want to generate new exception then we should use throw keyword.
Only objects that are instances of Throwable class (or one of its subclasses) are thrown by the JVM
or can be thrown by the Java throw statement.
[Link]("Num1 : ");
int num1 = [Link]();
[Link]("Num2 : ");
int num2 = [Link]();
if( num2 == 0 )
throw new ArithmeticException("Divide by zero exception");
int result = num1 / num2;
[Link]("Result : "+result);
}catch ( ArithmeticException ex) {
[Link]();
}catch ( RuntimeException ex) {
[Link]();
}catch ( Exception ex) {
[Link]();
}
}
Using [Link] class we can define catch block which can handle any checked as well as
uncheked exception.
try{
//TODO
}catch( Exception ex ){ //Generic catch block
[Link]();
}
Generally, generic catch block comes after all specific catch blocks.
finally
It is a keyword in Java.
If we want to close or release local resources then we should use finally block.
For given try block we can provide only one finally block.
We can define block after all try and catch blocks.
JVM always execute finally block.
try with resource
public static void main(String[] args) {
//try ( Program p = new Program()) { //Not Ok: The resource
type Program does not implement [Link]
try( Scanner sc = new Scanner([Link])){
[Link]("Num1 : ");
int num1 = [Link]();
[Link]("Num2 : ");
int num2 = [Link]();
if( num2 == 0 )
throw new ArithmeticException("Divide by zero exception");
int result = num1 / num2;
[Link]("Result : "+result);
throws
It is a keyword in Java
If we want delegate exception from method to the caller method then we should use throws
keyword/clause.
public class Program {
public static void displayRecord( ) throws InterruptedException {
for( int count = 1; count <= 10; ++ count ) {
[Link]("Count : "+count);
[Link](500);
}
}
public static void main(String[] args) {
try {
[Link]();
} catch (InterruptedException e) {
[Link]();
}
}
}
Exception chaining
Process of handling exception by throwing new type of exception is called as exception chaining.
Consider following code:
package [Link];
abstract class A{
public abstract void print( );
}
class B extends A{
@Override
public void print() throws RuntimeException{
try {
for( int count = 1; count <= 10; ++ count ) {
[Link]("Count : "+count);
[Link](250);
}
} catch (InterruptedException cause) {
throw new RuntimeException(cause); //Exception Chaining
}
}
}
public class Program {
public static void main(String[] args) {
try {
A a = new B();
[Link]();//Dynamic method dispatch
} catch (RuntimeException e) {
//[Link]();
Throwable cause = [Link]();
[Link](cause);
}
}
}
Day 14
class A extends Exception{ }
class B extends Exception{ }
class C extends Exception{ }
public class Program {
//public static void print( int number ) throws A, B, C {
public static void print( int number ) throws Exception {
if( number == 10 )
throw new A();
if( number == 20 )
throw new B();
if( number == 30 )
throw new C();
[Link]("Number : "+number);
}
public static void main(String[] args) {
try {
[Link](50);
} catch (Exception e) {
[Link]();
}
}
}
class Super{
public static void showRecord( ) {
[Link]("[Link]()");
}
}
class Sub extends Super{
@Override
public static void showRecord( ) { //Compiler Error
[Link]("[Link]()");
}
}
class Super{
public void printRecord( ) {
[Link]("[Link]()");
}
}
class Sub extends Super{
@Override
public void printRecord( ) { //Overrided method
[Link]("[Link]()");
}
}
public class Program {
public static void main(String[] args) {
//Super s1 = new Super();
//[Link]();
class A{
public void f2( ) {
[Link]("A.f2");
}
public final void f3() {
[Link]("A.f3");
}
}
class B extends A{
@Override
public final void f2() {
[Link]("B.f2");
}
}
public class Program {
public static void main(String[] args) {
B b = new B();
b.f2();
}
}
According business requirement, if implementation of class is logically 100% complete then we
should declare such class final.
We can not extend final class. In other words, we can not create sub class of final class.
Examples of final class:
[Link]
[Link]
[Link]
[Link]
All the wrapper classes
[Link]
[Link]
Abstract method an abstract class
According business requirement, if implementation of super class method is logically 100%
incomplete then we should declare super class method abstract.
abstract is modifier in java.
We can not provide body to the abstract method.
If we declare method abstract then we must declare class abstract.
We can not instantiate abstract class. In other words, we can not create instance of abstract class but
we can create reference of abstract class.
Abstract class may/may not contain abstract method.
If super class contains abstract method then sub class must override it otherwise sub class will be
considered as abstract.
Consider following code:
abstract class A{
public abstract void f1( );
}
class B extends A{
@Override
public void f1() {
//TODO
}
}
abstract class A{
public abstract void f1( );
}
abstract class B extends A{
}
abstract class A{
public abstract void f1( );
public abstract void f2( );
public abstract void f3( );
}
abstract class B extends A{
@Override
public void f1() { }
@Override
public void f2() { }
@Override
public void f3() { }
}
class C extends B {
@Override
public void f1() {
[Link]("C.f1");
}
}
class D extends B {
@Override
public void f2() {
[Link]("D.f2");
}
}
class E extends B{
@Override
public void f3() {
[Link]("E.f3");
}
}
public class Program {
public static void main(String[] args) {
A a = null;
a = new C();
a.f1();
a = new D();
a.f2();
a = new E();
a.f3();
}
}
Sole constructor
A constructor of super class which is designed to call from constructor of only sub class is called sole
constructor.
abstract class A{
private int num1;
private int num2;
public A( int num1, int num2) { //Sole Constructor
this.num1 = num1;
this.num2 = num2;
}
public void printRecord( ) {
[Link]("Num1 : "+this.num1);
[Link]("Num2 : "+this.num2);
}
}
class B extends A{
private int num3;
public B( int num1, int num2, int num3 ) {
super( num1, num2 );
this.num3 = num3;
}
@Override
public void printRecord() {
[Link]();
[Link]("Num3 : "+this.num3);
}
}
public class Program {
public static void main(String[] args) {
Process of converting value of variable of primitive type into non primitive type is called as boxing.
We can directly store reference of sub class instance into super class reference variable. It is
called as upcasting.
If we want to reduce object/instance dependency in the code then we should use upcasting.
In case of upcasting, using super class reference variable we can access:
non private fields of super class.
non private methods of super class.
overriden methods of sub class.
Downcasting definition
We can convert reference super class into reference of sub class. It is called as downcasting.
In case of upcasting, using super class reference variable, we can not access non private fields and
non overriden methods of sub class. If we want to access it then we should do downcasting.
Consider following code:
class A{
public void print( ){
[Link]("[Link]");
}
public void display( ){
[Link]("[Link]");
}
}
class B extends A{
@Override
public void print( ){
[Link]("[Link]");
}
public void show( ){
[Link]("[Link]");
}
}
class Program{
public static void main( String[] args ){
A a1 = new A(); //OK
[Link](); //[Link]
B b1 = new B( ); //OK
[Link](); //[Link] => Due to shadowing preference will be given
to [Link]
Generic Programming
Let us define stack to store boolean elements
class Stack{
private int top = -1;
private boolean[] arr;
public Stack( ) {
this( 5 );
}
public Stack( int size ) {
[Link] = new boolean[ size ];
}
public boolean empty( ) {
return [Link] == -1;
}
public boolean full( ) {
return [Link] == [Link] - 1;
}
public void push( boolean element ) throws StackOverflowException
{
if( [Link]())
throw new StackOverflowException("Stack is full");
[Link] = [Link] + 1;
[Link][ [Link] ] = element;
}
public boolean peek( ) throws StackUnderflowException {
if( [Link]())
throw new StackUnderflowException("Stack is empty");
return [Link][ [Link] ];
}
public void pop( ) throws StackUnderflowException {
if( [Link]())
throw new StackUnderflowException("Stack is empty");
[Link] = [Link] - 1;
}
}
class Stack{
private int top = -1;
private double[] arr;
public Stack( ) {
this( 5 );
}
public Stack( int size ) {
[Link] = new double[ size ];
}
public boolean empty( ) {
return [Link] == -1;
}
public boolean full( ) {
return [Link] == [Link] - 1;
}
public void push( double element ) throws StackOverflowException {
if( [Link]())
throw new StackOverflowException("Stack is full");
[Link] = [Link] + 1;
[Link][ [Link] ] = element;
}
public double peek( ) throws StackUnderflowException {
if( [Link]())
throw new StackUnderflowException("Stack is empty");
return [Link][ [Link] ];
}
public void pop( ) throws StackUnderflowException {
if( [Link]())
throw new StackUnderflowException("Stack is empty");
[Link] = [Link] - 1;
}
}
class Box{
private Object reference;
public Object getReference() {
return reference;
}
public void setReference(Object reference) {
[Link] = reference;
}
}
Using [Link] class, we can write generic code but we can not write type-safe generic code.
[Link](new Date());
[Link](date);
}
}
Why Generics
Generics gives us stronger typechecking at compile time. In other words, using generics we can write
type-safe generic code.
It completly eliminates need of explict typecasting.
It helps developer to define generic algorithms and data structures.
Generics Syntax:
We can specify type argument during declaration of reference as well as instantiation.
If we specify type argument during reference declaration then specifying type argument during
instantiation is optional. It is called as type inference.
If we use parameterized type without type argument then it is called as raw type.
Box b = new Box(); //OK: Here Box is called as raw type
//Box<Object> b1 = new Box< Object>( );
During instantiation of parameterized type, type argument must be non primitive type.
If we want to store primitive values inside instance of parameterized type then type argument must
be Wrapper class.
ArrayList demo
import [Link];
Wild Card
In Generics ? is called as wild card which represents unknown type.
Types of wild card
Unbouned wild card
Upper Bouned wild card
Lower Bounded wild card.
Consider following code
In above code, list will contain reference of ArrayList which can contain any type of element.
public static void main(String[] args) {
ArrayList<Integer> integerList = [Link]();
[Link]( integerList );
In the above code, list will contain reference of ArrayList which can containf Number and its sub type
of elements
In above code, list will contain reference of ArrayList which can contain Integer and its super type of
elements.
public static void main(String[] args) {
ArrayList<Integer> integerList = [Link]();
[Link]( integerList ); //OK
Restrictions on Generics
Reference: [Link]
Day 16
Synthetic Constructs in Java
Reference: [Link]
Generic Method
We can define generic method using [Link] class.
Type Erasure
Consider generic type without upper bound.
class Box<T>{
private T data;
public Box() {
}
public Box(T data) {
[Link] = data;
}
public T getData() {
return data;
}
public void setData(T data) {
[Link] = data;
}
@Override
public String toString() {
return [Link]();
}
}
class Box{
private Object data;
public Box() {
}
public Box(Object data) {
[Link] = data;
}
public Object getData() {
return data;
}
public void setData(Object data) {
[Link] = data;
}
@Override
public String toString() {
return [Link]();
}
}
public Box() {
}
public Box(T data) {
[Link] = data;
}
public T getData() {
return data;
}
public void setData(T data) {
[Link] = data;
}
@Override
public String toString() {
return [Link]();
}
}
class Box{
private Number data;
public Box() {
}
public Box(Number data) {
[Link] = data;
}
public Number getData() {
return data;
}
public void setData(Number data) {
[Link] = data;
}
@Override
public String toString() {
return [Link]();
}
}
Bridge method
Consider following code:
class Box<T>{
private T data;
public Box() {
}
public Box(T data) {
[Link] = data;
}
public void setData(T data) {
[Link] = data;
}
@Override
public String toString() {
return [Link]();
}
}
class Sample extends Box<Integer>{
public Sample() {
super();
}
public Sample(Integer data) {
super(data);
}
/*
//Method added by compiler to achive dynamic method dispatch
public void setData(Object data) { //Bridge method
[Link]((Integer)data);
} */
@Override
public void setData(Integer data) {
[Link](data);
}
}
public static void main3(String[] args) {
Sample s = new Sample();
Box b = s; //Upcasting
[Link](123); //OK
[Link]([Link]()); //123
}
Restrictions on Generics
Cannot Instantiate Generic Types with Primitive Types
class Box<T>{
private static T data; //Not OK
//TODO: Getter and Setter
}
A class cannot have two overloaded methods that will have the same signature after type erasure.
class Program{
private Program( ){
//TODO
}
public void main( String[] args ){
//TODO
}
}
class Program{
public Program( String s1, int i1, float f1, double d1 ){
//TODO
}
public void main( String[] args ){
//TODO
}
}
interface Printable{
//int value; //Error: The blank final field value may not have been
initialized
int value = 123;
//public static final int value = 123;
}
interface Printable{
//void print( ) { } //Error: Abstract methods do not specify a
body
void print( );
//public abstract void print( );
}
void print( );
//public abstract void print( );
}
class Test implements Printable{ //Service Provider
@Override
public void print() {
[Link]("Value : "+[Link]);
}
}
public class Program { //Service Consumer
public static void main(String[] args) {
Printable p = null; //OK
p = new Test( ); //Upcasting
[Link]();//Dynamic method dispatch
}
}
[Link]("Num2 : "+B.num2);
[Link]("Num2 : "+C.num2);
[Link]("Num3 : "+C.num3);
}
}
Interface method syntax:
interface A{
void f1();
}
interface B{
void f2();
}
interface C extends A, B{
void f3();
}
class D implements C{
@Override
public void f1() {
[Link]("D.f1");
}
@Override
public void f2() {
[Link]("D.f2");
}
@Override
public void f3() {
[Link]("D.f3");
}
}
public class Program {
public static void main(String[] args) {
D d = new D();
d.f1();//OK
A a = new D();
a.f1();//OK
B b = new D();
b.f2();//OK
C c = new D();
c.f1(); //OK
c.f2(); //OK
c.f3(); //Ok
}
}
interface A{
void f1();
void f3();
}
interface B{
void f2();
void f3();
}
class C implements A, B{
@Override
public void f1() {
[Link]("C.f1");
}
@Override
public void f2() {
[Link]("C.f2");
}
@Override
public void f3() {
[Link]("C.f3");
}
}
public class Program {
public static void main(String[] args) {
A a = new C();
a.f1();
a.f3();
B b = new C();
b.f2();
b.f3();
}
}
interface Printable{
void f1();
void f2();
void f3();
void f4();
}
abstract class AbstractPrintable implements Printable{
@Override public void f1() { }
@Override public void f2() { }
@Override public void f3() { }
}
class A extends AbstractPrintable{
@Override
public void f1() {
[Link]("A.f1");
}
}
class B extends AbstractPrintable{
@Override
public void f2() {
[Link]("B.f2");
}
}
class C extends AbstractPrintable{
@Override
public void f3() {
[Link]("C.f3");
}
}
public class Program {
public static void main(String[] args) {
Printable p = null;
p = new A();
p.f1(); //A.f1
p = new B();
p.f2(); //B.f2
p = new C();
p.f3(); //C.f3
}
}
Types of inheritance
Interface inheritance
Single inheritance( Allowed in java )
Multiple inheritance( Allowed in java )
Hierarchical inheritance( Allowed in java )
Multilevel inheritance( Allowed in java )
implementation inheritace
Single inheritance( Allowed in java )
Multiple inheritance( Not Allowed in java )
Hierarchical inheritance( Allowed in java )
Multilevel inheritance( Allowed in java )
Default interface method
If we want to make changes in the interface at runtime then we should use default method.
We can not provide body to the abstact method but it is mandatory to provide body to the default
method.
It is mandatory to override abstract method but it is optional to override default method.
interface A{
void f1( );
default void f2( ){
//TODO
}
}
class B implements A{
@override
public void f1( ){
//TODO
}
}
interface A{
void f1( );
default void f2( ){
//TODO
}
}
interface B{
void f1( );
default void f3( ){
//TODO
}
}
class C implements A, B{
@override
public void f1( ){
//TODO
}
}
interface A{
void f1( );
default void f2( ){
//TODO
}
}
interface B{
void f1( );
default void f2( ){
//TODO
}
}
class C implements A, B{
@override
public void f1( ){
//TODO
}
@Override
public void f2( ){ //mandatory to override
//TODO
}
}
Consider following code:
interface Collection {
void acceptRecord();
int[] toArray();
void printRecord();
public Array() {
this(5);
}
@Override
public void acceptRecord() {
try (Scanner sc = new Scanner([Link])) {
for (int index = 0; index < [Link]; ++index) {
[Link]("Enter element : ");
[Link][index] = [Link]();
}
}
}
@Override
public int[] toArray() {
return [Link];
}
@Override
public void sort() {
for( int i = 0; i < [Link] - 1; ++ i ) {
for( int j = i + 1; j < [Link]; ++ j ) {
if( [Link][ i ] > [Link][ j ] ) {
int[] temp = new int[ ] { arr[ i ], arr[ j ]};
[Link](temp);
arr[ i ] = temp[ 0 ];
arr[ j ] = temp[ 1 ];
}
}
}
}
@Override
public void printRecord() {
[Link]([Link]([Link]));
}
}
Static interface methods are helper methods that we can use inside default method as well as inside
sub class. But we can not override it inside sub class.
Functional interface
An interface which can contain Single Abstract Method (SAM) is called as Functional interface / SAM
interface.
Example:
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Consider following code:
@FunctionalInterface
interface A{
void f1();
}
@FunctionalInterface
interface A{
void f1();
default void f2( ){
}
}
@FunctionalInterface
interface A{
void f1();
default void f2( ){
}
static void f3( ){
}
}
@FunctionalInterface
interface A{
void f1();
default void f2( ){
}
default void f3( ){
}
static void f4( ){
}
static void f5( ){
}
}
If we want to create new instance from existing instance then we should use clone method.
clone is non final and native method of [Link] class:
Syntax:
protected native Object clone( )throws CloneNotSupportedException
Inside clone method, if we want to create shallow copy of instance then we should use [Link]();
Without implementing Cloneable interface, if we try to create clone() of the instane then clone
method throws CloneNotSupportedException.
Marker interface:
An interface which do not contain any member is called as marker / tagging interface.
Marker interface are used to generate metadata. It helps JVM to perform some operations e.g
to do clone, serializing state of java instance etc.
Example:
[Link]
[Link]
[Link]
[Link]
@Override
public String toString() {
return [Link]+" / "+[Link]+" / "+[Link];
}
}
[Link](dt1);
[Link](dt2);
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
[Link]();
}
}
Shallow Copy
Deep Copy
If we want to sort array/collection of non primitive type using [Link]() method then non primitive
type must implement Comparable interface.
Comparable is interface declared in [Link] package.
T -> the type of objects that this object may be compared to
Method:
int compareTo(T other)
Returns a negative integer(-1) : current/calling object is less than the specified object.
Returns zero(0): current/calling object is equal to the specified object.
Returns a positive integer(1) : current/calling object is greater than the specified object.
Comparable interface provides natural ordering( default ordering ) of elements inside same class.
This interface imposes a total ordering on the objects of each class that implements it. This ordering
is referred to as the class's natural ordering, and the class's compareTo method is referred to as its
natural comparison method.
@NoArgsConstructor
@AllArgsConstructor
@Getter @Setter
//@ToString
public class Employee implements Comparable<Employee>{
private int empNumber;
private String empName;
private String job;
private int manager;
private LocalDate hireDate;
private float salary;
private float commision;
private int deptNumber;
@Override
public int compareTo(Employee other) {
return [Link] - [Link];
}
@Override
public String toString() {
return [Link]("%-5d%-10s%-10s%-5d%-15s%-10.2f%-10.2f%-5d",
[Link], [Link], [Link], [Link], [Link],
[Link], [Link], [Link]);
}
}
import [Link];
import [Link];
public class IdComparator implements Comparator<Person>{
@Override
public int compare(Person p1, Person p2) {
if( p1 instanceof Student && p2 instanceof Student ) {
Student s1 = (Student) p1;
Student s2 = (Student) p2;
return [Link]() - [Link]();
}else if( p1 instanceof Employee && p2 instanceof Employee ) {
Employee e1 = (Employee) p1;
Employee e2 = (Employee) p2;
return [Link]() - [Link]();
}else if( p1 instanceof Student && p2 instanceof Employee ) {
Student s1 = (Student) p1;
Employee e2 = (Employee) p2;
return [Link]() - [Link]();
}else {
Employee e1 = (Employee) p1;
Student s2 = (Student) p2;
return [Link]() - [Link]();
}
}
}
import [Link];
import [Link];
We can use foreach loop on Array and any instance which implements [Link] interface.
Iterable is interface declared in [Link] package.
T -> the type of elements returned by the iterator
Implementing this interface allows an object to be the target of the "for-each loop" statement.
It is introduced in JDK 1.5
Methods:
[Link] iterator()
default Spliterator spliterator()
default void forEach(Consumer<? super T> action)
Iterator is interface declared in [Link] package.
E -> the type of elements returned by this iterator
It is introduced in JDK 1.2
Methods:
boolean hasNext()
E next()
default void remove()
default void forEachRemaining(Consumer<? super E> action)
import [Link];
class Node{
int data;
Node next = null;
public Node( int data ) {
[Link] = data;
}
}
Super class of abstract class can be either concrete class / abstract class. Abstract class can extend
only one abstract class / concrete class.
We can define constructor inside abstract class.
Abstract may/may not contain abstract method.
When state is involved in super type then it should be abstract class
Interface
If "is-a" relationship is not exist between super type & sub type( "can-do" relationship is exist ) and if
we want to use same method design in all the sub classes then super type should be interface.
Consider following diagram
Super type of interface must be interface. Interface can extend multiple interfaces.
We can not define constructor inside interface.
Interface methods are by default public and abstract.
When state is not involved in super type then it should be interface.
Nested class
We can define class inside scope of another class. It is called as nested class.
Consider following code:
Access modifier of top level class can be either package level private or public only but we can use
any access modifier on nested class.
Types of nested class
Non static nested class / Inner class
Static nested class
Inner class
In Java, non static nested class is called as inner class.
If implementation of nested class depends on top level class then we should declare nested class non
static.
@Override
public Iterator<Integer> iterator() {
Iterator<Integer> itr = new LinkedListIterator( [Link] );
//Upcasting
return itr;
}
Note: For the simplicity, consider non static nested class a non static method of the class.
Consider following code:
class Outer{
class Inner{
//TODO
}
}
Inside non static nested class i.e inner class, we can not define static members( fields & methods ).
But if we want to declare any static field then it must be final.
Using instance, we can access members of non static nested class inside method of top level class.
Consider following example:
class Outer{
private int num1 = 10; //OK
private static int num2 = 20; //OK
class Inner{
private int num3 = 30; //OK
//private static int num4 = 40; //Not OK
private final static int num4 = 40; //OK
}
Without instance, we can access all the members of top level class inside method of non static
nested class i.e inner class.
Consider following code:
class Outer{
private int num1 = 10;
private static int num2 = 20;
class Inner{
private int num3 = 30;
private final static int num4 = 40;
public void print( ) {
[Link]("Num1 : "+num1); //OK
[Link]("Num2 : "+num2); //OK
[Link]("Num3 : "+this.num3);
[Link]("Num4 : "+Inner.num4);
}
}
}
public class Program {
public static void main(String[] args) {
[Link] in = new Outer().new Inner();
[Link]();
}
}
class Outer{
private int num1 = 10;
class Inner{
private int num1 = 20;
public void print( ) {
int num1 = 30;
[Link]("Num1 : "+[Link].num1); //10
[Link]("Num1 : "+this.num1); //20
[Link]("Num1 : "+num1); //30
}
}
}
public class Program {
public static void main(String[] args) {
[Link] in = new Outer().new Inner();
[Link]();
}
}
In Java, we can not declare top level class static but we can declare nested class static.
Note: For simplicity, consider static nested class as a static method of the class.
Instantiation of Top level class:
We can access static members of the top level class inside method of static nested class directly. But
to access non static member of the class we must use instance of the class.
class Outer{
private int num1 = 10;
private static int num2 = 20;
interface Printable{
void print( );
}
public class Program {
public static void main(String[] args) {
Printable p = new Printable() {
@Override
public void print() {
[Link]("Hello World!!");
}
};
[Link]();
}
}
Reflection
Annotation
Day 18
What is Metadata?
Data about data is called as metadata. In other words, metadata refers to data that provides
information about other data.
For example, metadata for a photo might include:
The date and time it was taken
The location where it was taken
The camera used to take it
The resolution of the image.
In the case of digital media, metadata can include information about:
the artist
title
genre and album of a particular song or video.
In a file management application, metadata such as:
file name
size
creation date and modification date are commonly used to organize and search for files.
Metadata of Interface
What is the name of interface?
In which package it is declared?
Which is the access modifier of interface?
Which annotations are used on interface?
Which are the super interfaces of interface?
Which are the members declared inside interface?
Metadata of Class
What is the name of class?
In which package it is declared?
Which are the modifiers used on class?
Which are the annotations used on class?
Which is the super class of class?
Which are the super interfaces of the class?
Which are the members declared inside class?
Metadata of the Field
What is the name of the field?
Which is the type of field?
Which are the modifiers of field?
Which annotations has been used on the field?
Whether field is declared or inherited field?
Metadata of the method
What is the name of method?
Which are the modifiers used with method?
Which is the return type of method?
Which are the parameters of the methods?
Which exceptions method throws?
Which annotations has been used on the method.
Whether method is declared or inerhited method?
Application of Metadata
Metadata removes the need for native C/C++ header and library files when compiling.
Integrated Development Environment(IDE) uses metadata to help us write code. Its IntelliSense
feature parses metadata to tell us what fields and methods a type offers and in the case of a method,
what parameters the method expects.
Metadata allows an objectʼs fields to be serialized into a memory block, sent to another machine, and
then deserialized, re-creating the objectʼs state on the remote machine.
The Garbage Collector uses metadata to keep track of each object's lifecycle, from creation to
destruction.
Reflection
Reflection in Java is a feature that allows a program to examine or modify the behavior of a class,
method, or object at runtime.
It is a relatively advanced feature and should be used only by developers who have a strong grasp of
the fundamentals of the language.
reflection is a powerful technique and can enable applications to perform operations which would
otherwise be impossible.
using reflection, we can:
Obtain information about the class at runtime, such as its name, superclass, implemented
interfaces, constructors, methods, and fields.
Create new objects of a class dynamically, without knowing the class name at compile time.
Access and modify the values of fields in an object, even if they are declared as private.
Invoke methods on an object dynamically, without knowing the method names at compile time.
How to use reflection in Java?
Consider following code:
class Date{
//TODO: Member definition
}
class Address{
//TODO: Member definition
}
class Person{
//TODO: Member definition
}
class Program{
public static void main(String[] args) {
Date birthDate = new Date( 23, 7, 1983 );
Date joinDate = new Date( 1, 1, 2007 );
Address curAddress = new Address( "Pune-46");
Person person = new Person("Sandeep", currentAddress, birthDate );
}
}
When class loader loads Program, String, Date, Address, Person class for execution then it create
instance of [Link] per loaded type on Method area. Instance contains metadata of the
loaded type.
[Link] class
Class class is a final class declared in [Link] package.
The entry point for all reflection operations is [Link].
Instances of the class [Link] represent classes and interfaces in a running Java application.
Class has no public constructor. Instead Class objects are constructed automatically by the Java
Virtual Machine.
Methods of [Link]:
public static Class<?> forName(String className) throws ClassNotFoundException
public Annotation[] getAnnotations()
public Annotation[] getDeclaredAnnotations()
public ClassLoader getClassLoader()
public Constructor<?>[] getConstructors() throws SecurityException
public Constructor getConstructor(Class<?>... parameterTypes) throws
NoSuchMethodException, SecurityException
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException
public Field[] getDeclaredFields() throws SecurityException
public Field getField(String name) throws NoSuchFieldException, SecurityException
public Field[] getFields() throws SecurityException
public Class<?>[] getInterfaces()
public Method[] getMethods() throws SecurityException
public Method[] getDeclaredMethods()throws SecurityException
public String getName()
public String getSimpleName()
public Package getPackage()
public InputStream getResourceAsStream(String name)
public String getTypeName()
public T newInstance() throws InstantiationException, IllegalAccessException
Retrieving Class Objects
Using getClass() method:
int i = 123;
Class<?> c = [Link]( ); //Not OK
Class<?> c = [Link]; //OK
Class<?> c = [Link]; //OK
It is convenient to use .class syntax with primitive type and abstract class.
Using [Link]() method
If the fully-qualified name of a class is available, it is possible to get the corresponding Class
using the static method [Link]().
Class<?> c = [Link];
Class<?> c = [Link]; //OK
Class<?> c = [Link]; //OK
import [Link];
Class<?> sc = [Link]();
String superClassName = [Link]();//Returns the name of the
super class
Class<?>[] si = [Link]();
StringBuffer sb = new StringBuffer();
for (Class<?> i : si) {
[Link]([Link]());//Returns the name of the super
interfaces
}
}
}
import [Link];
import [Link];
public class Program {
public static void main(String[] args) {
Class<?> c = [Link];
Field[] fields = [Link](); //Returns an array of public
fields that are declared in the class or its superclasses
Field[] declaredFields = [Link](); //Returns an array
of all the fields declared in the class
for (Field field : declaredFields) {
String modifiers = [Link]([Link]());
String typeName = [Link]().getSimpleName();
String fieldName = [Link]();
[Link]( modifiers+" "+typeName+" "+fieldName);
}
}
}
getFields() returns an array of public fields that are declared in the class or its superclasses. This
includes fields inherited from the superclass or any interface that the class implements. This method
does not return any private or protected fields, regardless of whether they are inherited or declared in
the class.
getDeclaredFields() returns an array of all the fields declared in the class. This includes public,
private, and protected fields. It does not include any fields inherited from a superclass or an interface.
Examine Method Metadata
import [Link];
import [Link];
import [Link];
getMethods(): This method returns an array of Method objects that represent all the public methods
of the class (including inherited methods) and the public methods declared in any interfaces
implemented by the class.
getDeclaredMethods(): This method returns an array of Method objects that represent all the
methods declared explicitly by the class, including both public and non-public methods. It does not
include any inherited methods or the methods declared in any interfaces implemented by the class.
Accessing private fields using Reflection
import [Link];
class Complex{
private int real;
private int imag;
public Complex() {
[Link] = 10;
[Link] = 20;
}
public int getReal() {
return [Link];
}
public int getImag() {
return [Link];
}
}
public class Program {
public static void main(String[] args) {
try {
Complex complex = new Complex();
[Link]("Real Number : "+[Link]());
[Link]("Imag Number : "+[Link]());
Class<?> c = [Link]();
Field field = null;
field = [Link]("real");
[Link](true);
[Link](complex, 50);
field = [Link]("imag");
[Link](true);
[Link](complex, 60);
import [Link];
import [Link];
class Complex {
private int real;
private int imag;
Middleware Application
//[Link]
public class Calculator {
public double sum( int num1, float num2, double num3) {
return num1 + num2 + num3;
}
public int sub( int num1, int num2 ) {
return num1 + num2;
}
}
//[Link]
class Convert{
public static Object changeType( String type, String value ) {
switch( type ) {
case "int":
return [Link](value);
case "float":
return [Link](value);
case "double":
return [Link](value);
}
return null;
}
}
//[Link]
import [Link];
import [Link];
import [Link];
public class Program {
public static void main(String[] args) {
try( Scanner sc = new Scanner([Link])){
[Link]("Enter F.Q. Class Name : ");
String className = [Link]();
//[Link]
Class<?> c = [Link](className);
Advantages of Reflection:
Dynamic class loading: Reflection allows classes to be loaded and instantiated dynamically, which
can be useful when the class to be used is not known at compile time.
Introspection: Reflection allows the properties and methods of a class to be inspected at runtime.
This can be useful for building tools like debuggers or IDEs, where we need to be able to examine the
structure of a program while it is running.
Frameworks and libraries: Many Java frameworks and libraries make use of reflection to provide
powerful features like dependency injection, ORM, and serialization.
Testing: Reflection can be useful for testing by allowing access to private methods and fields, and for
mocking objects.
Drawbacks of Reflection:
Performance overhead: Reflection operations are slower than direct method calls because they
involve additional runtime checks and lookups.
Security risks: Reflection can be used to bypass access controls and security measures, allowing
malicious code to access private fields and methods or modify the behavior of a program in
unexpected ways.
Complexity and readability: Reflection code can be harder to read and understand, especially for
developers who are not familiar with the language's reflection APIs.
Proxy Design Pattern( Assignment )
The official Java documentation on the Proxy pattern:
[Link]
Reference: The Gang of Four (GoF) book: The GoF book "Design Patterns: Elements of Reusable
Object-Oriented Software".
Multithreading
Singletasking versus multitasking
Process Definition:
Program in execution is called as process.
Running instance of a program is called as process.
Process is also called as task.
Term Singletasking and multitasking is always used in the context of Operating System
An ability of operating system to execute single task at a time is called as Singletasking.
Example: MS DOS is singletasking operating system.
An ability of operating system to execute multiple task at a time is called as Multitasking.
Example: MS Windows, Linuxm Mac OS etc.
Thread concept
Thread Definition
Lightweight process is called as thread.
According to Java, thread is a seperate path of execution which runs independently
Therad always resides in process.
If we want to utilize H/W resources( memory, cpu) efficiently then we should use thread.
If any application take help of single thread for the execution then such application is called as single
threaded application.
If any application take help of multiple threads for the execution then such application is called as
multi threaded application.
Thread is Non Java resource. It is also called unmanged resource.
process based versus thread based multitasking
Before transfering control of CPU from one process to another, schedular must save state of the
process into process control block. Then another process get access of CPU. It is called context
switching.
Since context switching is a heavy task, proess based multitasking is called as heavy weight
multitasking.
Threads always reside into process. Hence to access the resources thread do not require context
switching. So thread based multitasking is called as lightweight multitasking
Java is multithreaded
When we start execution of Java application, JVM starts execution of main thread and Garbage
collector. Due to these threads, every Java application is multithreaded.
Main Thread
It is called as user thread / Non dameon thread.
Main thread is responsible for invoking main method.
In Java, priority of main thread is 5( Thread.NORM_PRIORITY ).
Garbage Collector
It is called as daemon thread / background thread.
Garbage collector is responsible for invoking finalize method and deallocating / releasing
memory of unused objects.
Garbage collector is also called as finalizer.
In Java, priority of garbage collector is 8( Thread.NORM_PRIORITY + 3).
Multithreading in Java
If we want to use threads in Java then we should use Types declared in [Link] package.
Interface(s)
Runnable
Class(es)
Thread
ThreadGroup
ThreadLocal
Enum:
[Link]
Exception
IllegalThreadStateException
IllegalMonitorStateException
InterruptedException
Runnable
It is functional interface declared in [Link] package.
Method:
void run() //Business logic method of thread
To create thread, we can use Runnable interface.
Thread
Nested Type
[Link] is enum declared inside Thread class.
import [Link];
NEW 0
RUNNABLE 1
BLOCKED 2
WAITING 3
TIMED_WAITING 4
TERMINATED 5
Fields:
public static final int MIN_PRIORITY //1
public static final int NORM_PRIORITY //5
public static final int MAX_PRIORITY //10
Constructors
public Thread()
public Thread(String name)
public Thread(Runnable target)
public Thread(Runnable target, String name)
public Thread(ThreadGroup group, Runnable target, String name)
Methods
public static Thread currentThread()
public final String getName()
public final void setName(String name)
public final int getPriority()
public final void setPriority(int newPriority)
public [Link] getState()
public final boolean isAlive()
public final boolean isDaemon()
public final void join() throws InterruptedException
public final void setDaemon(boolean on)
public static void sleep(long millis) throws InterruptedException
public void start()
public static void yield()
Thread creation using [Link] class and Runnable interface
User Thread versus Daemon Thread
Thread termintation
Blocking calls in Thread
Race condition and synchronized keyword
Inter thread communication using wait,notify/notifyAll
Synchronization using consumer/producer
Thread life cycle.
Day 19
Why Java is multi-threaded
When we start execution of Java application then JVM starts execution of main thread and garbage
collector( GC ). Due to these two threads every java application is multithreaded.
Main Thread
It is user thread / non daemon thread.
It is responsible for calling/invoking main method.
Its default priority in 5( In Java, Thread.NORM_PRIORITY ).
Garbage Collector / Finalizer
It is daemon thread / backgrounf thread.
It is responsible for releasing / reclaiming / deallocating memory of unused( whose
reference count is 0 ) instances.
Before releasing memory of unused instance, GC invoke finalize( similar to destructor in
C++) method on instance.
Its default priority in 8( In Java, Thread.NORM_PRIORITY + 3 ).
If we want to use non java resource into Java then we must use Java Native Interface framework.
Thread is non Java resource and to access it we require JNI. But Java application developer need not
to worry avout it. Because SUN/ORACLE developers has already written logic to access OS thread in
Java. In other words, Java has built-in support to thead. Hence java is considered as multithreaded
programming langauge.
Runnable
It is a functional interface declared in [Link] pckage.
"void run( )" is a method of [Link] interface. In the context of multi-threading, run()
method is called as business logic method.
If we want to create thread in Java then we should use Runnable interface.
Thread
[Link] class is a sub class of [Link] class and it implements [Link]
interface.
Thread is non Java resource. In other words, it is unmanaged resource. Hence developer must take
care of its creation as well as termination / dispose.
Instance of [Link] is not a operating system thread. Rather it represents operating system
thread.
package [Link];
public class Thread extends Object implements Runnable{
public static enum State{
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}
}
package [Link];
public class Thread extends Object implements Runnable{
@FunctionalInterface
public static interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
}
Output is:
class Sample{
public Sample( ) {
[Link]("Inside constructor of
"+[Link]().getSimpleName());
}
public void print( ) {
[Link]("Inside print method of
"+[Link]().getSimpleName());
}
@Override
protected void finalize() throws Throwable {
[Link]("Inside finalize method of
"+[Link]().getSimpleName());
Output is
finalize
It is non final method of [Link] class.
If we want to release class level( which is declared as field ) resources then we should
use finalize method.
class Sample{
private Scanner sc; //Field
public Sample( ) {
[Link] = new Scanner( [Link]);
}
//TODO
@Override
protected void finalize() throws Throwable {
[Link]();
}
}
public class Program {
public static void main(String[] args) {
Sample sample = null;
sample = new Sample();
[Link]();
sample = null;
[Link]
}
}
If we call start() method on already started thread then start() method throws
IllegalThreadStateException
When control come out of run method then thread gets terminated. In this case thread is considered
in TERMINATED state.
In following cases, control can come out of run method and thead can terminate:
Successful completion of run method.
Getting exception during execition of run method.
Execution of jump statement( return statement ) inside run method.
If we want to suspend execution of running thread then we should use sleep() method. It is a static
method of [Link] class.
[Link]( 250 )
@Override
public void run() {
//TODO: Business Logic
}
}
public class Program {
public static void main(String[] args) {
Task th1 = new Task("User Thread#1");
Task th2 = new Task("User Thread#2");
}
}
what is the relation between start and run method?
Thread is non Java resource. In other words, it is unmanaged resource. Hence developer must take
care of its creation as well as termination / dispose.
Instance of [Link] is not a operating system thread. Rather it represents operating system
thread.
package [Link];
public class Thread extends Object implements Runnable{
public static enum State{
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}
}
package [Link];
public class Thread extends Object implements Runnable{
@FunctionalInterface
public static interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
}
Output is:
class Sample{
public Sample( ) {
[Link]("Inside constructor of
"+[Link]().getSimpleName());
}
public void print( ) {
[Link]("Inside print method of
"+[Link]().getSimpleName());
}
@Override
protected void finalize() throws Throwable {
[Link]("Inside finalize method of
"+[Link]().getSimpleName());
Output is
finalize
It is non final method of [Link] class.
If we want to release class level( which is declared as field ) resources then we should
use finalize method.
class Sample{
private Scanner sc; //Field
public Sample( ) {
[Link] = new Scanner( [Link]);
}
//TODO
@Override
protected void finalize() throws Throwable {
[Link]();
}
}
public class Program {
public static void main(String[] args) {
Sample sample = null;
sample = new Sample();
[Link]();
sample = null;
[Link]
}
}
If we call start() method on already started thread then start() method throws
IllegalThreadStateException
When control come out of run method then thread gets terminated. In this case thread is considered
in TERMINATED state.
In following cases, control can come out of run method and thead can terminate:
Successful completion of run method.
Getting exception during execition of run method.
Execution of jump statement( return statement ) inside run method.
If we want to suspend execution of running thread then we should use sleep() method. It is a static
method of [Link] class.
[Link]( 250 )
@Override
public void run() {
//TODO: Business Logic
}
}
public class Program {
public static void main(String[] args) {
Task th1 = new Task("User Thread#1");
Task th2 = new Task("User Thread#2");
}
}
what is the relation between start and run method?
What will happen if we call run method instead of start method on thread instance
class Task extends Thread{
public Task( String name ) {
super( name );
}
@Override
public void run() {
[Link]("Inside run method :
"+[Link]().getName());
}
}
public class Program {
public static void main(String[] args) {
Thread thread = new Task( "Thread#1");
//[Link](); //Inside run method : Thread#1
[Link]();//Inside run method : main
}
}
If we call start() method on thread instance then JVM starts execution of new Thread. But if we call
run() method on thread instance then JVM do not start execution of new Thread. In above code, main
therad is calling main method and main method is calling run() method. In directly main thread is
calling run() method.
What is the difference between creating thread using Runnable and Thread class
Runnable
Consider Thread creation using Runnable interface:
class B extends A{
public B( ){
}
@Override
public void run( ){
//TODO: Write business logic here
}
}
class C extends B{
public C( ){
}
@Override
public void run( ){
//TODO: Write business logic here
}
}
class D extends C{
public D( ){
}
@Override
public void run( ){
//TODO: Write business logic here
}
}
If create instance of class B then first A class and then B class constructor will call. In class A, Thread
registration process will start and when OS thread will get CPU then B class run method will call.
Same is the case of class C and D. In simple words, If class implement Runnable interface then that
class and all its sub classes must participate in Threading behavior.
Thread
Consider Thread creation by extending Thread class:
In Java, class can extend more than one class. So here we can not extend another class / if
class already sub class of another class then we can not extend Thread.
Let us try to create sub class of class A
class B extends A{
public B( ){
}
@Override
public void run( ){
//TODO: Write business logic here
}
}
class C extends B{
public C( ){
}
@Override
public void run( ){
//TODO: Write business logic here
}
}
class D extends C{
public D( ){
}
@Override
public synchronized void start() {
//Keep Empty
}
}
In above code class A, B and C must participate into Threading behavior. But by overriding
start( ) method class D can come out of threading behavior.
Types of Thread in java:
User Thread
It is also called as non daemon thread.
If we create any thread from main method / another user thread then it is by default considered
as user thread.
Default Properties of main thead:
Type: User Thread
Priority: 5
Thread group: main
Daemon Thread
It is also called as background thread.
If we create any thread from finalze method / another deamon thread then it is by default
considered as daemon thread.
Default Properties of GC thead:
Type: Daemon Thread
Priority: 8
Thread group: system
Using "public final boolean isDaemon()" method we can check type of thread.
Using "public final void setDaemon(boolean on)" method we can marks thread as either a daemon
thread or a user thread.
When the interrupt signal is sent to the thread, it will set an interrupted flag on the thread. We can
check that flag using isInterrupted() method.
isInterrupted() method only check interrupted status but do not reset the status.
Using interrupted() method we can check interrupted status but it reset interrupted status. In other
words, if this method were to be called twice in succession, the second call would return false
while (![Link]()) {
for (int count = 100; count <= 120; ++count)
[Link]("Count : " + count);
}
}
}
public class Program {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Task());
[Link]();
}
}
Thread Priority
OS schedular is responsible for assigning CPU to the thread.
On the basis of thread priority schedular assign CPU to the thread.
Thread priorities of Java and OS are different.
Thread priorities in Java:
Thread.MIN_PRIORITY = 1;
Thread.NORM_PRIORITY = 5;
Thread.MAX_PRIORITY = 10;
How will you read thread priority in Java?
If we set priority of a thread in Java then OS map it differently on differnt system. Hence Same Java
application produces different behavior on different OS.
Which features of Java makes Java application platform dependent:
Abstract Window Toolkit(AWT) Components
AWT components implicitly use peer classes and these classes has been written into
C++ which are OS specific.
Thread priorities
Thread Join
If we call join method on thread instance then it blocks execution of all other threads
Consider following code:
Race Condition
A race condition is a situation that occurs in a concurrent system when two or more threads or
processes access a shared resource or variable in an uncontrolled order, resulting in unpredictable
and often incorrect behavior.
To prevent race conditions, concurrency control mechanisms such as locks, semaphores, and
monitors can be used to ensure that only one thread at a time can access and modify a shared
resource.
In Java,we can use synchronized keyword with block/method to avoid race condition.
If threads are waiting to get monitor object associated with shared resource then it is consider in
BLOCKED state.
In Java, inter-thread communication is achieved using the wait(), notify() and notifyAll() methods,
which are defined in the Object class.
wait() : This method causes the current thread to wait until another thread invokes the notify()
or notifyAll() method for the same object. The thread will release the lock it holds on the object
and wait until it's notified by another thread.
notify() : This method wakes up a single thread that is waiting on the object. If there are
multiple threads waiting, only one thread will be awakened. The awakened thread will not be
able to proceed until it regains the lock on the object.
notifyAll() : This method wakes up all the threads that are waiting on the object. All the threads
will then compete for the lock on the object.
The JVM throws the IllegalMonitorStateException when a thread attempts to call the wait(), notify(),
or notifyAll() methods on an object without holding the object's monitor.
class TickTock{
public void tick() throws InterruptedException {
synchronized( this ) {
[Link]("Tick ");
[Link]();
[Link]( 1000 ); //To avoid deadlock pass time
}
}
public void tock() throws InterruptedException {
synchronized( this ) {
[Link](" Tock");
[Link]();
[Link]( 1000 ); //To avoid deadlock pass time
}
}
}
@Override
public void run() {
try {
while (true) {
String order = "Burger"; // produce food
[Link](order);
[Link](1000);
}
} catch (InterruptedException e) {
[Link]();
}
}
}
@Override
public void run() {
try {
while (true) {
String order = [Link]();
serve(order); // consume food
[Link](1000);
}
} catch (InterruptedException e) {
[Link]();
}
}
private void serve(String order) {
[Link]("Serving " + order);
}
}
Volatile Fields:
Computers with multiple processors can temporarily hold memory values in registers or local memory
caches. As a consequence, threads running in different processors may see different values for the
same memory location.
class SharedInstance{
int counter = 0;
}
Here we assume that there are two threads are working on SharedInstance.
If these two threads run on different processors then each thread will have its own local copy
of counter.
If we modifies value of one thread, then its value might not reflect in the original one in the
main memory instantly. It is totally depends on the write policy of cache.
Now the other thread is not aware of the modified value which leads to data inconsistency.
If the counter variable is not declared volatile there is no guarantee about when the value of the
counter variable is written from the CPU cache back to main memory. This means, that the
counter variable value in the CPU cache may not be the same as in main memory.
volatile is a keyword in Java which is applicable only for fields.
"DAC";
//{'D','A','C','\0'}
In Java, String is collection of character instances which do not end with '\0' character.
If we want to manipulate String in Java then we can use following classes:
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
If we create String instance using new operator then it gets space on heap section.
String s1 = "CDAC";
//s1 : String reference
//"CDAC" : String literal
If we create String without new operator the it gets space on String literal on method area.
String s1 = "CDAC";
//char[] data = {'C','D','A','C'};
//String s1 = new String( data );
In Java, String do not ends with '\0' character. Using illegal index, if we try to access character from
String then String methods throws StringIndexOutofBoundsException.
Strings are constant; their values cannot be changed after they are created. In other words, String
instances are immutable.
Consider following code:
[Link]([Link]("ACTS")); //CDAC,ACTS
String s2 = [Link]("ACTS");
[Link](s2); //CDAC,ACTS
}
The Java language provides special support for the string concatenation operator ( + ), and for
conversion of other objects to strings.
Using + operator, we can contact any(primitive/non primitive) value to the String but using
concat method we can concat onluy String.
Constant expressions always gets evaluated at compile time. Hence "CDAC,"+"ACTS" will be
considered as "CDAC,ACTS" at compile time.
if( s1 == s2 )
[Link]("Equal");
else
[Link]("Not Equal");
//Output: Not Equal
}
public static void main(String[] args) {
String s1 = "CDAC,ACTS";
String str = "ACTS";
String s2 = "CDAC,"+str;
if( [Link](s2) )
[Link]("Equal");
else
[Link]("Not Equal");
//Output: Equal
}
if( s1 == s2 )
[Link]("Equal");
else
[Link]("Not Equal");
//Output: Equal
}
intern() method returns reference of the String from String pool.
if( [Link](s2) )
[Link]("Equal");
else
[Link]("Not Equal");
//Output: Equal
}
class Date{ }
class Addresss{ }
class Person{
private String name = new String();
private Date birthDate = new Date();
private Address currentAddress = new Address();
}
class Program{
public static void main(String[] args) {
Person p = new Person( );
}
}
In Java, instance do not get space inside another instance. Rather instance contains reference of
another instance.
Library
In Java, .jar file is a library file.
It can contain, menifest file, resources, packages.
Package can contain sub package, interface, class, enum, exception, error, annotation types
Example: [Link]
Framework
framework = collection of libraries + tools + rules/guidelines
It is a development platform which contain reusable partial code on the top of it we can develop
application.
Examples:
JUnit: Unit testing framework which is used to write test case.
Apache Log4j2: Logging framework which is used to record activities.
AWT/Swing/Java-FX: GUI framework.
JNI: Framework to access native code
Struts: Readymade MVC based web application framework.
Hibernate: ORM based automatic persistence framework
Spring: Enterprise framework
Collection
Any instance which contains multiple elements is called as collection.
In java, data structure is also called as collection.
Collection Framework
Collection framework is a library of data structure classes on the top of it we can develop Java
application.
In Java, collection framework talk about use not about implementation.
In Java, when we use collection to store instance then it doesnt contain instance rather it contains
reference of the instance.
To use collection framework, we should import [Link] package.
Iterable
It is interface declared in [Link] package.
It is introduced in jDK 1.5.
Implementing this interface allows an object to be the target of the "for-each loop" statement.
Methods:
Iterator iterator()
default Spliterator spliterator()
default void forEach(Consumer<? super T> action)
Collection
Reference: [Link]
Value stored inside any collection( Array, Stack, Queue, LinkedList etc.) is called as element.
It is interface declared in [Link] package.
It is root interface in the collection framework interface hierarchy.
The JDK does not provide any direct implementations of Collection interface.
Direct implementation classes of Collection interface are AbstractList, AbstractQueue, AbstractSet.
List, Queue, Set are sub interfaces of [Link] interface.
Abstract methods of [Link] interface:
boolean add(E e)
boolean addAll(Collection<? extends E> c)
void clear()
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean isEmpty()
boolean remove(Object o)
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
int size()
Object[] toArray()
T[] toArray(T[] a)
Default methods of [Link] interface:
default Stream stream()
default Stream parallelStream()
default boolean removeIf(Predicate<? super E> filter)
List
This interface is a member of the Java Collections Framework and introduced in JDK 1.2
It is sub interface of Collection interface. It means that all the methods of Collection interafce will be
inherited into List interface.
Direct implementation classes of List interfaces are AbstractList, ArrayList, Vector, Stack, LinkedList.
These collection classes are called as List collections.
Inside List collection we can store data in sequential fashion.
We can store duplicate elements inside any List collection.
We can store multiple null values inside List collection.
With the help of integer index, we can access elements from List collection.
We can traverse elements of any List collection using Iterator as well as ListIterator.
This interface is a member of the Java Collections Framework.
Abstract methods of [Link] interface:
void add(int index, E element)
boolean addAll(int index, Collection<? extends E> c)
E remove(int index)
E get(int index)
E set(int index, E element)
int indexOf(Object o)
int lastIndexOf(Object o)
ListIterator listIterator()
ListIterator listIterator(int index)
List subList(int fromIndex, int toIndex)
Default methods of [Link] interface:
default void sort(Comparator<? super E> c)
default void replaceAll(UnaryOperator operator)
Note: If we want to manage elements of non final type inside any List collection then we should
override at least equals methods inside non final type.
ArrayList
Array is collection of fixed elements. ArrayList is resizeable array.
Implementation of ArrayList is based of array.
ArrayList is List collection.
Since ArrayList is List collection we can store elements sequentially.
Since ArrayList is List collection, we can store duplicate elements as well as null elements inside
ArrayList.
Since ArrayList is List collection, we can access its elements using integer index.
Since ArrayList is List collection, we can traverse its elements using Iterator as well as ListIterator.
ArrayList implementation is unsynchronized. Using [Link]() method we can
make it synchronized.
If ArrayList is full then its capacity gets increased by half of existing capacity.
This class is a member of the Java Collections Framework and introduced in JDK 1.2.
Constructor Summary of ArrayList class:
public ArrayList()
//Object[] elementData;
private static int capacity(List<Integer> list) throws Exception{
Class<?> c = [Link]();
Field field = [Link]("elementData");
[Link](true);
Object[] elementData = (Object[]) [Link](list);
return [Link];
}
public static void main(String[] args) {
try {
List<Integer> list = [Link]();
[Link]("Size : "+[Link]()); //5
How will you search and remove single element from ArrayList?
class Date{ }
class Addresss{ }
class Person{
private String name = new String();
private Date birthDate = new Date();
private Address currentAddress = new Address();
}
class Program{
public static void main(String[] args) {
Person p = new Person( );
}
}
In Java, instance do not get space inside another instance. Rather instance contains reference of
another instance.
Library
In Java, .jar file is a library file.
It can contain, menifest file, resources, packages.
Package can contain sub package, interface, class, enum, exception, error, annotation types
Example: [Link]
Framework
framework = collection of libraries + tools + rules/guidelines
It is a development platform which contain reusable partial code on the top of it we can develop
application.
Examples:
JUnit: Unit testing framework which is used to write test case.
Apache Log4j2: Logging framework which is used to record activities.
AWT/Swing/Java-FX: GUI framework.
JNI: Framework to access native code
Struts: Readymade MVC based web application framework.
Hibernate: ORM based automatic persistence framework
Spring: Enterprise framework
Collection
Any instance which contains multiple elements is called as collection.
In java, data structure is also called as collection.
Collection Framework
Collection framework is a library of data structure classes on the top of it we can develop Java
application.
In Java, collection framework talk about use not about implementation.
In Java, when we use collection to store instance then it doesnt contain instance rather it contains
reference of the instance.
To use collection framework, we should import [Link] package.
Iterable
It is interface declared in [Link] package.
It is introduced in jDK 1.5.
Implementing this interface allows an object to be the target of the "for-each loop" statement.
Methods:
Iterator iterator()
default Spliterator spliterator()
default void forEach(Consumer<? super T> action)
Collection
Reference: [Link]
Value stored inside any collection( Array, Stack, Queue, LinkedList etc.) is called as element.
It is interface declared in [Link] package.
It is root interface in the collection framework interface hierarchy.
The JDK does not provide any direct implementations of Collection interface.
Direct implementation classes of Collection interface are AbstractList, AbstractQueue, AbstractSet.
List, Queue, Set are sub interfaces of [Link] interface.
Abstract methods of [Link] interface:
boolean add(E e)
boolean addAll(Collection<? extends E> c)
void clear()
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean isEmpty()
boolean remove(Object o)
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
int size()
Object[] toArray()
T[] toArray(T[] a)
Default methods of [Link] interface:
default Stream stream()
default Stream parallelStream()
default boolean removeIf(Predicate<? super E> filter)
List
This interface is a member of the Java Collections Framework and introduced in JDK 1.2
It is sub interface of Collection interface. It means that all the methods of Collection interafce will be
inherited into List interface.
Direct implementation classes of List interfaces are AbstractList, ArrayList, Vector, Stack, LinkedList.
These collection classes are called as List collections.
Inside List collection we can store data in sequential fashion.
We can store duplicate elements inside any List collection.
We can store multiple null values inside List collection.
With the help of integer index, we can access elements from List collection.
We can traverse elements of any List collection using Iterator as well as ListIterator.
This interface is a member of the Java Collections Framework.
Abstract methods of [Link] interface:
void add(int index, E element)
boolean addAll(int index, Collection<? extends E> c)
E remove(int index)
E get(int index)
E set(int index, E element)
int indexOf(Object o)
int lastIndexOf(Object o)
ListIterator listIterator()
ListIterator listIterator(int index)
List subList(int fromIndex, int toIndex)
Default methods of [Link] interface:
default void sort(Comparator<? super E> c)
default void replaceAll(UnaryOperator operator)
Note: If we want to manage elements of non final type inside any List collection then we should
override at least equals methods inside non final type.
ArrayList
Array is collection of fixed elements. ArrayList is resizeable array.
Implementation of ArrayList is based of array.
ArrayList is List collection.
Since ArrayList is List collection we can store elements sequentially.
Since ArrayList is List collection, we can store duplicate elements as well as null elements inside
ArrayList.
Since ArrayList is List collection, we can access its elements using integer index.
Since ArrayList is List collection, we can traverse its elements using Iterator as well as ListIterator.
ArrayList implementation is unsynchronized. Using [Link]() method we can
make it synchronized.
If ArrayList is full then its capacity gets increased by half of existing capacity.
This class is a member of the Java Collections Framework and introduced in JDK 1.2.
Constructor Summary of ArrayList class:
public ArrayList()
//Object[] elementData;
private static int capacity(List<Integer> list) throws Exception{
Class<?> c = [Link]();
Field field = [Link]("elementData");
[Link](true);
Object[] elementData = (Object[]) [Link](list);
return [Link];
}
public static void main(String[] args) {
try {
List<Integer> list = [Link]();
[Link]("Size : "+[Link]()); //5
How will you search and remove single element from ArrayList?
During traversing, without iterator, if we try to make changes in underlying collection and if we do not
get ConcurrentModificationException then such iterator is called as fail-safe Iterator. Such iterators
works by creating copy of the Collection.
LinkedList
Deque
It is sub interface of Queue interface.
The name deque is short for "double ended queue" and is usually pronounced "deck".
This interface is a member of the Java Collections Framework.
It is introduced in JDK 1.6
Set
It is sub interface of [Link] interface.
HashSet, LinkedHashSet, TreeSet, EnumSet are Set collections.
Set Collections do not contain duplicate elements.
This interface is a member of the Java Collections Framework.
It is introduced in JDK 1.2
Method names of Collection and Set interface are same. No new method is added in Set interafce.
What is the difference between List and Set?
ArrayList, Vector, LinkedList are List Collections and HashSet, LinkedHashSet, TreeSet are Set
collections
List collections can contain duplicate elements but Set collections do not contain duplicate elements.
List collections can contain null elements but not all Set collections contain null elements.
We can traverse elements of List collection using ListIterator as well as Iterator but we can we can
traverse elements of Set collection using Iterator only.
All List collections are sequential collections but we can not give gurantee of order of elements in Set
collection.
TreeSet
It is a Set collection.
It can not contain duplicate elements.
It can not contain null elements.
It contains data in sorted order.
TreeSet implementation is based on TreeMap<K,V>.
It is unsynchronized collection. Using [Link]() method we can make it
synchronized.
This class is a member of the Java Collections Framework.
It is introduced in JDK 1.2
Note: If we want to use TreeSet to store elements of non final type then non final type should
implement Comparable interface.
How to create instance of TreeSet
[Link](50);
[Link](10);
[Link](30);
[Link](20);
[Link](40);
[Link]( set );
}
Algorithm
In Computer science algorithm and data structure are two different branches.
Data structure describes 2 things:
How to organize data inside RAM?
Which operations should be used to organize data inside RAM.
Data structure can be linear / non linear.
Well defined set of statements that we can use to solve real world common problems is called as
algorithms.
In the context of data structure algorithms can be searching / sorting algorithms.
Searching
Searching refers to the process of finding location( index / reference ) of an element in Collection.
The collection of data may be in array, list, database, or any other data structure.
There are several searching algorithms, each with its own strengths and weaknesses:
Linear search
Binary search
Hashing
Interpolation search
Exponential search
Linear Search
Linear search is a simple searching algorithm that sequentially searches each element in a collection
until the desired item is found.
Consider following code:
Hashing is a technique used to store and retrieve data in a fast and efficient manner.
Hashing searching is based on hash code.
Hashcode is not an index / address / reference. It is a logical integer number that can be generated by
processing state of the instance.
To generate hash code we should use hash function. Consider following example
In the context of hashing, a slot refers to a location in the hash table where a key-value pair can be
stored.
In other words, hash code is required to generate index which is called as slot in hashing.
By Processing state of the instance, if we get same slot then it is called as collision.
To avoid collision, we can maintain one collection(LinkedList/BST) per slot. It is called as bucket.
Note: If we want to store any element of non primitive type inside Hashcode based collection then we
should override equals and hashCode method inside non primitive type.
Pros of Hashing
Fast retrieval: Hashing allows for constant-time retrieval of data, regardless of the size of the
data set. This makes it a very efficient searching algorithm.
Flexibility: Hashing can be used to search for any type of data, including strings, numbers, and
custom objects.
Easy to implement
Supports dynamic resizing: Hash tables can be resized dynamically to accommodate more
data, without having to recreate the entire data structure.
Cons of Hashing:
Hash collisions: Hash collisions occur when two different keys are mapped to the same hash
value. This can result in slower lookup times and may require additional processing to resolve
the collision.
Memory usage: Hash tables can consume a lot of memory, particularly if the data set is large.
This can lead to performance issues if the available memory is limited.
Hash functions: The efficiency of hashing depends on the quality of the hash function used.
Poor hash functions can lead to more collisions, slower retrieval times, and other issues.
equals and hashCode are non final methods of [Link] class.
If we do not override equals method then super class's equals method will call. equals method of
Object class do not compare state of instances. It compares state of references.
Consider equals method definition of Object class:
hashCode() method of [Link] class convert memory address of instance into integer value.
Hence even though state of the instances are same we get different hashCode. If we want hashCode
based on state of the instance then we should override hashCode method inside class.
Consider implementation:
@Override
public int hashCode() {
int prime = 31;
int result = 1;
result = result * prime + [Link];
return result;
}
HashSet
It is hashCode based collection whose implementation is based on Hashtable.
In HashSet elements get space according its hash code hence It doesn't give any gurantee about
order of the elements.
Since it is Set collection, it doesn't contain duplicate elements.
HashSet can contain null element.
It is unsynchronized collection. Using [Link]() method we can consider it
synchronized.
This class is a member of the Java Collections Framework.
It is introduced in JDK 1.2
If we want to use any element of non final type inside HashSet then non final type should override
equals() and hashCode() method.
Instantiation of HashSet:
[Link](101);
[Link](125);
[Link](13);
[Link](314);
[Link](215);
[Link](null);
[Link](set); //[null, 101, 215, 314, 125, 13]
}
LinkedHashSet
It is hashCode based collection whose implementation is based on Hashtable and LinkedList.
During traversing it maintains order of lements.
Since it is Set collection, it doesn't contain duplicate elements.
HashSet can contain null element.
It is unsynchronized collection. Using [Link]() method we can consider it
synchronized.
This class is a member of the Java Collections Framework.
It is introduced in JDK 1.4
If we want to use any element of non final type inside HashSet then non final type should override
equals() and hashCode() method.
Dictionary<K,V>
Dictionary<K,V> is abstract class declared in [Link] package.
We can use it store elements in key value pair format.
Hashtable is sub class of Dictionary<K,V> class.
It was introduced in JDK 1.0
Method Summary
public abstract V put(K key, V value)
public abstract int size()
public abstract V get(Object key)
public abstract V remove(Object key)
public abstract boolean isEmpty()
public abstract Enumeration keys()
public abstract Enumeration elements()
Consider example of Dictionary class:
import [Link];
import [Link];
import [Link];
public class Program {
public static Dictionary<Integer, String> getDictionary( ){
Dictionary<Integer, String> d = new Hashtable<>(); //Upcasting
[Link](1,"PreDAC");
[Link](2,"DAC");
[Link](3,"DMC");
[Link](4,"DIVESD");
[Link](5,"DESD");
[Link](6,"DBDA");
return d;
}
private static void countAndPrintEntries(Dictionary<Integer, String>
d) {
[Link]("Count of entries : "+[Link]());
}
private static void printKeys(Dictionary<Integer, String> d) {
Enumeration<Integer> keys = [Link]();
Integer key = null;
while( [Link]()) {
key = [Link]();
[Link]( key );
}
}
private static void printValues(Dictionary<Integer, String> d) {
Enumeration<String> values = [Link]();
String value = null;
while( [Link]()) {
value = [Link]();
[Link](value);
}
}
private static void printValue(Dictionary<Integer, String> d, int
courseId) {
Integer key = new Integer( courseId );
String value = [Link](key);
if( value != null )
[Link](key+" "+value);
else
[Link]("Invalid key");
}
private static void removeEntry(Dictionary<Integer, String> d, int
courseId) {
Integer key = new Integer( courseId );
String value = [Link](key);
if( value != null )
[Link](key+" "+value+" is removed");
else
[Link]("Invalid key");
}
public static void main(String[] args) {
Dictionary<Integer, String> d = [Link]();
//[Link]( d );
//[Link]( d );
//[Link]( d );
//[Link]( d, 2 );
[Link]( d, 200);
}
}
This class is obsolete. New implementations should implement the Map interface, rather than
extending this class.
Map<K,V>
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];