Pass-by-value, Garbage Collection, Final

Java is always pass-by-value.

The problem we’re facing here is statements like – Objects are passed by reference, and primitives are passed by value – This is wrong or partially correct. Everyone will agree that primitive values are passed by value, there is no such thing as pointers/reference to a primitive. However Objects are not passed by reference. A correct statement would be Objects reference are passed by value. Lets take an example:


package mynotes.shortConcepts;

public class Point {

private double x;
 private double y;

public Point(double x, double y) {
 this.x = x;
 this.y = y;
 }

@Override
 public String toString() {
 return "X::" + this.x + " Y::" + this.y;
 }

public double getX() {
 return x;
 }

public void setX(double x) {
 this.x = x;
 }

public double getY() {
 return y;
 }

public void setY(double y) {
 this.y = y;
 }

}


package mynotes.shortConcepts;

public class PassByValue {

public static void tricky(Point p1, Point p2) {
 p1.setX(100);
 p1.setY(100);
 Point temp = p1;
 p1 = p2;
 p2 = temp;
 System.out.println("p1::"+p1);
 System.out.println("p2::"+p2);
 }

public static void main(String[] args) {

Point point1=new Point(0,0);
 Point point2=new Point(50,50);
 System.out.println("Point1::"+point1);
 System.out.println("Point2::"+point2);
 tricky(point1,point2);
 System.out.println("Point1::"+point1);
 System.out.println("Point2::"+point2);

}

}

Output:


Point1::X::0.0 Y::0.0
Point2::X::50.0 Y::50.0
p1::X::50.0 Y::50.0
p2::X::100.0 Y::100.0
Point1::X::100.0 Y::100.0
Point2::X::50.0 Y::50.0

The method successfully alters the value of point1, however, a swap of point1 and point2 fails! This is the major source of confusion. In the main() method, point1 and point2 are nothing more than object references. When you pass point1 and point2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references.

Garbage Collection

Storage for objects is allocated in a designated part of the memory called the heap. Having an automatic garbage collector frees the programmer from the responsibility of writing code for deleting objects. Time critical applications should bear in mind that the automatic garbage collector runs as a background task and may have a negative impact on their performance. An automatic garbage collector essentially performs two tasks:

  • decides if and when memory needs to be reclaimed
  • finds objects that are no longer needed by the program and reclaims their storage

A method need not always leave objects to be garbage collected after its termination. It can facilitate garbage collection by taking suitable action, for example, by nulling references.

Object Finalization

Object finalization provides an object with a last resort to undertake any action before its storage is reclaimed. The automatic garbage collector calls the finalize() method in an object that is eligible for garbage collection before actually destroying the object. The finalize() method is defined in the Object class.

protected void finalize() throws Throwable

An implementation of the finalize() method is called a finalizer. A subclass can override the finalizer from the Object class in order to take more specific and appropriate action before an object of the subclass is destroyed. Note that the overridden method cannot narrow the visibility of the method and it must be declared either protected or public.

A finalizer can, like any other method, catch and throw exceptions. However, any exception thrown but not caught by a finalizer that is called by the garbage collector is ignored, and the finalization of this object is terminated. The finalizer is only called once on an object, regardless of whether any exception is thrown during its execution. In case of finalization failure, the object still remains eligible for disposal at the discretion of the garbage collector.

Invoking Garbage Collection Programmatically

Although Java provides facilities to invoke the garbage collection explicitly, there are no guarantees that it will be run. The program can only request that garbage collection be performed, but there is no way that garbage collection can be forced.

System.gc() method can be used to request garbage collection. and System.runFinalization() method to tell do any pending finalizers to be run for all the eligible objects for GC.

Alternatively, corresponding methods in the Runtime class can be used. A Java application has a unique Runtime object that can be used by the application to interact with the JVM. An application can obtain this object by calling the method Runtime.getRuntime() . The Runtime class provides various methods related to memory issues.

static Runtime getRuntime() – Returns the Runtime object associated with the current application.
void gc() – Requests that garbage collection be run. However, it is recommended to use the more convenient static method System.gc().
void runFinalization() – Requests that any pending finalizers be run for objects eligible for garbage collection. Again, it is more convenient to use the static method System.runFinalization().
long freeMemory() – Returns the amount of free memory (bytes) in the JVM that is available for new objects.
etc….

Java Final Keyword

Following are some of the scenarios for using final keyword:

  • A variable that is declared as final and not initialized is called a blank final variable. A blank final variable forces the constructors to initialise it.
  • A static final variable has to initialized there only.
  • When applied to a variable (reference): The reference variable cannot point to any other object on the heap.
  • Java classes declared as final cannot be extended. Restricting inheritance.
  • Methods declared as final cannot be overridden.
  • Method Arguments as final – The final keyword when used for parameters/variables in Java marks the reference as final. By marking the new references final, you protect them from reassignment. It’s considered sometimes a good coding practice.It just means that you can’t write: arg1 = null;arg2= new …; but you can still write: arg1.setXXX(…); arg2.setXXX(…). Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.

Grab all the code from my GitHub repository.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: