CPS 335/CPS 500- Java Programming for the Internet

Session 7

Constructors, Finalizers and Inner Class

 

Saying that a constructor is a method is like saying that the Australian platypus is just another mammal. To understand the platypus, it is important to know how it is different from other mammals. To understand the constructor, it is similarly important to understand how it differs from a method.

Purpose and Function
Constructors have one purpose in life: to create an instance of a class. This can also be called creating an object, as in:


Platypus p1 = new Platypus();

The purpose of methods, by contrast, is much more general. A method's basic function is to execute Java code.

Signature Differences
Constructors and methods differ in three aspects of the signature: modifiers, return type, and name. Like methods, constructors can have any of the access modifiers: public, protected, private, or none (often called package or friendly). Unlike methods, constructors can take only access modifiers. Therefore, constructors cannot be abstract, final, native, static, or synchronized.

The return types are very different too. Methods can have any valid return type, or no return type, in which case the return type is given as void. Constructors have no return type, not even void.

Finally, in terms of the signature, methods and constructors have different names. Constructors have the same name as their class; by convention, methods use names other than the class name. If the Java program follows normal conventions, methods will start with a lowercase letter, constructors with an uppercase letter. Also, constructor names are usually nouns because class names are usually nouns; method names usually indicate actions.

The use of "this"
Constructors and methods use the keyword this quite differently. A method uses this to refer to the instance of the class that is executing the method. Static methods do not use this; they do not belong to a class instance, so this would have nothing to reference. Static methods belong to the class as a whole, rather than to an instance. Constructors use this to refer to another constructor in the same class with a different parameter list. Study the following code:


public class Platypus {

       String name;

       Platypus(String input) {
               name = input;
       }

       Platypus() {
               this("John/Mary Doe");
       }

       public static void main(String args[]) {
               Platypus p1 = new Platypus("digger");
               Platypus p2 = new Platypus();
       }
}

In the code, there are two constructors. The first takes a String input to name the instance. The second, taking no parameters, calls the first constructor by the default name "John/Mary Doe".

If a constructor uses this, it must be in the constructor's first line; ignoring this rule will cause the compiler to object.

The use of "super"
Methods and constructors both use
super to refer to a superclass, but in different ways. Methods use super to execute an overridden method in the superclass, as the following example illustrates:


class Mammal {
       void getBirthInfo() {
               System.out.println("born alive.");
       }
}

class Platypus extends Mammal {
       void getBirthInfo() {
               System.out.println("hatch from eggs");
               System.out.print("a mammal normally is ");
               super.getBirthInfo();
       }
}

In the above program, the call to super.getBirthInfo() calls the overridden method of the Mammal superclass.

Constructors use super to invoke the superclass's constructor. If a constructor uses super, it must use it in the first line; otherwise, the compiler will complain. An example follows:


public class SuperClassDemo {
        SuperClassDemo() {}
}

class Child extends SuperClassDemo {
       Child() {
               super();
       }
}

In the above (and trivial!) example, the constructor Child() includes a call to super, which causes the class SuperClassDemo to be instantiated, in addition to the Child class.

Compiler-supplied code
The new Java programmer may stumble when the compiler automatically supplies code for constructors. This happens if you write a class with no constructors; the compiler will automatically supply a no-argument constructor for you. Thus, if you write:


public class Example {}

it is functionally equivalent to writing:


public class Example{
       Example() {}
}

The compiler also automatically supplies code when you do not use super (using zero or more parameters) as the first line of a constructor. In this case, the computer automatically inserts super. Thus, if you write:


public class TestConstructors {
       TestConstructors() {}
}

it is functionally equivalent to writing:


public class TestConstructors {
       TestConstructors() {
              
super;
       }
}

The sharp-eyed beginner may wonder how the above program can call the parent class's constructor when TestConstructor is not extending any class. The answer is that Java extends the Object class when you do not explicitly extend a class. The compiler automatically supplies a no-argument constructor if no constructor is explicitly declared, and automatically supplies a no-argument super call when a constructor has no explicit call to super. So the following two code snippets are functionally equivalent:


public class Example {}

and


public class Example {
       Example() {
            
super;
       }
}

Inheritance
What is wrong with the following scenario? A lawyer is reading the will of
A. Class. Members of the Class family are gathered around a large conference table, some sobbing gently. The lawyer reads, "I, A. Class, being of sound mind and body, leave all my constructors to my children."

The problem is that constructors cannot be inherited. Fortunately for the Class children, they will automatically inherit any of their parents' methods, so the Class children will not become totally destitute.

Remember, Java methods are inherited, constructors are not. Consider the following class:


public class Example {
        public void sayHi {
                system.out.println("Hi");
        }

        Example() {}
}

public class SubClass extends Example {
}

The SubClass class automatically inherits the sayHi method found in the parent class. However, the constructor Example() is not inherited by the SubClass.

Summarizing the differences
Just as the platypus differs from the typical mammal, so too do constructors differ from methods; specifically in their purpose, signature, and use of this and super. Additionally, constructors differ with respect to inheritance and compiler-supplied code. Keeping all these details straight can be a chore; the following table provides a convenient summary of the salient points.

 

Topic

Constructors

Methods

Purpose

Create an instance of a class

Group Java statements

Modifiers

Cannot be abstract, final, native, static, or synchronized

