KEMBAR78
Unit 2 Notes | PDF | Java Virtual Machine | Java (Programming Language)
0% found this document useful (0 votes)
17 views32 pages

Unit 2 Notes

Java is a class-based, object-oriented programming language known for its platform independence, simplicity, robustness, and security features, allowing developers to write code that can run on any system supporting Java. Key features include object-oriented programming principles, multithreading, and high performance through the Java Virtual Machine (JVM), which executes compiled bytecode. The document also covers Java's data types, operators, arrays, and the structure of classes and objects.

Uploaded by

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

Unit 2 Notes

Java is a class-based, object-oriented programming language known for its platform independence, simplicity, robustness, and security features, allowing developers to write code that can run on any system supporting Java. Key features include object-oriented programming principles, multithreading, and high performance through the Java Virtual Machine (JVM), which executes compiled bytecode. The document also covers Java's data types, operators, arrays, and the structure of classes and objects.

Uploaded by

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

Introduction to Java

Java is a class-based, object-oriented programming language that is designed to have as few


implementation dependencies as possible. It is intended to let application developers Write
Once and Run Anywhere (WORA), meaning that compiled Java code can run on all platforms
that support Java without the need for recompilation. Java was developed by James
Gosling at Sun Microsystems Inc. in May 1995 and later acquired by Oracle
Corporation and is widely used for developing applications for desktop, web, and mobile
devices.

Java is known for its simplicity, robustness, and security features, making it a popular choice for
enterprise-level applications. Java applications are compiled to byte code that can run on any
Java Virtual Machine.

Key Features of Java


1. Platform Independent

Compiler converts source code to byte code and then the JVM executes the bytecode generated
by the compiler. This byte code can run on any platform be it Windows, Linux, or macOS which
means if we compile a program on Windows, then we can run it on Linux and vice versa. Each
operating system has a different JVM, but the output produced by all the OS is the same after the
execution of the byte code. That is why we call java a platform-independent language.

2. Object-Oriented Programming

Java is an object-oriented language, promoting the use of objects and classes. Organizing the
program in the terms of a collection of objects is a way of object-oriented programming, each of
which represents an instance of the class.

The four main concepts of Object-Oriented programming are:

Abstraction

Encapsulation

Inheritance

Polymorphism

3. Simplicity

Java’s syntax is simple and easy to learn, especially for those familiar with C or C++. It
eliminates complex features like pointers and multiple inheritances, making it easier to write,
debug, and maintain code.
4. Robustness

Java language is robust which means reliable. It is developed in such a way that it puts a lot of
effort into checking errors as early as possible, that is why the java compiler is able to detect
even those errors that are not easy to detect by another programming language. The main
features of java that make it robust are garbage collection, exception handling, and memory
allocation.

5. Security

In java, we don’t have pointers, so we cannot access out-of-bound arrays i.e it


shows ArrayIndexOutOfBound Exception if we try to do so. That’s why several security flaws
like stack corruption or buffer overflow are impossible to exploit in Java. Also, java programs
run in an environment that is independent of the os(operating system) environment which makes
java programs more secure.

6. Distributed

We can create distributed applications using the java programming language. Remote Method
Invocation and Enterprise Java Beans are used for creating distributed applications in java. The
java programs can be easily distributed on one or more systems that are connected to each other
through an internet connection.

7. Multithreading

Java supports multithreading, enabling the concurrent execution of multiple parts of a program.
This feature is particularly useful for applications that require high performance, such as games
and real-time simulations.

8. Portability

As we know, java code written on one machine can be run on another machine. The platform-
independent feature of java in which its platform-independent bytecode can be taken to any
platform for execution makes java portable. WORA(Write Once Run Anywhere) makes java
application to generates a ‘.class’ file that corresponds to our applications(program) but contains
code in binary format. It provides ease t architecture-neutral ease as bytecode is not dependent on
any machine architecture. It is the primary reason java is used in the enterprising IT industry
globally worldwide.

9. High Performance

Java architecture is defined in such a way that it reduces overhead during the runtime and at
some times java uses Just In Time (JIT) compiler where the compiler compiles code on-demand
basis where it only compiles those methods that are called making applications to execute faster.
Java Virtual Machine Concepts

Java Virtual Machine(JVM)


JVM(Java Virtual Machine) runs Java applications as a run-time engine. JVM is the one that
calls the main method present in a Java code. JVM is a part of JRE(Java Runtime Environment).

Java applications are called WORA (Write Once Run Anywhere). This means a programmer can
develop Java code on one system and expect it to run on any other Java-enabled system without
any adjustment. This is all possible because of JVM.

