The Object SuperclassJ8 Home « The Object Superclass

We finish the section with two lessons looking at the Object superclass, the 'daddy' of all objects. To explain what we mean by the last sentence, we need to first look back to the first Java class we wrote on the site, the Hello.java class:


package info.java8;
public class Hello {
   public static void main (String[] args) {
      System.out.println("Hello World");
   }
}

Unbeknown to us, this simple program was implicitly extended by the compiler, in fact every program we write has an implicit superclass called Object. How can this be though? Looking back to earlier lessons in the section how can our Garbage class extend Truck and Object, we know we can only extend one class. Well the compiler just travels up the inheritance tree and tries to extend our Truck class. The Truck class extends the Vehicle class so the compiler travels up the tree again. The Vehicle class extends nothing so the compiler implicitly extends the Vehicle class with Object. What this means for us is that we get to inherit the methods of Object which we will talk about as we go through this lesson. For now, we just need to know that we always inherit from Object at the top of any hierarchy we create. Before we look at the methods of the Object class lets list some points about Object:

  • Any class that doesn't implicitly extend another class, is implicitly extended by the compiler to extend Object.
  • Object is a concrete class so we can create objects of type Object.
  • Every class inherits the non-final methods of Object and these methods can be overridden.
  • We can use Object as a polymorphic type for methods that need to work with objects of any type.
    • So if we can use Object as a polymorphic type, why not use Object with all our methods, parameters and return types? There are two very good reasons not to do this:
      1. Java is a strongly typed language and as such cares about the type of the variables we declare. As we know whenever we declare a variable in Java, we have to give it a type, or the compiler complains when we come to compile the code. If we made every parameter and return type Object bang goes our type-safety. Instead of catching errors at compile time, we may run code for months before we get a runtime error, or even worse not notice an error at all, not a pleasant prospect.
      2. Inheritance, remember this only works up the inheritance tree as explained in inheritance method invocation. So if we made everything reference Object, what happens when we try to use the load() method from our Vehicle classes on the Object reference type? The compiler doesn't allow it as Object knows nothing of subclass methods unless they have been overridden. Therefore the only methods that can be called on Object are its own methods, or overrides thereof.
    So although it can be very useful to use the Object reference type polymorphically, and on occasions this is exactly what we want to do, it comes with a price.

Object Methods Overview Top

The table below shows the declarations of all the methods in the Object class:

Method Declaration Description
Discussed in this lesson
protected void finalize()Called by the garbage collector on an object before that object is discarded.
public final Class<? extends Object> getClass()Obtains and returns the runtime class of an object.
The <? extends Object> syntax is an example of a generic type which is discussed in the Generics section.
public String toString()Returns a string description of the object.
Discussed in the Checking Object Equality Lesson
public boolean equals(Object obj)Indicates whether another object is equal to the invoking object.
public int hashCode()Returns the hash code value associated with the object.
Discussed in the Concurrency Section
public final void notify()Wakes up a single thread that is waiting on the invoking object's lock.
public final void notifyAll() Wakes up all threads that are waiting on the invoking object's lock.
public final void wait()Current thread is put into a wait state until another thread invokes the notify()or notifyAll() method for this object.
public final void wait(long timeout)Current thread is put into a wait state until either another thread invokes the notify() or notifyAll() method for this object, or a specified amount of time has elapsed.
public final void wait(long timeout, int nanos)Current thread is put into a wait state until another thread invokes the notify() or notifyAll() method for this object, or a specified amount of time has elapsed, or a certain amount of real time has elapsed.
Not discussed
protected Object clone()Creates and returns a shallow copy of this object.

We will go through the first three methods in much greater detail as we go through this lesson and look at the equals() and hashCode() method in the Checking Object Equality lesson. Use the links in the table above to go the Concurrency section for more information on the other Object methods we discuss on the site. For more information on the clone() method follow the link below.

Java Documentation Top