Can be abstract, final, native, static, or synchronized

Return type

No return type, not even void

void or a valid return type

Name

Same name as the class (first letter is capitalized by convention) -- usually a noun

Any name except the class. Method names begin with a lowercase letter by convention -- usually the name of an action

this

Refers to another constructor in the same class. If used, it must be the first line of the constructor

Refers to an instance of the owning class. Cannot be used by static methods

super

Calls the constructor of the parent class. If used, must be the first line of the constructor

Calls an overridden method in the parent class

Inheritance

Constructors are not inherited

Methods are inherited

Compiler automatically supplies a default constructor

If the class has no constructor, a no-argument constructor is automatically supplied

Does not apply

Compiler automatically supplies a default call to the superclass constructor

If the constructor makes no zero-or-more argument calls to super, a no-argument call to super is made

Does not apply

Differences between Constructors and Methods

What is garbage collection:
The process of automatically reclaiming the memory that is no longer in use is known as garbage collection. Garbage collection is a runtime component of Java which sits on top of the heap: memory area from which Java objects are created and periodically scans it for objects which are eligible to be reclaimed since there are no references to these objects in the program.

Object's life cycle:
In Java, life of an object is determined by the variable that references it. As long there is atleast one variable in the program accessing the object, that object will not become a candidate for garbage collection.

Finalizer:
Object class defines finalize method. This method is automatically called before an object is destroyed.

Following are the important considerations you must be aware of.

  1. Java does not guarantee that any particular object will be garbage collected, but makes a promise to call finalize on an object before reclaiming the memory it occupies.
  2. There is no guarantee what so ever as to when the finalize method is called. 
  3. There is no specific order in which the finalize method will be called. 
  4. Overriding finalize method in your class does not prioritize your object for garbage collection over any other object which do not have finalize method overridden in its class.
  5. Any exception thrown by the finalize method causes the finalization of that object to be stopped, but is not notified to the application and that object is still considered as finalized.
  6. finalize can run only once on the object in it's entire life cycle.
  7. finalize method defined in Object class, as such does nothing. In order to get some meaningful thing done, you will have to override this method in the subclass.
  8. Unlike constructors, which are chained from the subclass to superclass, finalizers are not implicitly chained.  It is considered a good programming practice if you call the superclass finalizer like super.finalize() in your subclass. 
  9. By default garbage collector will not execute the finalizers of any objects left on heap when the application exists.

So how to get an object garbage collected:
There is simply no way to force garbage collection, but you can suggest your intention of getting the object garbage collected to Java Virtual Machine and then live rest to it and hope for the best !!. Java provide following two methods.

public static void runFinalization()

The above method defined in Runtime class, runs finalization methods of any objects that have not yet been finalized. This methods only suggests the JVM to run the finalize methods on the objects which have not run and in any case cannot force it. Following is from Java API

Calling this method suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run. When control returns from the method call, the Java Virtual Machine has made a best effort to complete all outstanding finalizations.

Run the following code and see what output you get !!

public class MyClass
{
  public static void main (String args[])
  {
    finObj myObj = new finObj("Obj");
    System.runFinalization();
  }
}

class finObj
{
  String myName;
  finObj (String aname)
  {
    myName = aname;
  }
  public void finalize()
  {
    System.out.println(myName);
  }
}

public static void gc()

The above method is also defined in Runtime class, runs garbage collector and tries to reclaim memory from unused objects. Following is from Java API

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

Does Garbage collection a feature of every JVM:
There is no guarantee that every implementation of Java Virtual Machine(JVM) will have a garbage collection process. It is left to the implementers of JVM to decide whether to provide garbage collection mechanism or not, as well as what type of algorithm to achieve it. 

Inner class
It is possible to nest a class definition within another class and treat the nested class like any other method of that class.
 

class Enclosingclass

{

     class InnerClassP

            {
                        ……

                        ……

            }

}
 

the instance of the inner class can exist only within the instance of the enclosing class and it has direct access to instance variables and methods of its enclosing instance.
 
 public class Parcel
{
     class Contents      // inner class

     {                 

          private int i = 6;

          public int value()      // a function which returns the value of the member   

                                  // variable j for the object which calls it. 

          {

              return i;
          }

     }

 

     class Destination                 // inner class

     {

          private String label;   // private variables cannot be accessed by

                                  // functions which are outside the class(Destination)

         

          Destination(String whereto)

          {

              label = whereto;

          }

 

          String readlabel()

          {

              return label;

          }

     }

    

     public void ship(String dest)

     {

          Contents c = new Contents();          // instance of the Contents class

          Destination d = new Destination(dest); // instance of the destination class

                                                // with the constructor overwritten

          System.out.println("Shipped "+ c.value() + " items  to" + dest);

     }

 

     public static void main(String args[])

     {

          Parcel p = new Parcel();     // p is the object for the Parcel class

          p.ship("Congo");

     }

}
   

The inner classes are the Destination class and the Contents class its instance is created in the ship function of the Parcel class, here the destination is fixed as Congo.

HW7

Due Date:

March 21st 2005 Midnight.

 


Return to Index



Java is a trademark of Sun Microsystems, Inc.

Department of Electrical Engineering and Computer Science
Syracuse University


This Page was compiled by Vishal Kapashi on
01 March 2005.