When we compile a .java file, .class files(contains byte-code) with the same class names present
in .java file are generated by the Java compiler. This .class file goes into various steps when we
run it. These steps together describe the whole JVM.

1. Class Loader Subsystem

It is mainly responsible for three activities.

Loading

Linking

Initialization

Loading:

The Class loader reads the “.class” file, generate the corresponding binary data and save it in the
method area.

Linking
Performs verification, preparation, and (optionally) resolution.

Verification - It ensures the correctness of the .class file. This activity is done by the
component ByteCodeVerifier. Once this activity is completed then the class file is ready for
compilation.

Preparation - JVM allocates memory for class static variables and initializing the
memory to default values.

Resolution: It is the process of replacing symbolic references from the type with direct
references.

Initialization

In this phase, all static variables are assigned with their values defined in the code and static
block(if any). In general, there are three class loaders:

Bootstrap class loader: Every JVM implementation must have a bootstrap class loader, capable
of loading trusted classes.

Extension class loader: It is a child of the bootstrap class loader. It loads the classes present in
the extensions directories.

System/Application class loader: It is a child of the extension class loader. It is responsible to


load classes from the application classpath. It internally uses Environment Variable which
mapped to java.class.path.

2. JVM Memory Areas

Method area: In the method area, all class level information like class name, immediate parent
class name, methods and variables information etc. are stored, including static variables. There is
only one method area per JVM, and it is a shared resource.

Heap area: Information of all objects is stored in the heap area. There is also one Heap Area per
JVM. It is also a shared resource.

Stack area: For every thread, JVM creates one run-time stack which is stored here. Every block
of this stack is called activation record/stack frame which stores methods calls. All local
variables of that method are stored in their corresponding frame. After a thread terminates, its
run-time stack will be destroyed by JVM. It is not a shared resource.

PC Registers: Store address of current execution instruction of a thread. Obviously, each thread
has separate PC Registers.

Native method stacks: For every thread, a separate native stack is created. It stores native
method information.
3. Execution Engine

Execution engine executes the “.class” (bytecode). It reads the byte-code line by line, uses data
and information present in various memory area and executes instructions. It can be classified
into three parts:

Interpreter: It interprets the bytecode line by line and then executes. The disadvantage here is
that when one method is called multiple times, every time interpretation is required.

Just-In-Time Compiler(JIT) : It is used to increase the efficiency of an interpreter. It compiles


the entire bytecode and changes it to native code so whenever the interpreter sees repeated
method calls, JIT provides direct native code for that part so re-interpretation is not required,
thus efficiency is improved.

Garbage Collector: It destroys un-referenced objects.

4. Java Native Interface (JNI)

It is an interface that interacts with the Native Method Libraries and provides the native
libraries(C, C++) required for the execution. It enables JVM to call C/C++ libraries and to be
called by C/C++ libraries which may be specific to hardware.

5. Native Method Libraries

These are collections of native libraries required for executing native methods. They include
libraries written in languages like C and C++.

Primitive Data Types and Variables in Java


Data types in Java are of different sizes and values that can be stored in the variable that is made
as per convenience and circumstances to cover up all test cases. Java has two categories in which
data types are segregated

Primitive Data Type: such as boolean, char, int, short, byte, long, float, and double. The
Boolean with uppercase B is a wrapper class for the primitive data type boolean in Java.

Non-Primitive Data Type or Object Data type: such as String, Array, etc.

Primitive Data Types in Java

Primitive data are only single values and have no special capabilities. There are 8 primitive data
types. They are depicted below in tabular format below as follows:
Descriptio Defaul Siz Example
Type n t e Literals Range of values

boolea 8
true or false false true, false true, false
n bits

twos-
8
complement 0 (none) -128 to 127
bits
byte integer

‘a’, ‘\u0041’, ‘\ characters representation


Unicode 16
\u0000 101’, ‘\\’, ‘\’, ‘\ of ASCII values
character bits
char n’, ‘β’ 0 to 255

twos-
16
complement 0 (none) -32,768 to 32,767
bits
short integer

twos- -2,147,483,648
32
complement 0 -2,-1,0,1,2 to
bits
int intger 2,147,483,647

-
9,223,372,036,854,775,80
twos-
64 -2L,- 8
complement 0
bits 1L,0L,1L,2L to
integer
9,223,372,036,854,775,80
long 7

1.23e100f , -
IEEE 754 32 1.23e-
0.0 upto 7 decimal digits
floating point bits 100f , .3f ,3.1
float 4F

1.23456e300
IEEE 754 64
0.0 d , -123456e- upto 16 decimal digits
floating point bits
double 300d , 1e1d
Variables:

A variable is a container for storing data values. In Java, variables must be declared with a
specific type before they can be used.

Syntax:

<datatype><variable_name> = <value>;

Example:

intage=25; // Declares an int variable 'age' with value 25

Java Operators

Operators in Java are special symbols or keywords used to perform operations on operands. They
can be categorized into various types:

1. Arithmetic Operators:
o + (Addition)
o - (Subtraction)
o * (Multiplication)
o / (Division)
o % (Modulo)

Example:

inta=10, b = 5;
intsum= a + b; // sum = 15

2. Relational Operators:
o == (Equal to)
o != (Not equal to)
o > (Greater than)
o < (Less than)
o >= (Greater than or equal to)
o <= (Less than or equal to)

Example:

inta=10, b = 5;
booleanresult= a >b; // result = true

3. Logical Operators:
o && (Logical AND)
o || (Logical OR)
o ! (Logical NOT)

Example:

booleanx=true, y = false;
booleanresult= x &&y; // result = false

4. Assignment Operators:
o = (Assigns a value)

+= , Add and assign.


-= , Subtract and assign.
*= , Multiply and assign.
/= , Divide and assign.
%= , Modulo and assign.

Example:

inta=5;
a += 3; // a = 8

5. Unary Operators:
o ++ (Increment)
o -- (Decrement)
o + (Unary plus)
o - (Unary minus)

Example:

inta=10;
a++; // a = 11

6. Ternary Operator:
o condition ? expr1 : expr2; (If-Else shorthand)

Example:

inta=10, b = 5;
intresult= (a > b) ? a : b; // result = 10

7. Bitwise Operators:
o & (Bitwise AND) – returns bit-by-bit AND of input values.
o | (Bitwise OR) – returns bit-by-bit OR of input values.
o ^ (Bitwise XOR) – returns bit-by-bit XOR of input values.
o ~ (Bitwise Complement) – inverts all bits

Java Expressions and Statements

 Expression: An expression is a combination of variables, operators, and method calls


that produce a value. Example:

intsum= a + b; // 'a + b' is an expression

 Statement: A statement in Java is a complete unit of execution. A statement can be a


declaration, a method call, or a control structure. Example:

inta=10; // Declaration statement


System.out.println("Hello, World!"); // Method call statement

Java statements include control flow statements like:

 if-else: Conditional branching


 for, while, do-while: Loops
 switch: Multi-way branching

Arrays in Java

Arrays are fundamental structures in Java that allow us to store multiple values of the
same type in a single variable. They are useful for storing and managing collections of data.

There are some basic operations we can start with as mentioned below:

1. Array Declaration

To declare an array in Java, use the following syntax:

type[] arrayName;

type: The data type of the array elements (e.g., int, String).

arrayName: The name of the array.

2. Create an Array

To create an array, you need to allocate memory for it using the new keyword:

// Creating an array of 5 integers


numbers = new int[5];
This statement initializes the numbers array to hold 5 integers. The default value for each
element is 0.

3. Access an Element of an Array

We can access array elements using their index, which starts from 0:

// Setting the first element of the array


numbers[0] = 10;

// Accessing the first element


int firstElement = numbers[0];

The first line sets the value of the first element to 10. The second line retrieves the value of the
first element.

4. Change an Array Element

To change an element, assign a new value to a specific index:

// Changing the first element to 20


numbers[0] = 20;

5. Array Length

We can get the length of an array using the length property:

// Getting the length of the array


int length = numbers.length;

Example:

public class ArrayExample {

public static void main(String[] args) {

int[] arr = {1, 2, 3, 4, 5};

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

System.out.println(arr[i]);

}
Class and Objects in Java

In Java, classes and objects are the foundational concepts of object-oriented programming
(OOP). A class is a blueprint or template for creating objects, which are instances of the class.
Let's explore these concepts in detail.

Class in Java

A class in Java is a blueprint that defines the structure and behavior (attributes and methods) that
objects created from the class will have. It is essentially a user-defined data type that can hold
variables (fields) and methods (functions) that operate on these variables.

Basic Structure of a Class:


classClassName {
// Fields (attributes)
dataTypefieldName;

// Constructor(s)
publicClassName() {
// Initialization code
}

// Methods (behavior)
publicreturnTypemethodName() {
// Method body
}
}

Key Points:

 Fields (also called properties or attributes) represent the state of an object.


