Java Programming/API/java.lang.Object

From Wikibooks, open books for an open world
< Java Programming
Jump to: navigation, search

java.lang.Object[edit]

Object class is the superclass of all Java classes. All Java classes inherited from this class. This makes it possible that we can have methods that are available in all Java classes. This simplifies things compared to C++ where this is not the case.

Object class methods Description
boolean equals( Object o ); Gives generic way to compare objects
Class getClass(); The Class class gives us more information about the object
int hashCode(); Returns a hash value that is be used to search object in a collection
void notify(); Used in synchronizing threads
void notifyAll(); Used in synchronizing threads
String toString(); Can be used to convert the object to String
void wait(); Used in synchronizing threads
protected Object clone() throws CloneNotSupportedException ; Return a new object that are exactly the same as the current object
protected void finalize() throws Throwable; This method is called just before an object is garbage collected

equals() Method[edit]

  • The 'boolean equals( Object o );' method gives a generic way to compare objects for equality. You need to override it, in your class. Then you can write:
public boolean isCustomerExsist( Customer newCustomer )
{
   boolean isRet = false;
   Iterator iter = _collAllCustomer.iterator();
   while ( iter.hasNext() )
   {
      if ( newCustomer.equals( (Customer) iter.next() )
      {
         // -- Customer was found ---
         isRet = true;
      }
   }
  return isRet;
}

Keep in mind that when you override equals(), you always need to also override hashCode() so the two methods are consistent. If two objects are equal, they must have the same hashcode.

For more information also see Java Programming/Comparing Objects

getClass() Method[edit]

There is a Class object for each class in your program. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects. Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded

For more information see Class.

The most popular use of the Class is to find out the object's class name during runtime.

import com.yourCompany.Customer;
...
Object obj = new Customer();
...
System.out.println( "Name:" + obj.getClass().getName() );

The output:

Name: com.yourCompany.Customer

hashCode() Method[edit]

In most cases you should not override this method, since the default implementation of this method returns a unique number for the object. The number is used when the object is put into a collection. Finding an object in a big collection may take a while, if objects are compared one by one sequentially. To speed the search up, objects may be placed in a tree structure, weighted by an integer hash code. Comparing the hash code while navigating through the tree, the number of object comparisons can be reduced.

   _______ A _____
   |              |  
__ B__          __C__
|     |        |     |
D     E        F     G
...  ...      ...   ...

To give you a general idea of how it may work, see the above diagram. Let's say we are searching object G. If at each 'node' of the tree we can decide which way to go, then by 3 steps we reach the object G.

By constrast in a linear search:

A --- B  ----- C  ---- C  ---- D  ---- E ---- F ---- G

We would need 8 steps to reach the object G.

So the search will be faster with the tree structure. Adding a new object however, will be slower because the tree structure needs to be maintained. The place of the new object in the tree has to be found first.

toString() Methods[edit]

This method can be used to convert an object to a String. It is automatically used in many places to convert objects to String; for example: in PrintStream, in StringBuffer, and for the string concatenation operator when used on objects.

The default implementation returns a weird string with the class name and the hash code.

For example:

String str = "This customer is " + objCust;

The toString() method is called on the objCust object.

The toString() method can also be used for debugging:

public class Customer
{
   private String _name;
   private String _address;
   private String _age;
...
   public String toString()
   {
       StringBuffer buf = StringBuffer();
       buf.append( "Name   = " );  buf.append( _name );     buf.append( "\n" );
       buf.append( "Address= " );  buf.append( _address );  buf.append( "\n" );
       buf.append( "Age    = " );  buf.append( _age );      buf.append( "\n" );
    ...
       return buf.toString();
   }
...
}

After that whenever in your code, you want to see what a customer object is, just call:

System.out.println( objCustomer );

Synchronizing Threads Methods[edit]

In a multi-threaded environment, when more than one thread can access and modify a resource, the outcome could be unpredictable. For example, let's have a counter variable that is incremented by more than one thread.

Beware! Synchronization is an ambiguous term. It doesn't consist of making all threads executing the same code section at the same time. It is the opposite. It avoids any two threads to execute a same code section at the same time. It synchronizes the end of a processing with the beginning of a second processing.

Example Code section 1.1: Counter implementation
int counter = 0;
...
counter += 1;

The above code is built up by the following sub-operations:

  • Read ; read variable counter
  • Add ; add 1 to the value
  • Save ; save the new value to variable counter

Let's say that two threads need to execute that code, and if the initial value of the counter variable is zero, we expect after the operations the value to be 2.

Thread 1   Thread 2
         
Read 0   Read 0
         
Add 1   Add 1
         
Save 1   Save 1
         

In the above case Thread 1 operation is lost, because Thread 2 overwrites its value. We'd like Thread 2 to wait until Thread 1 finishes the operation. See below:

Thread 1   Thread 2
         
Read 0   blocked
         
Add 1   blocked
         
Save 1   unblocked
         
  Read 1
     
  Add 1
     
  Save 2
     
Critical Section 
In the above example the code counter+=1 must be executed by one and only one thread at any given time. That is called critical section. During programming, in a multi-threading environment we have to identify all those pieces of code that belongs to a critical section, and make sure that only one thread can execute those codes at any given time. That is called synchronization.
Synchronizing threads 
The thread access to a critical section code must be synchronized among the threads, that is to make sure that only one thread can execute them at any given time.
Object monitor 
Each object has an Object monitor. Basically it is a semaphore, indicating if a critical section code is being executed by a thread or not. Before a critical section can be executed, the thread must obtain an Object monitor. Only one thread at a time can own that object's monitor.
A thread becomes the owner of the object's monitor in one of three ways 
  • By executing a synchronized instance method of that object. See synchronized keyword.
  • By executing the body of a synchronized statement that synchronizes on the object. See synchronized keyword.
  • For objects of type Class, by executing a synchronized static method of that class.
The Object Monitor takes care of the synchronization, so why do we need the "wait() and notify() methods"? 
For synchronization we don't really need them, however for certain situations it is nice to use them. A nice and considerate thread will use them. It can happen that during executing a critical section, the thread is stuck, cannot continue. It can be because it's waiting for an IO and other resources. In any case, the thread may need to wait a relatively long time. It would be selfish for the thread to hold on to the object monitor and blocking other threads to do their work. So the thread goes to a 'wait' state, by calling the wait() method on the object. It has to be the same object the thread obtained its object monitor from.
In the other hand though, a thread should call the wait() method only if there is at least one other thread out there who will call the notify() method when the resource is available, otherwise the thread will wait for ever, unless a time interval is specified as parameter.
Let's have an analogy. You go in a shop to buy some items. You line up at the counter, you obtain the attention of the sale-clerk - you get her "object-monitor". You ask for the item you want. One item needs to be brought in from a warehouse. It'll take more than five minutes, so you release the sales-clerk (give her back her "object-monitor") so she can serve other customers. You go into a wait state. Let's say there are five other customers already waiting. There is a sale-clerk, who brings in the items from the warehouse. As she does that, she gets the attention of the first sales-clerk, getting her object-monitor and notifies one or all waiting customer(s), so the waited customer(s) woke up and line up again to get the attention of the first sales-clerk.
Note the synchronization between the waiting customer and the sale-clerk who brings in the items. This is kind of producer-consumer synchronization.
Also note that there is only one object-monitor, belonging to the first sales-clerk. That object-monitor/the attention of clerk needs to be obtained first before a wait and a notify can happen.


final void wait() method 
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resume execution.
final void wait(long time) 
The same as wait, but the thread wakes after the specified time passes, regardless of whether there was a notify or not.
final void notify() 
This method should only be called by a thread that is the owner of this object's monitor. Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
final void notifyAll() 
Same as notify(), but it wakes up all threads that are waiting on this object's monitor.


What are the differences between the sleep() and wait() methods? 
Thread.sleep(millis)  
This is a static method of the Thread class. Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. The thread does not lose ownership of any monitors. It means that if the thread has an object-monitor, all other threads that need that monitor are blocked. This method can be called regardless whether the thread has any monitor or not.
wait()  
This method is inherited from the Object class. The thread must obtain the object-monitor of that object first before calling the wait() method. The object monitor is returned by the wait() method, so it does not block other threads wanting this object-monitor, while waiting.


See also:[edit]