As we have seen, new operator dynamically allocates memory for objects from the free memory which is available. But memory in a system is not infinite, so as we create more objects, at some point, the memory will be exhausted and the new operator will fail when no memory is available to create new objects. As developers we need to make sure that free memory is available before creating a new object. This can be achieved when we release already allocated memory when the objects are not needed anymore. Manually freeing memory can lead to errors and it creates unnecessary overhead to the developer. Java uses a different approach for handling this kind of situation and it is called garbage collection.
Java’s garbage collection releases the memory automatically by periodically checking for objects in our program. This does not require any programmer or developer intervention. When no references to an object exist, it assumes that this object is no more needed. It will find the memory occupied by this object and releases. This freed memory can be used for new allocations.
Garbage collection takes time so the Java Runtime system decides to run it when it is needed. This can be decided based on two conditions: There should be the object to free and there is a need to free them. So it is not possible to tell precisely when garbage collection will take place.
We use constructors to create an object and initialize. In the same way, when we are freeing an object, we may like to perform some operations.
For example, while creating an object we opened a file from the disk and we need to close it when we are freeing that object. In Java, this can be achieved by defining a finalize() method. It is similar to C++ destructors.
The syntax of finalize method is given below,
protected void finalize () { // finalization code here }
The keyword protected is an access modifier and specifies the access to finalize() method by other classes . We will learn more about access modifiers later.
It is important to understand that the finalize method will be called just before garbage collection. As we do not know when garbage collection can occur, we also do not when the finalize method will be executed.
When a method is called on an object, Java sends the reference to itself (object) implicitly as an argument. The name of this argument this. By using this keyword we can access data members and methods of that object. Below program explains about usage of this keyword.
/* This is a simple Java program about Class. Call this file KH_thisKeyword.java. */ class power { int base; int exponent; public power(int base, int exponent) { this.base = base; this.exponent = exponent; } int getPower() { int val = 1; if(this.exponent==0) return 0; for( int i = this.exponent; i>0; i--) val = val * this.base; return val; } } public class KH_thisKeyword { // A Java program begins with a call to main(). public static void main(String args[]) { power x = new power(4, 2); System.out.println(x.base + " raised to the " + x.exponent + " power is " + x.getPower()); } }
Download the code Run the code
Output:
4 raised to the 2 power is 16
Another most important feature of Java is to restrict access to members of a class. This can be achieved by using access modifiers.
Java provides three types of access modifiers, they are: public, private and protected.
Till now we did not use any access modifier in our programs. Hence, you might have understood that default access modifier is ‘package protected’ which is ‘public within the package’. Below program explains about access modifiers, try to access private member outside of class and see how the program behaves.
/* This is a simple Java program about Class. Call this file KH_thisKeyword.java. */ class MyClass { private int a; // private access public int b; // public access int c; // default access void setA(int a) { this.a = a; } int getA() { return a; } } class KH_AccessDemo { public static void main(String args[]) { MyClass ob = new MyClass(); /* Access to alpha is allowed only through its accessor methods. */ ob.setA(-99); System.out.println("ob.a is " + ob.getA()); // You cannot access alpha like this: // ob.a = 10; // Wrong! alpha is private! // These are OK because beta and gamma are public. ob.b = 88; ob.c = 99; } }
Download the code Run the code
output:
ob.a is -99