 Methods (also called functions) represent the behavior of an object.
 A constructor is a special method used to initialize objects of the class.

Example of a Simple Class:


classCar {
// Fields (Attributes)
String model;
String color;
intyear;

// Constructor to initialize the object


publicCar(String model, String color, intyear) {
this.model = model;
this.color = color;
this.year = year;
}

// Method to display car details


publicvoiddisplayInfo() {
System.out.println("Model: " + model);
System.out.println("Color: " + color);
System.out.println("Year: " + year);
}
}

In the above example:

 The Car class has three fields: model, color, and year.
 The Car constructor initializes the object with specific values for these fields.
 The displayInfo method displays the car's information.

Object in Java

An object is an instance of a class. While a class is a blueprint, an object is a concrete instance


that contains actual values for its fields. Objects are created using the new keyword.

Creating and Using Objects:

To create an object, you use the new keyword followed by the constructor of the class.

CarmyCar=newCar("Toyota Corolla", "Red", 2020);


myCar.displayInfo();

In the above example:

 myCar is an object of the Car class.


 The constructor is called with specific values ("Toyota Corolla", "Red", 2020) to initialize
the object.
 The displayInfo() method is called to print the details of the myCar object.

Class and Object Example

Let’s create a practical example where we define a Person class with fields and methods, and
create objects of the Person class.

classPerson {
// Fields (Attributes)
String name;
intage;

// Constructor to initialize the object


publicPerson(String name, int age) {
this.name = name;
this.age = age;
}

// Method to display person's details


publicvoidintroduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years
old.");
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
// Creating objects of the Person class
Personperson1=newPerson("Alice", 30);
Personperson2=newPerson("Bob", 25);

// Calling methods on the objects


person1.introduce(); // Outputs: Hello, my name is Alice and I am 30
years old.
person2.introduce(); // Outputs: Hello, my name is Bob and I am 25
years old.
}
}

Explanation:

 The Person class has two fields: name and age, which define the state of a person.
 The introduce() method is used to print a greeting message, describing the person.
 The Main class contains the main method, where two Person objects (person1 and person2) are
created using the constructor, and their introduce() method is called to display their details.

Memory and Object Instantiation

When you create an object using the new keyword:

1. Memory is allocated for the object on the heap.


2. The constructor of the class is called to initialize the object.
3. The reference variable (like person1) holds the memory address of the object created in the heap.

Class vs. Object

 Class: A blueprint or template for creating objects. It defines the attributes (fields) and behavior
(methods) of the objects.
 Object: An instance of a class that holds specific data and can perform actions defined in the
class.

Methods

A method in Java consists of the following components:

 Method Signature: This includes the method name, the return type, and any parameters.
 Method Body: This contains the actual code that defines what the method does.

Syntax:
returnTypemethodName(parameterList) {
// Method body
}

 Return Type: Specifies the type of value the method will return (e.g., int, String, void
for no return value).
 Method Name: The name of the method, which should be a valid Java identifier.
 Parameter List: A comma-separated list of parameters that the method accepts
(optional).
 Method Body: The block of code enclosed in curly braces {} that executes when the method is
called.

Example of a simple method:


publicintaddNumbers(int a, int b) {
return a + b;
}
This method addNumbers takes two integer parameters a and b, and returns their sum.

Static Methods
A static method belongs to the class rather than to instances (objects) of the class. This means
you can call static methods without creating an object of the class. Static methods are declared using the
static keyword.

 Static methods are called on the class itself, not on instances of the class.
 Static methods can only directly access other static members (fields and methods) of the
class.
 Static methods cannot use instance variables or instance methods directly because they do not
operate on an instance of the class.

Syntax of Static Method:


publicstaticreturnTypemethodName(parameterList) {
// Method body
}

Example of a Static Method:


classCalculator {
// Static method
publicstaticintmultiply(int a, int b) {
return a * b;
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
// Calling the static method without creating an instance of Calculator
intresult=Calculator.multiply(4, 5);
System.out.println("The result is: " + result);
}
}

In this example:

 The multiply method is a static method of the Calculator class.


 The method is called using the class name Calculator.multiply(4, 5) without
creating an object of the Calculator class.

Restrictions of Static Methods:

 Static methods cannot access instance variables or instance methods directly, because
they are not associated with any specific instance of the class.
 They can only call other static methods and access static fields in the same class.

Constructors

A constructor is a special type of method used to initialize objects. It has the same name as the
class and does not have a return type (not even void).

Types of Constructors:

1. Default Constructor: A constructor that does not take any arguments. If you don’t
provide any constructor, Java provides a default one.

classCar {
String model;
String color;
intyear;

// Default constructor
publicCar() {
model = "Unknown";
color = "Unknown";
year = 0;
}
}

2. Parameterized Constructor: A constructor that takes arguments to initialize an object


with specific values.

classCar {
String model;
String color;
intyear;
// Parameterized constructor
publicCar(String model, String color, intyear) {
this.model = model;
this.color = color;
this.year = year;
}
}

Example with Constructors:

classCar {
String model;
String color;
intyear;

// Constructor to initialize the object


publicCar(String model, String color, intyear) {
this.model = model;
this.color = color;
this.year = year;
}

// Method to display car details


publicvoiddisplayInfo() {
System.out.println("Model: " + model);
System.out.println("Color: " + color);
System.out.println("Year: " + year);
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
// Creating objects of the Car class with the parameterized constructor
Carcar1=newCar("Tesla Model 3", "White", 2021);
Carcar2=newCar("BMW X5", "Black", 2020);

// Calling methods on the objects


car1.displayInfo(); // Outputs the details of car1
car2.displayInfo(); // Outputs the details of car2
}
}

Constructor Overloading

Constructor overloading in Java allows you to define multiple constructors with different
parameters in the same class. This enables you to create objects in different ways, depending on
the constructor used.

In Java, a constructor is a special method used to initialize objects. A constructor has the same
name as the class and does not have a return type.

 Constructor overloading happens when you define more than one constructor in the same
class with the same name but with different parameter lists (different number, types, or order of
parameters).
 Java will choose which constructor to call based on the arguments passed during object
creation.

Example of Constructor Overloading:


classCar {
String model;
intyear;
String color;

// Default constructor (no parameters)


publicCar() {
model = "Unknown";
year = 2020;
color = "Black";
}

// Constructor with one parameter


publicCar(String model) {
this.model = model;
this.year = 2020;
this.color = "Black";
}

// Constructor with two parameters


publicCar(String model, intyear) {
this.model = model;
this.year = year;
this.color = "Black";
}

// Constructor with three parameters


publicCar(String model, int year, String color) {
this.model = model;
this.year = year;
this.color = color;
}
// Method to display details of the car
publicvoiddisplay() {
System.out.println("Model: " + model + ", Year: " + year + ", Color: " +
color);
}
}
publicclassMain {
publicstaticvoidmain(String[] args) {
// Using different constructors
Carcar1=newCar(); // Calls the default constructor
Carcar2=newCar("Tesla"); // Calls constructor with one parameter
Carcar3=newCar("BMW", 2021); // Calls constructor with two parameters
Carcar4=newCar("Audi", 2023, "Red"); // Calls constructor with three
parameters
// Displaying the car details
car1.display();
car2.display();
car3.display();
car4.display();
}
}

Rules for Constructor Overloading

Different parameter lists: The constructors should differ in the number, types, or order of
parameters.

Cannot differ by return type: Constructor overloading cannot be based on different return
types, because constructors do not have return types.

this Keyword

In Java, the this keyword is a reference variable that refers to the current instance of the class. It
is commonly used within instance methods and constructors to refer to the current object's
instance variables and methods. The this keyword can also be used to differentiate between
instance variables and local variables that have the same name.

1) this: to refer current class instance variable


The this keyword can be used to refer current class instance variable. If there is ambiguity
between the instance variables and parameters, this keyword resolves the problem of
ambiguity.

2) this: to invoke current class method


You may invoke the method of the current class by using the this keyword. If you don't use
the this keyword, compiler automatically adds this keyword while invoking the method. Let's
see the example
3) this() : to invoke current class constructor
The this() constructor call can be used to invoke the current class constructor. It is used to
reuse the constructor. In other words, it is used for constructor chaining.

4) this: to pass as an argument in the method


The this keyword can also be passed as an argument in the method. It is mainly used in the
event handling.

5) this: to pass as argument in the constructor call


We can pass the this keyword in the constructor also. It is useful if we have to use one
object in multiple classes.

6) this keyword can be used to return current class instance


We can return this keyword as an statement from the method. In such case, return type of
the method must be the class type (non-primitive).

Syntax of this that can be returned as a statement


return_type method_name(){
return this;
}

Using Objects as Parameters

In Java, you can pass objects as parameters to methods. When you pass an object to a
method, you are actually passing a reference to that object, not a copy of the object. This means
that changes made to the object's fields (instance variables) inside the method will affect the
original object.

Example:

