0% found this document useful (0 votes)
15 views

r20 Unit 2 Final

Uploaded by

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

r20 Unit 2 Final

Uploaded by

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

UNIT II:

Classes and Objects: Introduction, Class Declaration and Modifiers, Class Members, Declaration
of Class Objects, Assigning One Object to Another, Access Control for Class Members, Accessing
Private Members of Class, Constructor Methods for Class, Overloaded Constructor Methods,
Nested Classes, Final Class and Methods, Passing Arguments by Value and by Reference,
Keyword this.
Methods: Introduction, Defining Methods, Overloaded Methods, Overloaded Constructor
Methods, Class Objects as Parameters in Methods, Access Control, Recursive Methods, Nesting of
Methods, Overriding Methods, Attributes Final and Static.

2.1 .1 Classes Introduction:


Class is a user defined new data type. Once defined, this new type can be used to create objects of that
type.
Class is a template for an object, and an object is an instance of a class. Because an object is an instance
of a class, you will often see the two words object and instance used interchangeably
The General Form of a Class:
A class is declared by use of the class keyword.
class classname
{
type instance-variable1;
type instance-variable2;
// ...
type instance-variableN;
type methodname1(parameter-list)
{
// body of method
}
type methodname2(parameter-list)
{
// body of method
}
// ...
type methodnameN(parameter-list)
{
// body of method
}
}
The data, or variables, defined within a class are called instance variables. The code is contained within
methods. Collectively, the methods and variables defined within a class are called members of the class.
In most classes, the instance variables are acted upon and accessed by the methods defined for that class.
Thus, it is the methods that de can be used.

A Simple Class and its members


class Box
{
double width;
double height;
double depth;
void volume()
{
System.out.print("Volume is ");
System.out.println(width * height * depth);
}
}
Above class contains members as width, height, depth of double type and member function volume().

Declaring Objects:
Declaring objects of a class is a two-step process. First, you must declare a variable of the class type.
This variable does not define an object. Instead, it is simply a variable that can refer to an object.
Second, you must acquire an actual, physical copy of the object and assign it to that variable. You can
do this using the new operator. The new operator dynamically allocates (that is, allocates at run time)
memory for an object and returns a reference to it. This reference is, more or less, the address in
memory of the object allocated by new.
Ex: Box mybox = new Box();

This statement combines the two steps just described. It can be rewritten like this to show each step
more clearly:

Box mybox; // declare reference to object


mybox = new Box(); // allocate a Box object

Assigning One Object to Another:

Box b1 = new Box();


Box b2 = b1;

You might think that b2 is being assigned a reference to a copy of the object referred to by b1. That is,
you might think that b1 and b2 refer to separate and distinct objects. However, this would be wrong.
Instead, after this fragment executes, b1 and b2 will both refer to the same object. The assignment of b1
to b2 did not allocate any memory or copy any part of the original object. It simply makes b2 refer to the
same object as does b1. Thus, any changes made to the object through b2 will affect the object to which
b1 is referring, since they are the same object.
Access Control for Class Members:

As you know, encapsulation links data with the code that manipulates it. However, encapsulation
provides another important attribute: access control.

Java supplies a rich set of access specifiers. Some aspects of access control are related mostly to
inheritance or packages.
Java’s access specifiers are public, private, and protected.

Public:
When a member of a class is modified by the public specifier, then that member can be accessed by any
other code

Private:
When a member of a class is specified as private, then that member can only be accessed by other
members of its class.

Protected:
When a member of a class is specified as protected, then that member can be accessed by its sub classes
with in the package

When no access specifier is used, then by default the member of a class is public within its own
package, but cannot be accessed outside of its package.
Accessing Private Members of Class:

class Test {
int a; // default access
public int b; // public access
private int c; // private access
// methods to access c
void setc(int i) {
c = i;
}
int getc() {
return c;
}
}
public class Main {
public static void main(String args[]) {
Test ob = new Test();
ob.a = 1;
ob.b = 2;
// This is not OK and will cause an error
// ob.c = 100; // Error!
// You must access c through its methods
ob.setc(100); // OK
System.out.println("a, b, and c: " + ob.a +
" " + ob.b + " " + ob.getc());
}
}

Constructor Methods for Class:

x A constructor initializes an object immediately upon creation.


x It has the same name as the class in which it resides and is syntactically similar to a method.
x Once defined, the constructor is automatically called immediately after the object is created,
before the new operator completes.

Constructors look a little strange because they have no return type, not even void. This is because the
implicit return type of a class’ constructor is the class type itself. It is the constructor’s job to initialize
the internal state of an object so that the code creating an instance will have a fully initialized, usable
object immediately

