r20 Unit 2 Final
r20 Unit 2 Final
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.
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:
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());
}
}
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
//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();
}
}
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.
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.
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.
There are two types of nested classes non-static and static nested classes. The non-static nested
classes are also known as inner classes.
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.
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.
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.
// Class 1
// Outer class
class Outer {
void outerMethod()
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
class Inner {
// Main driver 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.
LocalInner1.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:
interface Eatable{
void eat();
class TestAnnonymousInner1{
};
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).
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:
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.
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:
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 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
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.
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
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.
Bike10(){
speedlimit=70;
System.out.println(speedlimit);
}
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 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.
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.
Counter(){
count++;//incrementing value
System.out.println(count);
}
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.
Counter2(){
count++;//incrementing the value of static variable
System.out.println(count);
}
1
2
3
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.
class A3{
static{
System.out.println("static block is invoked");
System.exit(0);
}
}
Test it Now
Output:
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
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.
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
class Employee {
private static int nextId = 1;// it is made static because it keep common is
shared by all objects among all and
{ this.name = name;
this.age = age;
this.ID = nextId++;
+ "\nAge=" + age);
+ nextId);
class UseEmployee {
F.show();
G.show();
E.showNextId();
F.showNextId();
G.showNextId();
X.show();
Y.show();
X.showNextId();
Y.showNextId();
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=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
class Employee {
this.name = name;
this.age = age;
this.ID = nextId++;
{
Employee E = new Employee("GFG1", 56);
E.show();
F.show();
G.show();
E.showNextId();
F.showNextId();
G.showNextId();
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
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);
}
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");
}
class Test
int a;
int b;
//Default constructor
Test()
this(10, 20);
//Parameterized constructor
Test(int a, int b)
this.a = a;
this.b = b;
Output:
Inside parameterized constructor
Inside 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();
}}
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.
int a;
int b;
//Default constructor
Test()
a = 10;
b = 20;
Test get()
{
return this;
void display()
object.get().display();
Output:
a = 10 b = 20
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();
}
}