class Car {

String model;

int year;

public Car(String model, int year) {


this.model = model;

this.year = year;

public void displayDetails() {

System.out.println("Model: " + model + ", Year: " + year);

public class Test {

public static void main(String[] args) {

// Create an instance of the Car class

Car myCar = new Car("Toyota", 2020);

// Pass the object to the method

updateCar(myCar);

// Display updated car details

myCar.displayDetails(); // The car's year should have changed to 2022

// Method that takes a Car object as a parameter

public static void updateCar(Car car) {

car.year = 2022; // Modify the year of the car object

car.model = "Honda"; // Modify the model of the car object

Argument passing
In Java, argument passing refers to how values are provided to a method when it is called. There
are two main ways arguments can be passed to methods in Java:

1. Pass-by-Value
2. Pass-by-Reference (via Objects)

1. Pass-by-Value (for Primitives)

When you pass a primitive type (like int, char, float, etc.) to a method, you are passing the
value of that variable, not the variable itself. Any changes made to the parameter inside the
method do not affect the original value of the argument in the calling code.

Example: Pass-by-Value (for Primitives)

public class PassByValueExample {

public static void main(String[] args) {

int num = 10;

System.out.println("Before calling changeValue: " + num); // Output: 10

changeValue(num); // Passing the value of num to the method

System.out.println("After calling changeValue: " + num); // Output: 10

public static void changeValue(int x) {

x = 20; // This changes the value of x inside the method, but does not affect the
original 'num'

System.out.println("Inside changeValue method: " + x); // Output: 20

2. Pass-by-Reference (via Objects)

When you pass an object to a method, you are passing a reference to the object. This means the
method can modify the fields (instance variables) of the object, and the changes will affect the
original object.
However, note that the reference itself is passed by value, meaning you can't change the
reference (i.e., point it to a new object) from within the method. But you can modify the object's
contents.

Example: Pass-by-Reference (via Objects)


class Person {

String name;

int age;

public Person(String name, int age) {

this.name = name;

this.age = age;

public void display() {

System.out.println("Name: " + name + ", Age: " + age);

public class PassByReferenceExample {

public static void main(String[] args) {

Person person1 = new Person("Alice", 25);

System.out.println("Before calling changePerson method:");

person1.display(); // Output: Name: Alice, Age: 25

// Pass the object reference to the method

changePerson(person1);

System.out.println("After calling changePerson method:");

person1.display(); // Output: Name: Bob, Age: 30

public static void changePerson(Person p) {

p.name = "Bob"; // Modify the name field of the object


p.age = 30; // Modify the age field of the object

}}

Method Overloading

Method overloading in Java refers to defining multiple methods with the same name but
different parameter lists within the same class. This is a form of compile-time polymorphism,
where the method to be invoked is determined at compile-time based on the method signature
(the number and types of parameters).

Key Points about Method Overloading:

 Same method name: Methods must have the same name.


 Different parameter lists: The methods must differ in the number of parameters, type of
parameters, or the order of parameters.
 Return type is not a factor: Methods with the same name and parameter list but different
return types are not overloaded.

Example of Method Overloading:


classCalculator {

// Method to add two integers


publicintadd(int a, intb) {
return a + b;
}

// Overloaded method to add three integers


publicintadd(int a, int b, intc) {
return a + b + c;
}

// Overloaded method to add two doubles


publicdoubleadd(double a, doubleb) {
return a + b;
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
Calculatorcalc=newCalculator();

// Calling overloaded methods


System.out.println("Sum of 2 integers: " + calc.add(5, 10));
System.out.println("Sum of 3 integers: " + calc.add(5, 10, 15));
System.out.println("Sum of 2 doubles: " + calc.add(5.5, 10.5));
}
}

In this example:
The add method is overloaded with different parameter counts and types, allowing it to handle different
addition operations.

Garbage Collection in Java

Garbage Collection (GC) in Java is the process by which the Java Virtual Machine (JVM)
automatically reclaims memory by destroying objects that are no longer in use (i.e., objects that
are unreachable or no longer referenced).

Key Points about Garbage Collection:

 Java manages memory automatically via garbage collection, which eliminates the need for
manual memory management.
 Unreachable Objects: An object is considered garbage if no active references are pointing to it.
 The JVM automatically decides when to perform garbage collection based on memory usage, but
you can trigger it manually by calling System.gc(). However, it is not guaranteed to run at that
time.

The finalize() Method

The finalize() method is a method of the Object class in Java. It is called by the garbage
collector before an object is destroyed to give the object a chance to release system resources
such as memory, file handles, or network connections.

Key Points about finalize():

 Purpose: The main purpose of finalize() is to allow an object to clean up any resources before it is
garbage collected. For example, closing file streams or database connections.
 Not guaranteed: The finalize() method is not guaranteed to be called immediately or at all. The
JVM is free to call or skip calling the finalize() method based on the garbage collection process.
 Deprecated in Java 9: In Java 9 and later, the finalize() method has been deprecated. It is
recommended to use try-with-resources or explicit resource management mechanisms instead.

Example of finalize() Method:


classResourceHandler {
publicvoidfinalize() {
// Cleaning up resources before object is garbage collected
System.out.println("Resource is being cleaned up.");
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
ResourceHandlerhandler=newResourceHandler();
handler = null; // Object is now eligible for garbage collection

// Suggesting the JVM to run garbage collection


System.gc();

// Sleep to allow time for GC


try {
Thread.sleep(1000); // Give the garbage collector time to run
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

In this example:

System.gc() is called to suggest that the JVM perform garbage collection.

 Thefinalize() method is invoked on an object before it is garbage collected. This method is


invoked automatically when an object is about to be removed from memory.

Inheritance and Polymorphism:

Inheritance

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows one


class to inherit properties (fields) and behaviors (methods) from another class. In Java,
inheritance allows a class to derive from another class, enabling code reusability and the creation
of a hierarchy of classes.

The extends keyword is used for inheritance in Java. Using the extends keyword indicates you
are derived from an existing class. In other words, “extends” refers to increased functionality.

 Base Class (Superclass): The class being inherited from.


 Derived Class (Subclass): The class that inherits from the superclass.

Syntax :
class DerivedClass extends BaseClass
{
//methods and fields
}
Key Features of Inheritance:

 Code Reusability: The subclass can reuse the methods and variables of the superclass.
 Method Overriding: The subclass can provide a specific implementation of a method that is
already defined in the superclass.

Example of Inheritance:
classAnimal {
voidspeak() {
System.out.println("Animal speaks");
}
}
classDogextendsAnimal {
// Method overriding
voidspeak() {
System.out.println("Dog barks");
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
Animalanimal=newAnimal();
animal.speak(); // Output: Animal speaks

Dogdog=newDog();
dog.speak(); // Output: Dog barks
}
}

In this example:

 The Dog class inherits the speak method from the Animal class but overrides it with its own
implementation.

Access Control in Java

Access control in Java defines the visibility and accessibility of classes, methods, and fields. Java
provides several access modifiers to control access to class members:

 public: The member is accessible from any other class.


 private: The member is accessible only within the class where it is defined.
 protected: The member is accessible within the same package or by subclasses.
 default (no modifier): The member is accessible only within the same package.

Multilevel Inheritance

Multilevel inheritance is when a class is derived from another class, and this derived class is
further extended by another class, creating a chain of inheritance. In the below image, class A
serves as a base class for the derived class B, which in turn serves as a base class for the derived
class C. In Java, a class cannot directly access the grandparent’s members.
Example of Multilevel Inheritance:
Class Animal {
void eat() {
System.out.println("Animal is eating");
}
}

Class Mammal extends Animal {


voidwalk() {
System.out.println("Mammal is walking");
}
}

Class Dog extends Mammal {


voidbark() {
System.out.println("Dog is barking");
}
}

Public class Main {


Public static void main(String[] args) {
Dog dog=newDog();
dog.eat(); // Inherited from Animal
dog.walk(); // Inherited from Mammal
dog.bark(); // Defined in Dog class
}
}

In this example:

 The Dog class inherits the eat method from Animal and the walk method from Mammal.

Multiple Inheritance (Through Interfaces)


In Multiple inheritances, one class can have more than one superclass and inherit features from all parent
classes. Please note that Java does not support multiple inheritances with classes. In Java, we can achieve
multiple inheritances only through Interfaces. In the image below, Class C is derived from interfaces A
and B.
Method Overriding

Overriding in Java occurs when a subclass implements a method which is already defined in the
superclass or Base Class. The method in the subclass must have the same signature as in the
superclass. It allows the subclass to modify the inherited methods.

Method overriding allows a subclass to provide a specific implementation of a method that is


already defined in its superclass. The overridden method must have the same method signature
(name, parameters, return type).

 @Override annotation: This annotation is used to indicate that a method is intended to override
a method in the superclass.

Example of Method Overriding:


classAnimal {
voidsound() {
System.out.println("Animal makes a sound");
}
}

classDogextendsAnimal {
@Override
voidsound() {
System.out.println("Dog barks");
}
}

publicclassMain {
publicstaticvoidmain(String[] args) {
AnimalmyAnimal=newAnimal();
myAnimal.sound(); // Output: Animal makes a sound

AnimalmyDog=newDog();
myDog.sound(); // Output: Dog barks (method overriding)
}
}

In this example:
 The sound() method is overridden in the Dog class. When called on an object of type Animal but
referencing a Dog, the overridden version of the method is invoked.

Abstract Classes

An abstract class is a class that cannot be instantiated directly and may contain abstract methods
(methods without a body) that must be implemented by subclasses.

 Abstract Method: A method without a body, declared with the abstract keyword.
 Concrete Class: A class that implements all abstract methods from the abstract class.

Example of Abstract Class:


Abstract class Animal {
Abstract void sound(); // Abstract method

void sleep() {
System.out.println("Animal is sleeping");
}
}

Class Dogextends Animal {


@Override
voidsound() {
System.out.println("Dog barks");
}
}

Public class Main {


Public static void main(String[] args) {
// Animal animal = new Animal(); // Error: Cannot instantiate abstract class
Dog dog=newDog();
dog.sound(); // Output: Dog barks
dog.sleep(); // Output: Animal is sleeping
}
}

In this example:

 The Animal class is abstract and contains an abstract method sound().


 The Dog class provides a concrete implementation of the sound() method.

Polymorphism

The word ‘polymorphism’ means ‘having many forms’. In Java, polymorphism refers to the
ability of a message to be displayed in more than one form. This concept is a key feature
of Object-Oriented Programming and it allows objects to behave differently based on their
specific class type.

Polymorphism is the ability of an object to take many forms. It allows you to use a parent class
reference to refer to child class objects and invoke the appropriate method.
Real-life Illustration of Polymorphism in Java: A person can have different characteristics at
the same time. Like a man at the same time is a father, a husband, and an employee. So the same
person possesses different behaviors in different situations. This is called polymorphism.

There are two types of polymorphism in Java:

 Compile-time polymorphism (Method Overloading): Compile-Time Polymorphism in


Java is also known as static polymorphism. It is achieved by having multiple methods
with the same name but different parameters.
 Runtime polymorphism (Method Overriding): Runtime Polymorphism in Java known
as Dynamic Method Dispatch.It is achieved when a subclass overrides a method of its
parent class.

Compile-time Polymorphism (Method Overloading):

Method overloading occurs when two or more methods in the same class have the same name
but differ in the number or type of parameters.Functions can be overloaded by changes in the
number of arguments or/and a change in the type of arguments.

 Syntax for Method Overloading:

class Calculator {
// Overloaded method to add two integers
public int add(int a, int b) {
return a + b;
}

// Overloaded method to add three integers


public int add(int a, int b, int c) {
return a + b + c;
}
}

 Using Method Overloading:

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(10, 20)); // Outputs: 30
System.out.println(calc.add(10, 20, 30)); // Outputs: 60
}
}

Runtime Polymorphism (Method Overriding):

This occurs when a subclass provides its own specific implementation of a method defined in its
superclass. It is a process in which a function call to the overridden method is resolved at
Runtime. This type of polymorphism is achieved by Method Overriding. Method overriding, on
the other hand, occurs when a derived class has a definition for one of the member functions of
the base class. That base function is said to be overridden.
 Example of Runtime Polymorphism:

class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}

class Dog extends Animal {


@Override
public void makeSound() {
System.out.println("Woof");
}
}

class Cat extends Animal {


@Override
public void makeSound() {
System.out.println("Meow");
}
}

public class Main {


public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog();
Animal myCat = new Cat();

myAnimal.makeSound(); // Outputs: Some sound


myDog.makeSound(); // Outputs: Woof
myCat.makeSound(); // Outputs: Meow
}
}

In the example above, we use an Animal reference to call the makeSound method, but the actual
method executed depends on the object's runtime type (Dog, Cat, or Animal), demonstrating
runtime polymorphism.

final Keyword

The final keyword in Java is used to define constants, prevent method overriding, and prevent
inheritance.

 final with variables: Used to define constants (the value cannot be changed after initialization).
 final with methods: Prevents a method from being overridden by subclasses.
 final with classes: Prevents a class from being inherited.

Example of final Keyword:


// final class cannot be extended
finalclassFinalClass {
voidshow() {
System.out.println("Final class method");
}
}

classMain {
publicstaticvoidmain(String[] args) {
// FinalClass obj = new FinalClass(); // Valid, no issue with instantiating
final class
FinalClassobj=newFinalClass();
obj.show(); // Output: Final class method
}
}

// Example of final method


classAnimal {
finalvoidsleep() {
System.out.println("Animal is sleeping");
}
}

classDogextendsAnimal {
// Error: Cannot override final method sleep()
// void sleep() {
// System.out.println("Dog is sleeping");
// }
}

publicclassMain {
publicstaticvoidmain(String[] args) {
Animaldog=newAnimal();
dog.sleep(); // Output: Animal is sleeping
}
}

In this example:

 The FinalClass class cannot be subclassed.


 The sleep() method in Animal cannot be overridden because it is declared final.

You might also like