class Box {
double width;
double height;
double depth;
// This is the constructor for Box.
Box() {
System.out.println("Constructing Box");
width = 10;
height = 10;
depth = 10;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
class BoxDemo6 {
public static void main(String args[]) {
// declare, allocate, and initialize Box objects
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume is " + vol);
// get volume of second box
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
When this program is run, it generates the following results:
Constructing Box
Constructing Box
Volume is 1000.0
Volume is 1000.0

Types of java constructors :


There are two types of constructors:
x Default constructor (no-arg constructor)
x Parameterized constructor

//Default constructor
class Bike1
{
Bike1()
{
System.out.println("Bike is created");
}
public static void main(String args[])
{
Bike1 b=new Bike1();
}
}

//Parameterized constructor
class Student4
{
int id;
String name;
Student4(int i,String n)
{
id = i;
name = n;
}
void display()
{
System.out.println(id+" "+name);
}
public static void main(String args[])
{
Student4 s1 = new Student4(111,"Karan");
Student4 s2 = new Student4(222,"Aryan");
s1.display();
s2.display();
}
}

Overloaded Constructor Methods:

In addition to overloading normal methods, you can also overload constructor methods. In fact, for most
real-world classes that you create, overloaded constructors will be the norm, not the exception. To
understand why, let’s return to the Box class developed in the preceding chapter. Following is the latest
version of Box:

class Box
{
double width;
double height;
double depth;
// This is the constructor for Box.
Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
}
// compute and return volume
double volume()
{
return width * height * depth;
}
}
Java Inner Classes (Nested Classes)

Java inner class or nested class is a class that is declared inside the class or interface.

We use inner classes to logically group classes and interfaces in one place to be more readable and
maintainable.

Additionally, it can access all the members of the outer class, including private data members and
methods.

Syntax of Inner class

1. class Java_Outer_class{
2. //code
3. class Java_Inner_class{
4. //code
5. }
6. }
Advantage of Java inner classes

There are three advantages of inner classes in Java. They are as follows:

1. Nested classes represent a particular type of relationship that is it can access all the
members (data members and methods) of the outer class, including private.
2. Nested classes are used to develop more readable and maintainable code because it
logically group classes and interfaces in one place only.
3. Code Optimization: It requires less code to write.

Need of Java Inner class

Sometimes users need to program a class in such a way so that no other class can access it. Therefore,
it would be better if you include it within other classes.

If all the class objects are a part of the outer object then it is easier to nest that class inside the outer
class. That way all the outer class can access all the objects of the inner class.

Types of Nested classes

There are two types of nested classes non-static and static nested classes. The non-static nested
classes are also known as inner classes.

o Non-static nested class (inner class)


1. Member inner class
2. Anonymous inner class
3. Local inner class
o Static nested class
java Member Inner class
A non-static class that is created inside a class but outside a method is called member inner class. It
is also known as a regular inner class. It can be declared with access modifiers like public, default,
private, and protected.

Syntax:

1. class Outer{
2. //code
3. class Inner{
4. //code
5. }
6. }
Java Member Inner Class Example

In this example, we are creating a msg() method in the member inner class that is accessing the
private data member of the outer class.

TestMemberOuter1.java

1. class TestMemberOuter1{
2. private int data=30;
3. class Inner{
4. void msg(){System.out.println("data is "+data);}
5. }
6. public static void main(String args[]){
7. TestMemberOuter1 obj=new TestMemberOuter1();
8. TestMemberOuter1.Inner in=obj.new Inner();
9. in.msg();
10. }
11. }

Output:

data is 30
How to instantiate Member Inner class in Java?

An object or instance of a member's inner class always exists within an object of its outer class.
The new operator is used to create the object of member inner class with slightly different syntax.

The general form of syntax to create an object of the member inner class is as follows:

Syntax:

1. OuterClassReference.new MemberInnerClassConstructor();

Example:
1. obj.new Inner();

Here, OuterClassReference is the reference of the outer class followed by a dot which is followed
by the new operator.

Internal working of Java member inner class

The java compiler creates two class files in the case of the inner class. The class file name of the inner
class is "Outer$Inner". If you want to instantiate the inner class, you must have to create the instance
of the outer class. In such a case, an instance of inner class is created inside the instance of the outer
class.

Internal code generated by the compiler


The Java compiler creates a class file named Outer$Inner in this case. The Member inner class has the
reference of Outer class that is why it can access all the data members of Outer class including
private.

Note: We can not have a static method in a nested inner class because an inner class is implicitly
associated with an object of its outer class so it cannot define any static method for itself. For
example, the following program doesn’t compile.

// Java Program to Demonstrate Nested class

// Where Error is thrown

// Class 1

// Outer class

class Outer {

// Method defined inside outer class

void outerMethod()

// Print statement

System.out.println("inside outerMethod");

// Class 2

// Inner class

class Inner {
// Main driver method

public static void main(String[] args)

// Display message for better readability

System.out.println("inside inner class Method");

Localnner class

A class i.e., created inside a method, is called local inner class in java. Local Inner Classes are the inner
classes that are defined inside a block. Generally, this block is a method body. Sometimes this block
can be a for loop, or an if clause. Local Inner classes are not a member of any enclosing classes. They
belong to the block they are defined within, due to which local inner classes cannot have any access
modifiers associated with them. However, they can be marked as final or abstract. These classes have
access to the fields of the class enclosing it.

If you want to invoke the methods of the local inner class, you must instantiate this class inside the
method.

Java local inner class example

LocalInner1.java

1. public class localInner1{


2. private int data=30;//instance variable
3. void display(){
4. class Local{
5. void msg(){System.out.println(data);}
6. }
7. Local l=new Local();
8. l.msg();
9. }
10. public static void main(String args[]){
11. localInner1 obj=new localInner1();
12. obj.display();
13. }
14. }

Rules for Java Local Inner class


1) Local inner class cannot be invoked from outside the method.
2) Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8, it is possible to
access the non-final local variable in the local inner class.

Example of local inner class with local variable


LocalInner2.java

class localInner2{
private int data=30;//instance variable
void display(){
int value=50;//local variable must be final till jdk 1.7 only
class Local{
void msg(){System.out.println(value);}
}
Local l=new Local();
l.msg();
}
public static void main(String args[]){
localInner2 obj=new localInner2();
obj.display();
}
}

Note: Local inner class cannot access non-final local variable till JDK 1.7.
Since JDK 1.8, it is possible to access the non-final local variable in method
local inner class.

Anonymous Classes

Java anonymous inner class is an inner class without a name and for which only a single object is
created. An anonymous inner class can be useful when making an instance of an object with
certain "extras" such as overloading methods of a class or interface, without having to actually
subclass a class.

In simple words, a class that has no name is known as an anonymous inner class in Java. It should
be used if you have to override a method of class or interface. Java Anonymous inner class can be
created in two ways:

1.Class (may be abstract or concrete).


2.Interface
Java anonymous inner class example using class

abstract class Person{


abstract void eat();
}
class TestAnonymousInner{
public static void main(String args[]){
Person p=new Person(){
void eat(){System.out.println("nice fruits");}
};
p.eat();
}
}

Internal working of given code

Person p=new Person(){


void eat(){System.out.println("nice fruits");}
};
A class is created, but its name is decided by the compiler, which extends the Person class and provides
the implementation of the eat() method.
An object of the Anonymous class is created that is referred to by 'p,' a reference variable of Person type.

Java anonymous inner class example using interface

interface Eatable{

void eat();

class TestAnnonymousInner1{

public static void main(String args[]){

Eatable e=new Eatable(){

public void eat(){System.out.println("nice fruits");}

};

e.eat();

}
Final Class and Methods:
Final Class:

When a class is declared with final keyword, it is called a final class. A final class cannot be
extended(inherited).

There are two uses of a final class :

1. One is definitely to prevent inheritance, as final classes cannot be extended. For example, all
Wrapper Classes like Integer,Float etc. are final classes. We can not extend them.
final class A
{
// methods and fields
}
// The following class is illegal.
class B extends A
{
// COMPILE-ERROR! Can't subclass A
}

2. The other use of final with classes is to create an immutable class like the predefined String
class. You cannot make a class immutable without making it final.

Final Method:

When a method is declared with final keyword, it is called a final method.


A final method cannot be overridden.
The Object class does this—a number of its methods are final.We must declare methods with final
keyword for which we required to follow the same implementation throughout all the derived classes.
The following fragment illustrates final keyword with a method:

class A
{
final void m1()
{
System.out.println("This is a final method.");
}
}

class B extends A
{
void m1()
{
// COMPILE-ERROR! Can't override.
System.out.println("Illegal!");
}
}
Passing Arguments by Value and by reference:
In general, there are two ways that a computer language can pass an argument to a subroutine.
The first way is call-by-value. This method copies the value of an argument into the formal parameter
of the subroutine. Therefore, changes made to the parameter of the subroutine have no effect on the
argument.
The second way an argument can be passed is call-by-reference.
In this method, a reference to an argument (not the value of the argument) is passed to the parameter.
Inside the subroutine, this reference is used to access the actual argument specified in the call. This
means that changes made to the parameter will affect the argument used to call the subroutine. As you
will see, Java uses both approaches, depending upon what is passed.
For example, consider the following program:
// Simple types are passed by value.
class Test
{
void meth(int i, int j)
{
i *= 2;
j /= 2;
}
}
class CallByValue
{
public static void main(String args[])
{
Test ob = new Test();
int a = 15, b = 20;
System.out.println("a and b before call: " +a + " " + b);
ob.meth(a, b);
System.out.println("a and b after call: " +a + " " + b);
}
}
The output from this program is shown here:
a and b before call: 15 20
a and b after call: 15 20

Pass by Reference: It is a process in which the actual copy of reference is passed to the function. This is
called by Reference.

Talking about Java, we can say that Java is Pass by Value and not pass by reference.

this Keyword:

Sometimes a method will need to refer to the object that invoked it. To allow this, Java defines the this
keyword. this can be used inside any method to refer to the current object. That is, this is always a
reference to the object on which the method was invoked. You can use this anywhere a reference to an
object of the cur what this refers to, consider the following version of Box( ):
// A redundant use of this.
Box(double w, double h, double d)
{
this.width = w;
this.height = h;
this.depth = d;
}
This version of Box( ) operates exactly like the earlier version. The use of this is redundant, but
perfectly correct. Inside Box( ), this will always refer to the invoking object. While it is redundant in this
case, this is useful in other contexts, one of which is explained in the next section.

Instance Variable Hiding:

As you know, it is illegal in Java to declare two local variables with the same name inside the same or
enclosing scopes. Interestingly, you can have local variables, including formal parameters to methods,
which instance variables. However, when a local variable has the same name as an instance
variable, the local variable hides the instance variable.
// Use this to resolve name-space collisions.
Box(double width, double height, double depth)
{
this.width = width;
this.height = height;
this.depth = depth;
}
A word of caution: The use of this in such a context can sometimes be confusing, and some
programmers are careful not to use local variables and formal parameter names that hide instance
variables

Introducing Methods:

This is the general form of a method:


type name(parameter-list)
{
// body of method
}

type specifies the type of data returned by the method. This can be any valid type, including class types
that you create. If the method does not return a value, its return type must be void.

The name of the method is specified by name. This can be any legal identifier other than those already
used by other items within the current scope.

The parameter-list is a sequence of type and identifier pairs separated by commas. Parameters are
essentially variables that receive the value of the arguments passed to the method when it is called. If the
method has no parameters, then the parameter list will be empty. Methods that have a return type other
than void return a value to the calling routine using the following form of the return statement: return
value; Here, value is the value returned

class Box
{
double width;
double height;
double depth;
// display volume of a box
void volume()
{
System.out.print("Volume is ");
System.out.println(width * height * depth);
}
}

class BoxDemo3
{
public static void main(String args[])
{
Box mybox1 = new Box();
Box mybox2 = new Box();
// assign values to mybox1's instance variables
mybox1.width = 10;
mybox1.height = 20;
mybox1.depth = 15;
/* assign different values to mybox2's
instance variables */
mybox2.width = 3;
mybox2.height = 6;
mybox2.depth = 9;
// display volume of first box
mybox1.volume();
// display volume of second box
mybox2.volume();}
}

Returning a Value:

While the implementation of volume( ) does move the computation of a box’s volume inside the Box
class where it belongs, it is not the best way to do it. For example, what if another part of your program
wanted to know the volume of a box, but not display its value? A better way to implement volume( ) is
to have it compute the volume of the box and return the result to the caller. The following example, an
improved version of the preceding program, does just that:

class Box {
double width;
double height;
double depth;
// compute and return volume
double volume() {
return width * height * depth;
}
}
class BoxDemo4 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
// assign values to mybox1's instance variables
mybox1.width = 10;
mybox1.height = 20;
mybox1.depth = 15;
/* assign different values to mybox2's
instance variables */
mybox2.width = 3;
mybox2.height = 6;
mybox2.depth = 9;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume is " + vol);
// get volume of second box
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}

Overloading Methods:
In Java it is possible to define two or more methods within the same class that share the same name, as
long as their parameter declarations are different. When this is the case, the methods are said to be
overloaded, and the process is referred to as method overloading. Method overloading is one of the
ways that Java implements polymorphism.
// Demonstrate method overloading.
class OverloadDemo {
void test() {
System.out.println("No parameters");
}
// Overload test for one integer parameter.
void test(int a) {
System.out.println("a: " + a);
}
// Overload test for two integer parameters.
void test(int a, int b) {
System.out.println("a and b: " + a + " " + b);
}
// overload test for a double parameter
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
}
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
double result;
// call all versions of test()
ob.test();
ob.test(10);
ob.test(10, 20);
result = ob.test(123.25);
System.out.println("Result of ob.test(123.25): " + result);
}
}
This program generates the following output:
No parameters a:
10
a and b: 10 20
double a: 123.25
Result of ob.test(123.25): 15190.5625
As you can see, test( ) is overloaded four times.

Class Objects as Parameters in methods:

class Test {
int a, b;
Test(int i, int j) {
a = i;
b = j;
}
// return true if o is equal to the invoking object
boolean equals(Test o) {
if(o.a == a && o.b == b) return true;
else return false;
}
}
class PassOb {
public static void main(String args[]) {
Test ob1 = new Test(100, 22);
Test ob2 = new Test(100, 22);
Test ob3 = new Test(-1, -1);
System.out.println("ob1 == ob2: " + ob1.equals(ob2));
System.out.println("ob1 == ob3: " + ob1.equals(ob3));
}
}
This program generates the following output:
ob1 == ob2: true
ob1 == ob3: false
As you can see, the equals( ) method inside Test compares two objects for equality and returns the
result. That is, it compares the invoking object with the one that it is passed. If they contain the same
values, then the method returns true. Otherwise, it returns false. Notice that the parameter o in equals( )
specifies Test as its type

Recursive Methods:
Java supports recursion. Recursion is the process of defining something in terms of itself.
As it relates to Java programming, recursion is the attribute that allows a method to call itself. A method
that calls itself is said to be recursive.
The classic example of recursion is the computation of the factorial of a number. The factorial of a
number N is the product of all the
whole numbers between 1 and N.
// A simple example of recursion(factorial).
class Factorial {
// this is a recursive function
int fact(int n) {
int result;
if(n==1) return 1;
result = fact(n-1) * n;
return result;
}
}
class Recursion {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println("Factorial of 3 is " + f.fact(3));
System.out.println("Factorial of 4 is " + f.fact(4));
System.out.println("Factorial of 5 is " + f.fact(5));
}
}
The output from this program is shown here:
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120

Nesting of methods:
A method of a class can be called only by an object of that class using the dot operator. So, there is an
exception to this. A method can be called by using only its name by another method of the same class
that is called Nesting of Methods.
class test
{
int a,b;
test(int p, int q)
{
a=p;
b=q;
}
int greatest()
{
if(a>=b)
return(a);
else
return(b);
}
void display()
{
int great=greatest();
System.out.println("The Greatest Value="+great);
}
}
class temp
{
public static void main(String args[])
{
test t1=new test(25,24);
t1.display();
}
}
2.2.6 Method overriding:
x In a class hierarchy, when a method in a sub class has the same name and type signature as a
method in its super class, then the method in the sub class is said to be override the method in the
sub class.
x When an overridden method is called from within a sub class, it will always refers to the version
of that method defined by the sub class
x The version of the method defined in the super class is hidden.
x In this situation, first it checks the method is existed in super class are not. If it is existed then it
executes the version of sub class otherwise it gives no such method found exception.
Note: Methods with different signatures overloading but not overriding.
// Method overriding.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b;
}
// display i and j
void show() {
System.out.println("i and j: " + i + " " + j);
}
}
class B extends A {
int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
// display k – this overrides show() in A
void show() {
System.out.println("k: " + k);
}
}
class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show(); // this calls show() in B
}
}
Output:
k: 3