As mentioned in the first two sections Java comes with very rich documentation. The following link will take you to the online version of documentation for the JavaTM 2 Platform Standard Edition 5.0 API Specification. Take a look at the documentation for the Object class which you can find by scrolling down the lower left pane and clicking on Object. You will go back to this documentation time and time again so if you haven't done so already I suggest adding this link to your browser's favourites toolbar for fast access.

The finalize() Method Top


  • The finalize() method is only ever invoked once, for any given object, by the JVM.

The finalize() method of the Object class is called by the garbage collector on an object before that object is discarded. The finalize method in the Object class doesn't execute any specific tasks, but gives us the opportunity to override. We may want to do this to clear up any resources held by an object such as closing a file used by it.

We have no control over when the garbage collector runs as this is in the control of the JVM. The garbage collector runs its collection efficiently and this means it usually runs when there are a lot of objects to discard.

Overriding finalize() Top

To see an overridden finalize() method in action we are going to have to instantiate a lot of objects and then make these objects eligible for garbage collection:


package info.java8;
/*
  Class to show an overridden finalize() method in action
*/ 
public class Finalize {
    private int i;
    
    Finalize(int i) {
        this.i = i;
    }
    /*
      Instantiate a Finalize object and immediately descope it
    */ 
    public void CreateFinalize(int i) {
        Finalize f = new Finalize(i);
    }
    /*
      Overridden finalize() method
    */ 
    protected void finalize() {
        System.out.println("The finalize() method called on object: " + i);
    }
    /*
      You may need to change the iterator to get this to work!
    */ 
    public static void main (String[] args) {
        Finalize f = new Finalize(0);
        for (int i=1; i < 300000; i++) {
            f.CreateFinalize(i);
        }
    }
}

Save, compile and run the Finalize class in directory   c:\_OOConcepts in the usual way.

run finalize()

The above screenshot shows the output of running our Finalize class on my machine. You may have to increase the iterator within the for loop to get it to work.

The getClass() Method Top

The getClass() method of the Object class obtains and returns the runtime class of an object, or put another way the object that was instantiated.


package info.java8;
/*
  Test Class for the getClass() method
*/ 
public class GetClassTest {
    public static void main (String[] args) {
        Vehicle car = new Car();
        System.out.println(car.getClass());
        Bus bus = new Bus();
        System.out.println(bus.getClass());
    }
}

Save, compile and run the file in directory   c:\_OOConcepts in the usual way.

run getClass()

The above screenshot shows the output of running our ATest test class. As you can see the method returns the class of the instantiated object.

The toString() Method Top

The toString() method of the Object class returns a string description of the object which consists of the name of the class, the @ symbol and the unsigned hexadecimal representation of the hash code of the object. The official documentation from Oracle encourages us to override this method in our subclasses, which as we now know, are all subclasses of Object. Before we create an override lets look at the output of the toString() method we inherit from Object:


package info.java8;
/*
  Test Class for the Object toString() method
*/ 
public class ToStringTest {
    public static void main (String[] args) {
        Carrier carrier = new Carrier(10, 20);
        System.out.println(carrier.toString());
    }
}

Save, compile and run the file in directory   c:\_OOConcepts in the usual way.

run toString()

The above screenshot shows the output of running our ToStringTest test class. As you can see the method returns the class of the instantiated object, the @ symbol and a number, not very meaningful.

Overriding toString() Top

What we need to do is override the Object toString() method in our Carrier class to give us some more information about the object state of instances we create:


package info.java8;
/*
  A Carrier class
*/ 
public class Carrier {
    ...
    /*
      A Carrier class 
    */    
    public String toString() {
        String strVal = "[" + this.people + ", " + this.cost + "]";
    }
}

After adding the toString override to the Carrier class, save and compile it and rerun the ToStringTest test class in directory   c:\_OOConcepts in the usual way.

run toString() 2

The above screenshot shows the output of running our ToStringTest test class. We have overridden the Object toString() method in our Carrier class with something more meaningful to the class in question.

Related Quiz

OO Concepts Quiz 19 - The Object Superclass

Lesson 19 Complete

In this lesson we took a first look at the Object object, the daddy of all objects.

What's Next?

We finish the section on OO Concepts by looking at object equality and how to use it correctly in our classes.