Dynamic method dispatch:


x It is a mechanism by which a call to an overridden method is resolved at run time rather then
compile time.
x It is important because this is how java implements runtime polymorphism.
x Before going to that we must know about super class reference sub class object.
Example:
// Dynamic Method Dispatch
class A {
void callme() {
System.out.println("Inside A's callme method");
}
}
class B extends A {
// override callme()
void callme() {
System.out.println("Inside B's callme method");
}
}
class C extends A {
// override callme()
void callme() {
System.out.println("Inside C's callme method");
}
}
class Dispatch {
public static void main(String args[]) {
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
A r; // obtain a reference of type A
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
allme(); // calls C's version of callme
}
}
Output:
Inside A’s callme method
Inside B’s callme method
Inside C’s callme method

2.2.7 Attributes Final and Static


The final keyword in java is used to restrict the user. The java final keyword can be used in many
context. Final can be:

1.variable
2.method
3.class
The final keyword can be applied with the variables, a final variable that have no value it is called blank
final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final
variable can be static also which will be initialized in the static block only. We will have detailed
learning of these. Let's first learn the basics of final keyword.

final keyword in java


1) Java final variable
If you make any variable as final, you cannot change the value of final variable(It will be constant).

Example of final variable


There is a final variable speedlimit, we are going to change the value of this variable, but It can't be
changed because final variable once assigned a value can never be changed.

class Bike9{
final int speedlimit=90;//final variable
void run(){
speedlimit=400; //raises an error
}
public static void main(String args[]){
Bike9 obj=new Bike9();
obj.run();
}
}//end of class

What is blank or uninitialized final variable?


A final variable that is not initialized at the time of declaration is known as blank final variable.

If you want to create a variable that is initialized at the time of creating object and once initialized may
not be changed, it is useful. For example PAN CARD number of an employee.

It can be initialized only in constructor.

Example of blank final variable


class Student{
int id;
String name;
final String PAN_CARD_NUMBER;
...
}
Can we initialize blank final variable?
Yes, but only in constructor. For example:
class Bike10{
final int speedlimit;//blank final variable

Bike10(){
speedlimit=70;
System.out.println(speedlimit);
}

public static void main(String args[]){


new Bike10();
}
}
2) Java final method

If you make any method as final, you cannot override it.

Example of final method


class Bike{
final void run(){System.out.println("running");}
}

class Honda extends Bike{


void run(){System.out.println("running safely with 100kmph");}

public static void main(String args[]){


Honda honda= new Honda();
honda.run();
}
}

Output:Compile Time Error

3) Java final class

If you make any class as final, you cannot extend it.


Example of final class

final class Bike{}

class Honda1 extends Bike{


void run(){System.out.println("running safely with 100kmph");}

public static void main(String args[]){


Honda1 honda= new Honda1();
honda.run();
}
}
Is final method inherited?
Ans) Yes, final method is inherited but you cannot override it. For Example:

class Bike{
final void run(){System.out.println("running...");}
}
class Honda2 extends Bike{
public static void main(String args[]){
new Honda2().run();
}
}
Java static keyword
The static keyword in Java is used for memory management mainly. We can apply static keyword
with variables, methods, blocks and nested classes. The static keyword belongs to the class than an
instance of the class.

The static can be:

1. Variable (also known as a class variable)


2. Method (also known as a class method)
3. Block
4. Nested class

Java static variable

If you declare any variable as static, it is known as a static variable.

The static variable can be used to refer to the common property of all objects (which is not unique for
each object), for example, the company name of employees, college name of students, etc.

The static variable gets memory only once in the class area at the time of class loading.

Advantages of static variable

It makes your program memory efficient (i.e., it saves memory).

Understanding the problem without static variable

class Student{

int rollno;

String name;

String college="ITS";

Suppose there are 500 students in my college, now all instance data members will get memory each
time when the object is created. All students have its unique rollno and name, so instance data
member is good in such case. Here, "college" refers to the common property of all objects. If we make
it static, this field will get the memory only once.

Java static property is shared to all objects.


Example of static variable
//Java Program to demonstrate the use of static variable
class Student{
int rollno;//instance variable
String name;
static String college ="ITS";//static variable
//constructor
Student(int r, String n){
rollno = r;
name = n;
}
//method to display the values
void display (){System.out.println(rollno+" "+name+" "+college);}
}
//Test class to show the values of objects
public class TestStaticVariable1{
public static void main(String args[]){
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
//we can change the college of all objects by the single line of code
//Student.college="BBDIT";
s1.display();
s2.display();
}
}

Program of the counter without static variable


In this example, we have created an instance variable named count which is incremented in the
constructor. Since instance variable gets the memory at the time of object creation, each object will
have the copy of the instance variable. If it is incremented, it won't reflect other objects. So each
object will have the value 1 in the count variable.

//Java Program to demonstrate the use of an instance variable


//which get memory each time when we create an object of the class.
class Counter{
int count=0;//will get memory each time when the instance is created

Counter(){
count++;//incrementing value
System.out.println(count);
}

public static void main(String args[]){


//Creating objects
Counter c1=new Counter();
Counter c2=new Counter();
Counter c3=new Counter();
}
}
Test it Now
Output:

1
1
1
Program of counter by static variable
As we have mentioned above, static variable will get the memory only once, if any object changes
the value of the static variable, it will retain its value.

//Java Program to illustrate the use of static variable which


//is shared with all objects.
class Counter2{
static int count=0;//will get memory only once and retain its value

Counter2(){
count++;//incrementing the value of static variable
System.out.println(count);
}

public static void main(String args[]){


//creating objects
Counter2 c1=new Counter2();
Counter2 c2=new Counter2();
Counter2 c3=new Counter2();
}
}
Test it Now
Output:

1
2
3

2) Java static method


If you apply static keyword with any method, it is known as static method.

A static method belongs to the class rather than the object of a class.
A static method can be invoked without the need for creating an instance of a class.
A static method can access static data member and can change the value of it.
Example of static method
//Java Program to demonstrate the use of a static method.
class Student{
int rollno;
String name;
static String college = "ITS";
//static method to change the value of static variable
static void change(){
college = "BBDIT";
}
//constructor to initialize the variable
Student(int r, String n){
rollno = r;
name = n;
}
//method to display values
void display(){System.out.println(rollno+" "+name+" "+college);}
}
//Test class to create and display the values of object
public class TestStaticMethod{
public static void main(String args[]){
Student.change();//calling change method
//creating objects
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
Student s3 = new Student(333,"Sonoo");
//calling display method
s1.display();
s2.display();
s3.display();
}
}
Test it Now
Output:111 Karan BBDIT
222 Aryan BBDIT
333 Sonoo BBDIT
Restrictions for the static method
There are two main restrictions for the static method. They are:

1.The static method can not use non static data member or call non-static method directly.
2.this and super cannot be used in static context.

int a=40;//non static

public static void main(String args[]){


System.out.println(a);
}
}
Test it Now
Output:Compile Time Error
Q) Why is the Java main method static?
Ans) It is because the object is not required to call a static method. If it were a non-static method,
JVM creates an object first then call main() method that will lead the problem of extra memory
allocation.

3) Java static block


Is used to initialize the static data member.
It is executed before the main method at the time of classloading.
Example of static block
class A2{
static{System.out.println("static block is invoked");}
public static void main(String args[]){
System.out.println("Hello main");
}
}
Test it Now
Output:static block is invoked
Hello main
Q) Can we execute a program without main() method?
Ans) No, one of the ways was the static block, but it was possible till JDK 1.6. Since JDK 1.7, it is not
possible to execute a Java class without the main method.

class A3{
static{
System.out.println("static block is invoked");
System.exit(0);
}
}
Test it Now
Output:

static block is invoked


Since JDK 1.7 and above, output would be:

Error: Main method not found in class A3, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application

Garbage Collection in Java


Garbage collection in Java is the process by which Java programs perform automatic memory
management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM
for short. When Java programs run on the JVM, objects are created on the heap, which is a portion
of memory dedicated to the program. Eventually, some objects will no longer be needed. The
garbage collector finds these unused objects and deletes them to free up memory.
What is Garbage Collection?
In C/C++, a programmer is responsible for both the creation and destruction of objects. Usually,
programmer neglects the destruction of useless objects. Due to this negligence, at a certain point,
sufficient memory may not be available to create new objects, and the entire program will
terminate abnormally, causing OutOfMemoryErrors.
But in Java, the programmer need not care for all those objects which are no longer in use. Garbage

main objective of Garbage


collector destroys these objects. The

Collector is to free heap memory by


destroying unreachable objects. The garbage collector
is the best example of the Daemon thread as it is always running in the
background.
How Does Garbage Collection in Java works?
Java garbage collection is an automatic process. Automatic garbage collection is the process of
looking at heap memory, identifying which objects are in use and which are not, and deleting the
unused objects. An in-use object, or a referenced object, means that some part of your program still
maintains a pointer to that object. An unused or unreferenced object is no longer referenced by any
part of your program. So the memory used by an unreferenced object can be reclaimed. The
programmer does not need to mark objects to be deleted explicitly. The garbage collection
implementation lives in the JVM.

Types of Activities in Java Garbage Collection

Two types of garbage collection activity usually happen in Java. These are:
1. Minor or incremental Garbage Collection: It is said to have occurred when unreachable
objects in the young generation heap memory are removed.
2. Major or Full Garbage Collection: It is said to have occurred when the objects that survived
the minor garbage collection are copied into the old generation or permanent generation
heap memory are removed. When compared to the young generation, garbage collection
happens less frequently in the old generation.

Important Concepts Related to Garbage Collection in Java

1. Unreachable objects: An object is said to be unreachable if it doesn’t contain any reference to it. Also,
note that objects which are part of the island of isolation are also unreachable.
Integer i = new Integer(4);
// the new Integer object is reachable via the reference in 'i'
i = null;
// the Integer object is no longer reachable.
2. Eligibility for garbage collection: An object is said to be eligible for GC(garbage collection) if it
is unreachable. After i = null, integer object 4 in the heap area is suitable for garbage collection in
the above image.
Ways to make an object eligible for Garbage Collector
x Even though the programmer is not responsible for destroying useless objects but it is highly
recommended to make an object unreachable(thus eligible for GC) if it is no longer required.
x There are generally four ways to make an object eligible for garbage collection.
1. Nullifying the reference variable
2. Re-assigning the reference variable
3. An object created inside the method
4. Island of Isolation
Ways for requesting JVM to run Garbage Collector
x Once we make an object eligible for garbage collection, it may not destroy immediately by the
garbage collector. Whenever JVM runs the Garbage Collector program, then only the object will
be destroyed. But when JVM runs Garbage Collector, we can not expect.
x We can also request JVM to run Garbage Collector. There are two ways to do it :
1. Using System.gc() method: System class contain static method gc() for requesting JVM to
run Garbage Collector.
2. Using Runtime.getRuntime().gc() method: Runtime class allows the application to interface
with the JVM in which the application is running. Hence by using its gc() method, we can
request JVM to run Garbage Collector.
3. There is no guarantee that any of the above two methods will run Garbage Collector.
4. The call System.gc() is effectively equivalent to the call : Runtime.getRuntime().gc()
Finalization
x Just before destroying an object, Garbage Collector calls finalize() method on the object to
perform cleanup activities. Once finalize() method completes, Garbage Collector destroys that
object.
x finalize() method is present in Object class with the following prototype.
protected void finalize() throws Throwable
Based on our requirement, we can override finalize() method for performing our cleanup activities
like closing connection from the database.
1. The finalize() method is called by Garbage Collector, not JVM. However, Garbage Collector is one
of the modules of JVM.
2. Object class finalize() method has an empty implementation. Thus, it is recommended to
override the finalize() method to dispose of system resources or perform other cleanups.
3. The finalize() method is never invoked more than once for any object.
4. If an uncaught exception is thrown by the finalize() method, the exception is ignored, and the
finalization of that object terminates.
Advantages of Garbage Collection in Java
The advantages of Garbage Collection in Java are:
x It makes java memory-efficient because the garbage collector removes the unreferenced objects
from heap memory.
x It is automatically done by the garbage collector(a part of JVM), so we don’t need extra effort.
Real-World Example
Let’s take a real-life example, where we use the concept of the garbage collector.
Question: Suppose you go for the internship at some company, and you were told to write a
program to count the number of employees working in the company(excluding interns). To make
this program, you have to use the concept of a garbage collector.
This is the actual task you were given at the company:
Write a program to create a class called Employee having the following data members.
1. An ID for storing unique id allocated to every employee.
2. Name of employee.
3. age of an employee.
Also, provide the following methods:
1. A parameterized constructor to initialize name and age. The ID should be initialized in this
constructor.
2. A method show() to display ID, name, and age.
3. A method showNextId() to display the ID of the next employee.
Now any beginner, who doesn’t know Garbage Collector in Java will code like this:
Java

// Java Program to count number of employees working in a company

class Employee {

private int ID;

private String name;


private int age;

private static int nextId = 1;// it is made static because it keep common is
shared by all objects among all and

public Employee(String name, int age)

{ this.name = name;

this.age = age;

this.ID = nextId++;

public void show()

System.out.println("Id=" + ID + "\nName=" + name

+ "\nAge=" + age);

public void showNextId()

System.out.println("Next employee id will be="

+ nextId);

class UseEmployee {

public static void main(String[] args)

Employee E = new Employee("GFG1", 56);

Employee F = new Employee("GFG2", 45);

Employee G = new Employee("GFG3", 25);


E.show();

F.show();

G.show();

E.showNextId();

F.showNextId();

G.showNextId();

{ // It is sub block to keep

// all those interns.

Employee X = new Employee("GFG4", 23);

Employee Y = new Employee("GFG5", 21);

X.show();

Y.show();

X.showNextId();

Y.showNextId();

// After countering this brace, X and Y will be removed.Therefore, now it


should show nextId as 4.

// Output of this line

E.showNextId();

// should be 4 but it will give 6 as output.

Output
Id=1
Name=GFG1
Age=56
Id=2
Name=GFG2
Age=45
Id=3
Name=GFG3
Age=25
Next employee id will be=4
Next employee id will be=4
Next employee id will be=4
Id=4
Name=GFG4
Age=23
Id=5
Name=GFG5
Age=21
Next employee id will be=6
Next employee id will be=6
Next employee id will be=6
Now to get the correct output:
Now garbage collector(gc) will see 2 objects free. Now to decrement nextId,gc(garbage collector)
will call method to finalize() only when we programmers have overridden it in our class. And as
mentioned previously, we have to request gc(garbage collector), and for this, we have to write the
following 3 steps before closing brace of sub-block.
1. Set references to null(i.e X = Y = null;)
2. Call, System.gc();
3. Call, System.runFinalization();
Now the correct code for counting the number of employees(excluding interns)
Java

// Correct code to count number of employees excluding interns.

class Employee {

private int ID;

private String name;

private int age;

private static int nextId = 1;


// it is made static because it is keep common among all and shared by all
objects

public Employee(String name, int age)

this.name = name;

this.age = age;

this.ID = nextId++;

public void show()

System.out.println("Id=" + ID + "\nName=" + name + "\nAge=" + age);

public void showNextId()

System.out.println("Next employee id will be=" + nextId);

protected void finalize()

--nextId;// In this case,gc,will call finalize() for 2 times for 2 objects

public class UseEmployee {

public static void main(String[] args)

{
Employee E = new Employee("GFG1", 56);

Employee F = new Employee("GFG2", 45);

Employee G = new Employee("GFG3", 25);

E.show();

F.show();

G.show();

E.showNextId();

F.showNextId();

G.showNextId();

// It is sub block to keep

// all those interns.

Employee X = new Employee("GFG4", 23);

Employee Y = new Employee("GFG5", 21);

X.show();

Y.show();

X.showNextId();

Y.showNextId();

X = Y = null;

System.gc();

System.runFinalization();

E.showNextId();
}

Output
Id=1
Name=GFG1
Age=56
Id=2
Name=GFG2
Age=45
Id=3
Name=GFG3
Age=25
Next employee id will be=4
Next employee id will be=4
Next employee id will be=4
Id=4
Name=GFG4
Age=23
Id=5
Name=GFG5
Age=21
Next employee id will be=6
Next employee id will be=6
Next employee id will be=4

this keyword in Java


There can be a lot of usage of Java this keyword. In Java, this is a reference
variable that refers to the current object.
Usage of Java this keyword
Here is given the 6 usage of java this keyword.
1. this can be used to refer current class instance variable.

2. this can be used to invoke current class method (implicitly)

3. this() can be used to invoke current class constructor.

4. this can be passed as an argument in the method call.

5. this can be passed as argument in the constructor call.

6. this can be used to return the current class instance from the method.
1. Using ‘this’ keyword to refer current class
instance variables
class Test
{
int a;
int b;

// Parameterized constructor
Test(int a, int b)
{
this.a = a;
this.b = b;
}

void display()
{
//Displaying value of variables a and b
System.out.println("a = " + a + " b = " + b);
}

public static void main(String[] args)


{
Test object = new Test(10, 20);
object.display();
}

Output:
a = 10 b = 20
Using this() to invoke current class constructor
class Test
{
int a;
int b;

//Default constructor
Test()
{
this(10, 20);
System.out.println("Inside default constructor \n");
}

//Parameterized constructor
Test(int a, int b)
{
this.a = a;
this.b = b;
System.out.println("Inside parameterized constructor");
}

public static void main(String[] args)


{
Test object = new Test();
}
}
Output:
Inside parameterized constructor
Inside default constructor
2. Using this() to invoke current class constructor

class Test

int a;

int b;

//Default constructor

Test()

this(10, 20);

System.out.println("Inside default constructor \n");

//Parameterized constructor

Test(int a, int b)

this.a = a;

this.b = b;

System.out.println("Inside parameterized constructor");

public static void main(String[] args)

Test object = new Test();

Output:
Inside parameterized constructor
Inside default constructor

Calling parameterized constructor from default constructor:

class A{
A(){
this(5);
System.out.println("hello a");
}
A(int x){
System.out.println(x);
}
}
class TestThis6{
public static void main(String args[]){
A a=new A();
}}

Real usage of this() constructor call


The this() constructor call should be used to reuse the constructor from the constructor. It
maintains the chain between the constructors i.e. it is used for constructor chaining. Let's see the
example given below that displays the actual use of this keyword

class Student
{
int rollno;
String name,course;
float fee;
Student(int rollno,String name,String course){
this.rollno=rollno;
this.name=name;
this.course=course;
}
Student(int rollno,String name,String course,float fee)
{
this(rollno,name,course);//reusing constructor
this.fee=fee;
}
void display(){System.out.println(rollno+" "+name+" "+course+" "+fee);}
}
class TestThis7{
public static void main(String args[]){
Student s1=new Student(111,"ankit","java");
Student s2=new Student(112,"sumit","java",6000f);
s1.display();
s2.display();
}}
Note Rule: Call to this() must be the first statement in constructor.

3. Using ‘this’ keyword to return the current class instance


class Test{

int a;

int b;

//Default constructor

Test()

a = 10;

b = 20;

//Method that returns current class instance

Test get()

{
return this;

//Displaying value of variables a and b

void display()

System.out.println("a = " + a + " b = " + b);

public static void main(String[] args)

Test object = new Test();

object.get().display();

Output:
a = 10 b = 20

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. Let's see the example:

class S2{
void m(S2 obj){
System.out.println("method is invoked");
}
void p(){
m(this);
}
public static void main(String args[]){
S2 s1 = new S2();
s1.p();
}
}
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. Let's see the example:

class B{
A4 obj;
B(A4 obj){
this.obj=obj;
}
void display(){
System.out.println(obj.data);//using data member of A4 class
}
}

class A4{
int data=10;
A4(){
B b=new B(this);
b.display();
}
public static void main(String args[]){
A4 a=new A4();
}
}

You might also like