Monday, August 25, 2008

SCJP-WRAPPER

Wrapper Class Summary - Methods of interest for SCJP
Class Name parseXXX getXXX toString toHexString
Boolean static boolean getBoolean(String) String toString()
static String toString(boolean)*
Character String toString()
static String toString(char)*
Byte static byte parseByte(String)
static byte parseByte(String, int) String toString()
static String toString(byte)
Short static short parseShort(String)
static short parseShort(String, int) toString()
static String toString(short)
Integer static int parseInt(String)
static int parseInt(String, int) static Integer getInteger(String)
static Integer getInteger(String, int)
static Integer getInteger(String, Integer) String toString()
static String toString(int)
static String toString(int, int) static String toHexString(int)
Long static long parseLong(String)
static long parseLong(String, int) static Long getLong(String)
static Long getLong(String, long)
static Long getLong(String, Long) String toString()
static String toString(long)
static String toString(long, int) static String toHexString(long)
Float static float parseFloat(String) String toString()
static String toString(float)
Double static double parseDouble(String) String toString()
static String toString(double)
* indicates that the method is new to JDK 1.4

.equals() for Wrapper classes

So how about Wrapper classes - when are they "equal"? In particular, we want to focus on the .equals method. The Sun Certified Programmer for the Java 2 Platform 1.4 Exam state that you must know the following methods
doubleValue, floatValue, intValue, longValue, parseXxx, getXxx, toString, and toHexString.
Ah, but where is the equals() method you might ask? It's not there, so I don't need to worry about it! That would be wrong! There are several items of confluence for the SCP for Java 2 Platform 1.4 - we previously had .equals() required knowledge based on other objectives. Second, the new hashCode method objective has the hashCode() and equals() methods of utmost importance. Even if the equals() method is not covered, knowing how to test the equality of two Wrapper classes is an important interview question or on the job scenario.
Let us use the Float and Double classes as examples. A value of 5.0 wrapped by a Double and a value 5.0 wrapped by a Float are the same, no? After all, is not 5.0 the same as 5.0? The answer is no when defined by the equals() method.
Let's take a look at the following code snippet:
Double aDouble = new Double (5.0);
Float aFloat = new Float(5.0);
if ( aFloat.equals(aDouble) )
System.out.println("equals");
The result is true if and only if the argument is not null and is a Float object that represents a float that has the identical bit pattern to the bit pattern of the float represented by this object. For this purpose, two float values are considered to be the same if and only if the method floatToIntBits(float) returns the same int value when applied to each. Note that in most cases, for two instances of class Float, f1 and f2, the value of f1.equals(f2) is true if and only if
f1.floatValue() == f2.floatValue()
also has the value true.
Thus, in the above code snippet, the aDouble object needs to be of type Float, not Double, to be considered "equal" by the equals() method.
There are two exceptions for the Float equals() method:
 If f1 and f2 both represent Float.NaN, then the equals method returns true, even though Float.NaN==Float.NaN has the value false.
 If f1 represents +0.0f while f2 represents -0.0f, or vice versa, the equal test has the value false, even though 0.0f==-0.0f has the value true. This definition allows hashtables to operate properly.

toHexString
The toHexString method does approximately what you expect in that it returns a string which is a hex string version of the number. It has a natural partner in the toBinaryString method which returns a string that represents the number in its binary version. The following example code will output the strings 100 followed by 10.
public class NumberFormats{
public static void main(String argv[]){
System.out.println(Integer.toBinaryString(4));
System.out.println(Integer.toHexString(16));

}
}

• Wrapper class names differ from the primitives only in the initial upper case letter.
Exceptions are Integer, which wraps int and Character, which wraps char values.
• All wrapper objects can be constructed by passing a string EXCEPT Character wrapper class for char data type. Most of these constructor throws NumberFormatException, which is a runtime exception.
• Wrapper classes override equals() method. equals() on wrappers return false if both the objects are not instances of the same class. This statement is true even when the value they are wrapping has the same numerical value.
• All wrapper objects are immutable. Once an object is created, the wrapped primitive value cannot be changed.
• Wrapper classes are final and hence cannot be sub classed.
• Byte, Double, Float, Integer and Short extend the abstract Number class
• all are public final ie cannot be extended
• get around limitations of primitive types
• allow objects to be created from primitive types
• all the classes have two constructor forms
• a constructor that takes the primitive type and creates an object eg Character(char), Integer(int)
• a constructor that converts a String into an object eg Integer("1"). Throws a NumberFormatException if the String cannot be converted to a number
Note
• The Character class does not have a constructor that takes a String argument
• all, except Character, have a valueOf(String s) method which is equivalent to new Type(String s)
• all have a typeValue() method which returns the value of the object as it's primitive type. These are all abstract methods defined in Number and overridden in each class
• public byte byteValue()
• public short shortValue()
• public int intValue()
• public long longValue()
• public float floatValue()
• public double doubleValue()
• all the classes override equals(), hashCode() and toString() in Object
• equals() returns true if the values of the compared objects are the same
• hashCode() returns the same hashcode for objects of the same type having the same value
• toString() returns the string representation of the objects value
• all have a public static final TYPE field which is the Class object for that primitive type
• all have two static fields MIN_VALUE and MAX_VALUE for the minimum and maximum values that can be held by the type
Void
• There is also a wrapper class for Void which cannot be instantiated.
• The constructors and methods described above do NOT exist for the Void class although it does have the TYPE field.
Character
• contains two methods for returning the numeric value of a character in the various number systems
• public static int digit(char ch, int radix)
• public static int getNumber(char ch)
• and one method to return the character value of a number
• public static char forDigit(int digit, int radix)
• has two case conversion methods
• public static char toLowerCase(char ch)
• public static char toUpperCase(char ch)
• also contains a variety of other methods to test whether a character is of a specific type eg isLetter(), isDefined(), isSpaceChar(), etc
• getType() returns an int that defines a character's Unicode type
Integer, Short, Byte and Long
• all have parseType methods e.g. parseInt(), parseShort, etc that take a String and parse it into the appropriate type
• the Integer and Long classes also have the static methods toBinaryString(), toOctalString() and toHexString() which take an integer value and convert it to the appropriate String representation
Float and Double
• both classes have static fields which define POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN
• and the following methods to test a value
• public boolean isNan()
• public static boolean isNaN(type value)
• public boolean isInfinite()
• public static boolean isInfinite(type value)
• Float also has a constructor that takes a double value
• both classes have methods to convert a value into a bit pattern or vice versa
• public static int floatToIntBits(float value)
• public static float intBitsToFloat(int bits)
• public static long doubleToLongBits(double value)
• public static double longBitsToDouble(long bits)
parseInt
public static int parseInt(String s) throws NumberFormatException
 Parses the string argument as a signed decimal integer.
 The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value.
 The resulting integer value is returned, exactly as if the argument and the radix 10 were given as arguments to the parseInt(java.lang.String, int) method

public static int parseInt(String s, int radix) throws NumberFormatException
 Parses the string argument as a signed integer in the radix specified by the second argument.
 The characters in the string must all be digits of the specified radix (as determined by whether Character.digit(char, int) returns a nonnegative value), except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value.
 The resulting integer value is returned.
An exception of type NumberFormatException (during RUNTIME )is thrown if any of the following situations occurs:
• The first argument is null or is a string of length zero.
• The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX. ( radix >= 2 , <=36 )
• Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') provided that the string is longer than length 1.
• The value represented by the string is not a value of type int.
Examples:
parseInt("0", 10) returns 0
parseInt("473", 10) returns 473
parseInt("-0", 10) returns 0
parseInt("-FF", 16) returns -255
parseInt("1100110", 2) returns 102
parseInt("2147483647", 10) returns 2147483647
parseInt("-2147483648", 10) returns -2147483648
parseInt("2147483648", 10) throws a NumberFormatException // size is more than integer
parseInt("99", 8) throws a NumberFormatException // 9 is not there in octal system
parseInt("99", 37) throws a NumberFormatException // radix is > 36
parseInt("99", 1) throws a NumberFormatException // radix is <2
parseInt("Kona", 10) throws a NumberFormatException
parseInt("Kona", 27) returns 411787 // please note this..
getBoolean
public static boolean getBoolean(String name)
 Returns true if and only if the system property named by the argument exists and is equal to the string "true".
 (Beginning with version 1.0.2 of the JavaTM platform, the test of this string is case insensitive.)
 A system property is accessible through getProperty, a method defined by the System class.
 If there is no property with the specified name, or if the specified name is empty or null, then false is returned.
 Parameters: name - the system property name.
 Returns: the boolean value of the system property.
getInteger
 public static Integer getInteger(String nm, int val)
 Determines the integer value of the system property with the specified name.
 The first argument is treated as the name of a system property. System properties are accessible through the System.getProperty(java.lang.String) method. The string value of this property is then interpreted as an integer value and an Integer object representing this value is returned. Details of possible numeric formats can be found with the definition of getProperty.
 The second argument is the default value. An Integer object that represents the value of the second argument is returned if there is no property of the specified name, if the property does not have the correct numeric format, or if the specified name is empty or null.
 Parameters: nm - property name. val - default value.
 Returns: the Integer value of the property.



===============IMP POINTS FROM JAVARANCH==================================

 Boolean b1 = new Boolean("123");
Boolean b2 = new Boolean("123");
b1.toString() == b2.toString() // - Returns true
 Byte by = new Byte(“123”)
by.toString() == by.toString() // - Returns false . Same for other wrapper classes except boolean
Byte class ( and Other wrappers except Boolean )
----------
.toString() method creates a new String object and returns this every time you call this method.
Boolean class
-------------
.toString() method returns a String literal "true" or "false" depending upon the value of this Boolean object. This String literal will be in String pool and every time you call, the same ref. value (memory address) is returned
 Primitive type wrapper classes
a)allow primitive types to behave as reference types.
Some loose language here but the intention is TRUE, IMO.
b)allow operator overloading to be implemented for primitive numeric types.
NO!!
c)provide string parsing and conversion methods
YES as in Integer.parseInt(String s)
d)provide arithmetic operators such as '+','-'
NO!!
 Float f1 = new Float("10.0f"); //fine
Double f2 = new Double("10.0d"); // fine
Long f2 = new Long("10L"); //  NumberFormatException at RUNTIME
 "Neither L nor l is permitted to appear at the end of the string as a type indicator, as would be permitted in Java programming language source code".

SCJP-THREADS

Threads Important Points from Whizlabs:

 If class A extends Thread class and doesn't override the run method, calling new A ().start  No compile and run time errors. Thread class run is called, which does nothing.
 The run method can be overloaded. But the run method with
o public void run () {} is called when the start () is called on the thread.
 Sleep method must be enclosed in try-catch blocks as it throws Interrupted Exception. Same is the case with wait and join methods also. Otherwise it gives compile time error
 MyTherad mt = new MyThread (); mt.run ()  calls run method like any other method. It doesn’t throw compile or runtime errors.
 Every Java Thread is a member of a Thread group.  If you do not specify the group of a thread, it will be a member of the group of the thread that started it, or the member of the current thread’s group. So if you start a thread from main thread without specifying the thread group, this thread will be member of the main thread group.
 A group of threads can’t be assigned a priority applicable for all the threads of that group. In other words there is no setPriority () method in ThreadGroup class. Rather a ThradGroup can be assigned the maximum priority by calling the setMaxPriority () method indicating that no thread of that group can have more priority than the set value of the group.
 A thread group can contain any number of threads.
 You can’t differentiate between a new Thread and a dead thread because calling isAlive() method in both the situations will return false. Method isAlive() returns true if a thread has been started but not yet died i.e. a thread is either runnable, running or non-running state.
 If a Thread is assigned a priority more than Thread.MAX_PRIORITY, it will compile fine but it will throw IllegalArgumentException during runtime.
 If a thread’s priority is set within range of Thread.MIN_PRIORITY and Thread.MAX_PRIORITY but higher than the Thread Group’s Max Priority, it will compile fine but at run time the scheduling system will assign the thread’s priority the is lower of the two priorities.
 Thread may share data between one another
 wait(), suspend(), stop(), sleep()  will definitely stop a thread from executing
 yield(), setPriority(), notify(), notifyAll()  may not stop a running thread
 The yield() method is used to call from the currently running thread to allow another thread of the same or higher priority to run. It is not guaranteed that the Thread that grabs the CPU will be of the higher priority. It will depend on the underlying OS or the threading algorithm of the JVM
 A subclass decides whether an inherited method should be marked synchronized or not. A synchronized method can be inherited to be non-synchronized or vice versa.
 Synchronized methods can call methods which are not synchronized; there is no restriction on it.
 Static methods can be synchronized; in this case the lock is obtained on the Class object of the class.
 Directly sub classing Thread class does NOT give access to more functionality than using the Runnable interface
 It is very important to remember that synchronized modifier can NOT be applied to constructor; else it will give compiler error. However block synchronization can be used within the constructors.
 MyThread implements Runnable; if Mythread doesn’t implement the run method correctly, it will give compile error.
 Thread type (Daemon thread / User Thread) can be changed by calling setDaemon(boolean), as many times you wish BUT only before the thread has been started. Attempt to change the thread type after start(), will compile fine but will throw IllegalThreadStateException when run, which is an indirect subclass of RuntimeException.
 Thread name doesn’t need to be unique, so two threads with the same name can execute separately.
 public class Thread extends Object implements Runnable
 A thread is a thread of execution in a program.
 The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
 Every thread has a priority.
 Threads with higher priority are executed in preference to threads with lower priority.
 Each thread may or may not also be marked as a daemon.
 When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
 When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class).
 The Java Virtual Machine continues to execute threads until either of the following occurs:
o The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
o All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
 Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.

public interface Runnable:
 The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.
 The class must define a method of no arguments called run.
 This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread.
 Being active simply means that a thread has been started and has not yet been stopped.
 In addition, Runnable provides the means for a class to be active while not subclassing Thread.
 A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target.
 In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.
Method Description
public void run() When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's run method to be called in that separately executing thread
The general contract of the method run is that it may take any action whatsoever.

Methods of Thread Class:
Method Signature Description
public static Thread currentThread() Returns a reference to the currently executing thread object.
public static void yield() Causes the currently executing thread object to temporarily pause and allow other threads to execute.
public static void sleep(long millis) throws InterruptedException 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.
InterruptedException - if another thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
public static void sleep(long millis, int nanos) throws InterruptedException Causes the currently executing thread to sleep (cease execution) for the specified number of milliseconds plus the specified number of nanoseconds. The thread does not lose ownership of any monitors.
IllegalArgumentException - if the value of millis is negative or the value of nanos is not in the range 0-999999.
public void start() Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
IllegalThreadStateException - if the thread was already started.
public void run() If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
Subclasses of Thread should override this method.
public final void stop() Forces the thread to stop executing.
It is permitted to stop a thread that has not yet been started. If the thread is eventually started, it immediately terminates.
public void interrupt() Interrupts this thread.
First the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
public static boolean interrupted() Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).
Returns: true if the current thread has been interrupted; false otherwise.
public boolean isInterrupted() Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method.
Returns: true if this thread has been interrupted; false otherwise.
public void destroy() Destroys this thread, without any cleanup. Any monitors it has locked remain locked. (This method is not implemented.)
public final boolean isAlive() Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
public final void setPriority(int newPriority) Changes the priority of this thread.
First the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException.
Otherwise, the priority of this thread is set to the smaller of the specified newPriority and the maximum permitted priority of the thread's thread group.
Throws: IllegalArgumentException - If the priority is not in the range MIN_PRIORITY to MAX_PRIORITY.
SecurityException - if the current thread cannot modify this thread.
public final int getPriority() Returns this thread's priority.
public final void setName(String name) Changes the name of this thread to be equal to the argument name.
public final String getName() Returns this thread's name.
public final ThreadGroup getThreadGroup() Returns the thread group to which this thread belongs. This method returns null if this thread has died (been stopped).
public static int activeCount() Returns the number of active threads in the current thread's thread group.
public int countStackFrames() Deprecated
public final void join(long millis) throws InterruptedException Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
public final void join(long millis, int nanos) throws InterruptedException Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.
IllegalArgumentException - if the value of millis is negative the value of nanos is not in the range 0-999999.
public final void join() throws InterruptedException Waits for this thread to die.
public static void dumpStack() Prints a stack trace of the current thread. This method is used only for debugging.
public final void setDaemon(boolean on) Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be called before the thread is started.
This method first calls the checkAccess method of this thread with no arguments. This may result in throwing a SecurityException (in the current thread).
Parameters:
on - if true, marks this thread as a daemon thread.
Throws: IllegalThreadStateException - if this thread is active.

public final boolean isDaemon() Tests if this thread is a daemon thread.
public final void checkAccess() Determines if the currently running thread has permission to modify this thread.
public String toString() Returns a string representation of this thread, including the thread's name, priority, and thread group.
public static boolean holdsLock(Object obj) Returns true if and only if the current thread holds the monitor lock on the specified object.
This method is designed to allow a program to assert that the current thread already holds a specified lock: assert Thread.holdsLock(obj);
NullPointerException - if obj is null


Kai’s Notes:

(1) Stop a thread

Know what methods you can call to interrupt or suspend a thread.
Know which classes these methods reside in and whether they are staticor not.

* yield() and sleep() of Thread class are static.
* start(), run() and interrupt() of Thread class are non-static.
* wait(), notify() and notifyAll() of Object class are non-static.

When will the execution of a Thread eventually stop?
x a) In case another Thread with higher priority thread enters the runnable state.
x b) Through a call to suspend()
x c) Through a call to wait()
x d) Through a call to MediaTracker.waitforID()
e) If the current thread starts another thread.
I think the answer are a,b,c if you considering that stop means coming
back to ready state. What about choice d.

Reply#1: Choice d is also correct, because you can use MediaTracker to load one or more images and to wait until those images have been completely loaded and are ready to be used. So when waitForID() is called, the execution of the thread stops until all the images have been loaded. This is correct because I got this question in the exam, and I got 100% in threads.

Reply #2: One of the cloudy issues that I did not like about the test was the ambiguity of the word 'stop' on the test: do they mean entering the stop state or do they mean 'the thread ceases to execute, but can run in the future'. This question and the test will refer to the latter definition. Therefore:
(a) wrong, because of pre-emptive and time sharing OS differences.
(b) true, suspend() puts you in the blocked state so answer is true, BUT suspend is deprecated in java 1.2 so this should not be given as an alternative.
(c) true, wait() causes the thread execution to stop and enter the runnable queue for its time out period or being notified and obtaining a lock.
(d) false, MediaTracker works to keep track of image loading so the current thread can keep on doing whatever it does.
(e) false, how does a current thread start another thread? Yield() will cease the execution of the current thread to give another thread in the runnable queue a chance to run, and start() will put a newly created thread into the runnable queue, but nothing other than the OS can force
a thread to run.

Reply #3: These are the answers based on both the assumptions.
Assumption 1: Stop means the thread cannot be run again. In this case,
none of the answers are correct. Assumption 2: Stop means temporary
suspension of thread. In this case, a,b,c,d are correct.
a is correct, because the policy is governed by the underlying OS.
b is correct, coz u can call a suspend method to stop the thread temporarily.
c is correct, coz the thread releases the monitor and waits for another thread to issue a notify.(refer to JDK docs or API)
d is correct, coz the current thread waits until the mediatracker's done with its work.
e is false, coz starting another thread does not stop the currentthread.

Which methods or cases may cause a thread to stop executing:

x wait()

x sleep()

x suspend()

x stop()

x MediaTracker.waitForID() // Something about loading a graphic
image of MediaTracker class

x Interrupted()

x The program exits via a call to exit(0)

- If the current thread starts a new thread.

x In case another thread with higher priority enters the
runnable state.

Are we supposed to pick stop() and suspend(), because they are
deprecated? I didn't know about this question, but interrupting can't
stop a thread, it can only wake up sleeping or waiting thread.


Jyoti's notes: Conditions that might prevent a thread from executing :


x The thread is not the highest priority thread and so cannot get CPU time.

x The thread is waiting on a condition because someone invoked wait() for the thread.

x The thread has explicitly yielded control by invoking yield() to allow another thread of the same priority to run.

x The thread has been put to sleep using the sleep() method

x Someone has suspended the thread using the suspend() method. (deprecated in Java 2)

x It is blocked for file I/O

x There is more than one thread with the same highest priority and JVM is switching between these threads, at the moment, the thread in question is awaiting CPU time.

Does MediaTracker.waitForID() block the current thread?

Ans: If it didn't block the current thread, it could not do its job, right? :-) The objective is to WAIT UNTIL something happens. Of course, it doesn't stop the separate thread generated by the AWT to load the image. Or any other thread but its own. Also, the requirement that it be used in a "try/catch (InterruptedException e)" block suggests the same.

(2) Theory
The thread questions were tenuous and some took the same form as the garbage collection questions.

Threads is more theoretical.

Which is true about Threads:
A. If suspended, cannot be restarted.
B. Stop running, if another Thread with higher priority is getting runnable.
C. Stop running, if the Thread starts another Thread.
D. If dead, cannot be restarted.
E. If interrupted, stop running.
F. .. I cannot remember. :(

I choose B,D,E. (a classic question, but I had 2-3 question about threads in this style)

Is it true or false, i would appreciate the answer?

A) Java Interpreter exits normally after the non-daemon threads have stopped. (True?)

B) Current thread suspends, when a file is opened for reading. (True?)

a) A thread can stop execution, if it was performing an I/O task with a remote file. (True?)

b) It is possible to suspend a thread indefinitely. (?)

c) Only way to make a thread is to extend the Thread class. (False)

d) After the thread exit main(), it can still run. (related to garbage collection) (?)

When, exactly, does a Java application/applet stop execution?
Does it stop execution when there are no more Daemon threads running?
What is a Daemon thread? Does it stop execution when there are no more User threads?


It keeps running until all user threads have ended. Here is the definition of daemon thread from Bruce Eckels TIJ. A "daemon" thread is one that is supposed to provide a general service in the background as long as the program is running, but is not part of the essence of the program. Thus, when all of the non-daemon threads complete the program is terminated.

What's daemon or non-daemon threads?

Daemon threads are utility threads to service regular non-daemon threads. In Java, their only reason of being is "service to others". If ONLY daemon threads are left in a JVM, the program exits. I guess an implication would be that if you create some daemon threads in your program, you don't have to worry about killing them since they will die when the 'real' threads are through executing.... Any good book and/or chapter and/or on-line tutorial on Java threads should cover this.

(3) When to use "synchronize" keyword

What modifier to use, if a method needs to protect the lock of its object.

A. public
B. protected
C. private
D. final
E. synchronized

Threads, there were couple of questions on synchronized.

Synchronization was asked.

Which modifier can be used together with 'synchronized'?

(4) Implement Runnable and start a thread

Post from Maha Anna:

A thread stops permanently becoz of
1. finishes it 's run method --YES
2. interrupt is invoked --- NO
3. stop --is invoked but since it is –YES deprecated it is no longer in use. should we use if given in exam
Thread stops executing for a while becoz of
1. sleep -YES
2. I/O Operations YES
3. wait --YES
4. yield --YES
5. suspend --deprecated??? should we use if given in exam --YES
6. higher priority thread enters --YES
7. if a thread creates a new thread. --NO
When an Intertrupt is invoked, the waiting, blocked or sleeping threads moves to "ready" state and then throws interrupted exception
I think for both 6 and 7 the answer is maybe. Anytime other threads are present, this may cause the current thread to stop executing temporarily, but there are no guarantees. If another thread is higher priority than the current thread, it's more likely that the current thread will pause, but still no guarantees.
For the options
6. higher priority thread enters --YES
7. if a thread creates a new thread. --NO
I also thought like you. But from the Exam point of view (only yes or no, if at all they word the answers like this ) what shoud we do? We shd think of the closest YES/NO .So a Higher priority thread enters (I assume the Ready state) means it most likely going to enter into Running state than NOT. So I thought the answer is YES. If a thread creates a new thread means the new thread is going to have the SAME PRIORITY as the creating thread, in which case it has less chance to enter into a Running state ,unless the creater yield() than as in option 6. So I inclained towards NO.
That makes sense, and I agree. I just didn't want people to think those answers were absolute. Yeah, if you get an ambiguous question like that on the actual test (which I don't think is nearly as common as ambiguous sample questions are) then you must simply make your best guess.

The isAlive Method
 The isAlive method returns true if the thread has been started and not stopped.
 If the isAlive method returns false, you know that the thread either is a New Thread or is Dead.
 If the isAlive method returns true, you know that the thread is either Runnable or Not Runnable.
 Runnable State includes Ready and Running States.
 You cannot differentiate between a New Thread or a Dead thread. Nor can you differentiate between a Runnable thread and a Not Runnable thread.
Understanding Thread Priority
 When a Java thread is created, it inherits its priority from the thread that created it.
 You can also modify a thread's priority at any time after its creation using the setPriority method.
 Thread priorities are integers ranging between MIN_PRIORITY and MAX_PRIORITY (constants defined in the Thread class).
 The higher the integer, the higher the priority.
 At any given time, when multiple threads are ready to be executed, the runtime system chooses the runnable thread with the highest priority for execution.
 Only when that thread stops, yields, or becomes not runnable for some reason will a lower priority thread start executing.
 If two threads of the same priority are waiting for the CPU, the scheduler chooses one of them to run in a round-robin fashion. The chosen thread will run until one of the following conditions is true:
• A higher priority thread becomes runnable.
• It yields, or its run method exits.
• On systems that support time-slicing, its time allotment has expired.
Then the second thread is given a chance to run, and so on, until the interpreter exits.
 The Java runtime system's thread scheduling algorithm is also preemptive. If at any time a thread with a higher priority than all other runnable threads becomes runnable, the runtime system chooses the new higher priority thread for execution. The new higher priority thread is said to preempt the other threads.
 Rule of thumb: At any given time, the highest priority thread is running. However, this is not guaranteed. The thread scheduler may choose to run a lower priority thread to avoid starvation. For this reason, use priority only to affect scheduling policy for efficiency purposes. Do not rely on thread priority for algorithm correctness
Grouping Threads
 Every Java thread is a member of a thread group.
 Thread groups provide a mechanism for collecting multiple threads into a single object and manipulating those threads all at once, rather than individually.
 For example, you can start or suspend all the threads within a group with a single method call.
 Java thread groups are implemented by the ThreadGroup class in the java.lang package.
 The runtime system puts a thread into a thread group during thread construction.
 When you create a thread, you can either allow the runtime system to put the new thread in some reasonable default group or you can explicitly set the new thread's group.
 The thread is a permanent member of whatever thread group it joins upon its creation--you cannot move a thread to a new group after the thread has been created.

The Default Thread Group
 If you create a new Thread without specifying its group in the constructor, the runtime system automatically places the new thread in the same group as the thread that created it (known as the current thread group and the current thread, respectively).
 When a Java application first starts up, the Java runtime system creates a ThreadGroup named main. Unless specified otherwise, all new threads that you create become members of the main thread group. :
 If you create a thread within an applet, the new thread's group may be something other than main, depending on the browser or viewer that the applet is running in

Methods that Operate on All Threads within a Group
 The ThreadGroup class has three methods that allow you to modify the current state of all the threads within that group:
• resume
• stop
• suspend
 These methods apply the appropriate state change to every thread in the thread group and its subgroups.

Making a Thread Not Runnable
A thread becomes Not Runnable when one of these events occurs:
• Its sleep method is invoked.
• The thread calls the wait method to wait for a specific condition to be satisifed.
• The thread is blocking on I/O.
One Question:
Most of the test questions were easy, but there were some tough thread questions. For example, I had a question that was almost identical to this:
Thread b holds the lock to object a. Thread c is blocked inside a wait call on object a. What will allow c to continue running?
 Threads do not have parent-child relationships
Q8. Select most appropriate answer for the following code
class MyThread extends Thread
{
public void run()
{
try {
Thread.sleep(300);
}
catch (InterruptedException e)
{
System.err.println(e);
}

System.out.println("I am alive");
}
}
public class MyClass
{
public static void main(String args[])
{
new MyThread().start();

int arr[] = new int[20];

arr[20] = 1237;
}
}

Thread MyThread continues even after runtime exception is thrown in
main() and prints "I am alive"
Thread MyThread dies as soon as runtime exception is thrown in main() without printing "I am alive"
Will print "I am alive" without any runtime error
Will give compilation error
SKIP THE QUESTION
Thread MyThread continues even after runtime exception is thrown inThread MyThread continues even after runtime exception is thrown in main() and prints "I am alive" Correct

SCJP-HASH CODE

Equals and Hash Code
Author: Manish Hatwalne
Introduction
The Java super class java.lang.Object has two very important methods defined in it. They are -
• public boolean equals(Object obj)
• public int hashCode()
public boolean equals(Object obj)
 This method checks if some other object passed to it as an argument is equal to the object on which this method is invoked.
 The default implementation of this method in Object class simply checks if two object references x and y refer to the same object. i.e. It checks if x == y. This particular comparison is also known as "shallow comparison".
 However, the classes providing their own implementations of the equals method are supposed to perform a "deep comparison"; by actually comparing the relevant data members. Since Object class has no data members that define its state, it simply performs shallow comparison.

This is what the JDK 1.4 API documentation says about the equals method of Object class-
 Indicates whether some other object is "equal to" this one.
The equals method implements an equivalence relation:
• It is reflexive: for any reference value x, x.equals(x) should return true.
• It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
• It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
• It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified.
• For any non-null reference value x, x.equals(null) should return false.
 The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).
 Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

The contract of the equals method precisely states what it requires. Once you understand it completely, implementation becomes relatively easy, moreover it would be correct. Let's understand what each of this really means.
1. Reflexive - It simply means that the object must be equal to itself, which it would be at any given instance; unless you intentionally override the equals method to behave otherwise.
2. Symmetric - It means that if object of one class is equal to another class object, the other class object must be equal to this class object. In other words, one object can not unilaterally decide whether it is equal to another object; two objects, and consequently the classes to which they belong, must bilaterally decide if they are equal or not. They BOTH must agree.
Hence, it is improper and incorrect to have your own class with equals method that has comparison with an object of java.lang.String class, or with any other built-in Java class for that matter. It is very important to understand this requirement properly, because it is quite likely that a naive implementation of equals method may violate this requirement which would result in undesired consequences.
3. Transitive - It means that if the first object is equal to the second object and the second object is equal to the third object; then the first object is equal to the third object. In other words, if two objects agree that they are equal, and follow the symmetry principle, one of them can not decide to have a similar contract with another object of different class. All three must agree and follow symmetry principle for various permutations of these three classes.
Consider this example - A, B and C are three classes. A and B both implement the equals method in such a way that it provides comparison for objects of class A and class B. Now, if author of class B decides to modify its equals method such that it would also provide equality comparison with class C; he would be violating the transitivity principle. Because, no proper equals comparison mechanism would exist for class A and class C objects.
4. Consistent - It means that if two objects are equal, they must remain equal as long as they are not modified. Likewise, if they are not equal, they must remain non-equal as long as they are not modified. The modification may take place in any one of them or in both of them.
5. null comparison - It means that any instantiable class object is not equal to null, hence the equals method must return false if a null is passed to it as an argument. You have to ensure that your implementation of the equals method returns false if a null is passed to it as an argument.
6. Equals & Hash Code relationship - The last note from the API documentation is very important, it states the relationship requirement between these two methods. It simply means that if two objects are equal, then they must have the same hash code, however the opposite is NOT true. This is discussed in details later in this article.
The details about these two methods are interrelated and how they should be overridden correctly is discussed later in this article.
public int hashCode()
This method returns the hash code value for the object on which this method is invoked. This method returns the hash code value as an integer and is supported for the benefit of hashing based collection classes such as Hashtable, HashMap, HashSet etc. This method must be overridden in every class that overrides the equals method.

This is what the JDK 1.4 API documentation says about the hashCode method of Object class-
Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.
The general contract of hashCode is:
• Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
• If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
• It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

As compared to the general contract specified by the equals method, the contract specified by the hashCode method is relatively simple and easy to understand. It simply states two important requirements that must be met while implementing the hashCode method. The third point of the contract, in fact is the elaboration of the second point. Let's understand what this contract really means.
1. Consistency during same execution - Firstly, it states that the hash code returned by the hashCode method must be consistently the same for multiple invocations during the same execution of the application as long as the object is not modified to affect the equals method.
2. Hash Code & Equals relationship - The second requirement of the contract is the hashCode counterpart of the requirement specified by the equals method. It simply emphasizes the same relationship - equal objects must produce the same hash code. However, the third point elaborates that unequal objects need not produce distinct hash codes.
After reviewing the general contracts of these two methods, it is clear that the relationship between these two methods can be summed up in the following statement -
Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.

The rest of the requirements specified in the contracts of these two methods are specific to those methods and are not directly related to the relationship between these two methods. Those specific requirements are discussed earlier. This relationship also enforces that whenever you override the equals method, you must override the hashCode method as well. Failing to comply with this requirement usually results in undetermined, undesired behavior of the class when confronted with Java collection classes or any other Java classes.
Correct Implementation Example
The following code exemplifies how all the requirements of equals and hashCode methods should be fulfilled so that the class behaves correctly and consistently with other Java classes. This class implements the equals method in such a way that it only provides equality comparison for the objects of the same class, similar to built-in Java classes like String and other wrapper classes.
1. public class Test
2. {
3. private int num;
4. private String data;
5.
6. public boolean equals(Object obj)
7. {
8. if(this == obj)
9. return true;
10. if((obj == null) || (obj.getClass() != this.getClass()))
11. return false;
12. // object must be Test at this point
13. Test test = (Test)obj;
14. return num == test.num &&
15. (data == test.data || (data != null && data.equals(test.data)));
16. }
17.
18. public int hashCode()
19. {
20. int hash = 7;
21. hash = 31 * hash + num;
22. hash = 31 * hash + (null == data ? 0 : data.hashCode());
23. return hash;
24. }
25.
26. // other methods
27. }

Now, let's examine why this implementation is the correct implementation. The class Test has two member variables - num and data. These two variables define state of the object and they also participate in the equals comparison for the objects of this class. Hence, they should also be involved in calculating the hash codes of this class objects.

Consider the equals method first. We can see that at line 8, the passed object reference is compared with this object itself, this approach usually saves time if both the object references are referring to the same object on the heap and if the equals comparison is expensive.
Next, the if condition at line 10 first checks if the argument is null, if not, then (due to the short-circuit nature of the OR || operator) it checks if the argument is of type Test by comparing the classes of the argument and this object. This is done by invoking the getClass() method on both the references. If either of these conditions fails, then false is returned. This is done by the following code -
if((obj == null) || (obj.getClass() != this.getClass())) return false; // prefer
This conditional check should be preferred instead of the conditional check given by -
if(!(obj instanceof Test)) return false; // avoid
This is because, the first condition (code in blue) ensures that it will return false if the argument is a subclass of the class Test. However, in case of the second condition (code in red) it fails. The instanceof operator condition fails to return false if the argument is a subclass of the class Test. Thus, it might violate the symmetry requirement of the contract. The instanceof check is correct only if the class is final, so that no subclass would exist. The first condition will work for both, final and non-final classes. Note that, both these conditions will return false if the argument is null. The instanceof operator returns false if the left hand side (LHS) operand is null, irrespective of the operand on the right hand side (RHS) as specified by JLS 15.20.2. However, the first condition should be preferred for better type checking.

This class implements the equals method in such a way that it provides equals comparison only for the objects of the same class. Note that, this is not mandatory. But, if a class decides to provide equals comparison for other class objects, then the other class (or classes) must also agree to provide the same for this class so as to fulfill the symmetry and reflexivity requirements of the contract. This particular equals method implementation does not violate both these requirements. The lines 14 and 15 actually perform the equality comparison for the data members, and return true if they are equal. Line 15 also ensures that invoking the equals method on String variable data will not result in a NullPointerException.
While implementing the equals method, primitives can be compared directly with an equality operator (==) after performing any necessary conversions (Such as float to Float.floatToIntBits or double to Double.doubleToLongBits). Whereas, object references can be compared by invoking their equals method recursively. You also need to ensure that invoking the equals method on these object references does not result in a NullPointerException.

Here are some useful guidelines for implementing the equals method correctly.
1. Use the equality == operator to check if the argument is the reference to this object, if yes. return true. This saves time when actual comparison is costly.
2. Use the following condition to check that the argument is not null and it is of the correct type, if not then return false.
if((obj == null) || (obj.getClass() != this.getClass())) return false;
Note that, correct type does not mean the same type or class as shown in the example above. It could be any class or interface that one or more classes agree to implement for providing the comparison.
3. Cast the method argument to the correct type. Again, the correct type may not be the same class. Also, since this step is done after the above type-check condition, it will not result in a ClassCastException.
4. Compare significant variables of both, the argument object and this object and check if they are equal. If *all* of them are equal then return true, otherwise return false. Again, as mentioned earlier, while comparing these class members/variables; primitive variables can be compared directly with an equality operator (==) after performing any necessary conversions (Such as float to Float.floatToIntBits or double to Double.doubleToLongBits). Whereas, object references can be compared by invoking their equals method recursively. You also need to ensure that invoking equals method on these object references does not result in a NullPointerException, as shown in the example above (Line 15).
It is neither necessary, nor advisable to include those class members in this comparison which can be calculated from other variables, hence the word "significant variables". This certainly improves the performance of the equals method. Only you can decide which class members are significant and which are not.
5. Do not change the type of the argument of the equals method. It takes a java.lang.Object as an argument, do not use your own class instead. If you do that, you will not be overriding the equals method, but you will be overloading it instead; which would cause problems. It is a very common mistake, and since it does not result in a compile time error, it becomes quite difficult to figure out why the code is not working properly.
6. Review your equals method to verify that it fulfills all the requirements stated by the general contract of the equals method.
7. Lastly, do not forget to override the hashCode method whenever you override the equals method, that's unpardonable. ;)
Now, let's examine the hashCode method of this example. At line 20, a non-zero constant value 7 (arbitrary) is assigned to an int variable hash. Since the class members/variables num and data do participate in the equals method comparison, they should also be involved in the calculation of the hash code. Though, this is not mandatory. You can use subset of the variables that participate in the equals method comparison to improve performance of the hashCode method. Performance of the hashCode method indeed is very important. But, you have to be very careful while selecting the subset. The subset should include those variables which are most likely to have the greatest diversity of the values. Sometimes, using all the variables that participate in the equals method comparison for calculating the hash code makes more sense.
This class uses both the variables for computing the hash code. Lines 21 and 22 calculate the hash code values based on these two variables. Line 22 also ensures that invoking hashCode method on the variable data does not result in a NullPointerException if data is null. This implementation ensures that the general contract of the hashCode method is not violated. This implementation will return consistent hash code values for different invocations and will also ensure that equal objects will have equal hash codes.
While implementing the hashCode method, primitives can be used directly in the calculation of the hash code value after performing any necessary conversions, such as float to Float.floatToIntBits or double to Double.doubleToLongBits. Since return type of the hashCode method is int, long values must to be converted to the integer values. As for hash codes of the object references, they should be calculated by invoking their hashCode method recursively. You also need to ensure that invoking the hashCode method on these object references does not result in a NullPointerException.

Writing a very good implementation of the hashCode method which calculates hash code values such that the distribution is uniform is not a trivial task and may require inputs from mathematicians and theoretical computer scientist. Nevertheless, it is possible to write a decent and correct implementation by following few simple rules.

Here are some useful guidelines for implementing the hashCode method correctly.
1. Store an arbitrary non-zero constant integer value (say 7) in an int variable, called hash.
2. Involve significant variables of your object in the calculation of the hash code, all the variables that are part of equals comparison should be considered for this. Compute an individual hash code int var_code for each variable var as follows -
a. If the variable(var) is byte, char, short or int, then var_code = (int)var;
b. If the variable(var) is long, then var_code = (int)(var ^ (var >>> 32));
c. If the variable(var) is float, then var_code = Float.floatToIntBits(var);
d. If the variable(var) is double, then -
long bits = Double.doubleToLongBits(var);
var_code = (int)(bits ^ (bits >>> 32));
e. If the variable(var) is boolean, then var_code = var ? 1 : 0;
f. If the variable(var) is an object reference, then check if it is null, if yes then var_code = 0; otherwise invoke the hashCode method recursively on this object reference to get the hash code. This can be simplified and given as -
var_code = (null == var ? 0 : var.hashCode());
3. Combine this individual variable hash code var_code in the original hash code hash as follows -
hash = 31 * hash + var_code;
4. Follow these steps for all the significant variables and in the end return the resulting integer hash.
5. Lastly, review your hashCode method and check if it is returning equal hash codes for equal objects. Also, verify that the hash codes returned for the object are consistently the same for multiple invocations during the same execution.
The guidelines provided here for implementing equals and hashCode methods are merely useful as guidelines, these are not absolute laws or rules. Nevertheless, following them while implementing these two methods will certainly give you correct and consistent results.
Summary & Miscellaneous Tips
• Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.
• The equals method provides "deep comparison" by checking if two objects are logically equal as opposed to the "shallow comparison" provided by the equality operator ==.
• However, the equals method in java.lang.Object class only provides "shallow comparison", same as provided by the equality operator ==.
• The equals method only takes Java objects as an argument, and not primitives; passing primitives will result in a compile time error.
• Passing objects of different types to the equals method will never result in a compile time error or runtime error.
• For standard Java wrapper classes and for java.lang.String, if the equals argument type (class) is different from the type of the object on which the equals method is invoked, it will return false.
• The class java.lang.StringBuffer does not override the equals method, and hence it inherits the implementation from java.lang.Object class.
• The equals method must not provide equality comparison with any built in Java class, as it would result in the violation of the symmetry requirement stated in the general contract of the equals method.
• If null is passed as an argument to the equals method, it will return false.
• Equal hash codes do not imply that the objects are equal.
• return 1; is a legal implementation of the hashCode method, however it is a very bad implementation. It is legal because it ensures that equal objects will have equal hash codes, it also ensures that the hash code returned will be consistent for multiple invocations during the same execution. Thus, it does not violate the general contract of the hashCode method. It is a bad implementation because it returns same hash code for all the objects. This explanation applies to all implementations of the hashCode method which return same constant integer value for all the objects.
• In standard JDK 1.4, the wrapper classes java.lang.Short, java.lang.Byte, java.lang.Character and java.lang.Integer simply return the value they represent as the hash code by typecasting it to an int.
• Since JDK version 1.3, the class java.lang.String caches its hash code, i.e. it calculates the hash code only once and stores it in an instance variable and returns this value whenever the hashCode method is called. It is legal because java.lang.String represents an immutable string.
• It is incorrect to involve a random number directly while computing the hash code of the class object, as it would not consistently return the same hash code for multiple invocations during the same execution.
Resources
Here is a list of few more resources that might be useful if you are interested in knowing more about these two methods, their implementation and significance.
• Object class - API documentation for the java.lang.Object class. The general contract of these two methods is available here.
• Effective Java - Nice book by Joshua Bloch. Chapter 3 of this book is available online in a pdf format. This chapter deals with all the methods of java.lang.Object class. It also discusses in details the implementation of equals and hashCode methods, correct and incorrect way of overriding them etc. This article is partially based on the information given in this book.
However, this article is an attempt to explain the mechanism and implementation details of these two methods in a simple and compact presentation. It also adds tips and review questions for better understanding.
• JavaWorld Article - This article discusses the methods of java.lang.Object, also explains shortcomings of using the instanceof condition in the equals method.
• Importance of equals and hashCode - This FAQ question discusses the importance of overriding equals and hashCode methods correctly. It also discusses important issues regarding these two methods with respect to Java collection framework.
• Equals & Hash Code Mock Test - If you are interested in taking the mock test featured here under review questions separately.

This article has been reviewed and revised repeatedly so as to make it as correct as possible. Thanks a lot to Valentin Crettaz and friends at JavaRanch for suggesting many changes. Especially thanks to Valentin for pointing out the violation of the symmetry requirement by using the instanceof condition in the equals method. If you notice any ambiguity, error in the article and/or the mock test, please do let me know. Your feedback is very important in making this article and test more useful.

SCJP-GARBAGE COLLECTION

Chapter 3: Garbage Collection-
Philip Heller Notes
Overview
You should be conversant with the mechanisms of the garbage collection system and with the ways your programming interacts with it.
Garbage collection simplifies the programmer’s job enormously. Memory management is susceptible to two types of error—memory can be used simultaneously for two purposes, or it can remain unavailable for reuse after it is no longer needed. Both of these errors can cause major problems for any program. An automatic garbage collection system such as Java provides prevents the first of these problems and reduces but does not eliminate the second.
State the behavior that is guaranteed by the garbage collection system and write code that explicitly makes objects eligible for collection.
This objective is intended to ensure you have a clear grasp of the responsibilities that rest with you as the programmer. It also ensures you understand the control—and lack of control—you have over the allocation and deallocation of memory. Proper handing of available memory is a crucial concern for anyone writing commercial grade applications, because memory is a finite resource in any computer system and forcing a program to resort to virtual memory will slow it down dramatically.
Critical Information
Two types of errors can occur in memory management in general programming: Memory can be made available for reuse while it is actually still in use, and memory that is no longer in use can remain allocated and unavailable for reuse.
Java’s garbage collection system entirely prevents accidental releasing of memory: As long as an object is accessible from any live thread, the object will remain valid, and the memory associated with it will not be reused. The garbage collector guarantees that it will not reclaim memory that is still in use or is potentially still usable.
There are two types of memory leak, which we shall call hard leaks and soft leaks. They are similar, but Java’s memory management system only helps with the hard leak. A hard leak occurs in languages without a garbage collection system, when there are no references to an area of memory, but that area of memory has not been released. The area of memory is then permanently lost from the program. This type of leak cannot occur with Java, since the scenario described, having zero references to an area of memory, is the definition of how the garbage collector decides the area is eligible for collection.
The second type of leak, a soft leak, occurs when a program has areas of memory that the program will never again use but that have not been, and will not be, released. Java’s garbage collection cannot protect against soft leaks because to do so would require semantic understanding of the meaning and operation of the algorithms that are being coded, and that represents artificial intelligence at a level beyond the skills of modern programming.
To avoid soft memory leaks with Java, simply write null into any reference that will not be used again. The object will become eligible for garbage collection as soon as all references to it are either set to null or become inaccessible.
When a local variable goes out of scope, it becomes inaccessible and therefore is no longer a valid reference to an object. Thus, it doesn’t explicitly require setting to null.
Limitations of the Garbage Collector
When the garbage collector runs, it consumes a certain amount of CPU time. Depending upon the particular garbage collection algorithm used in any given JVM, the rest of the JVM might be frozen while the collection proceeds.
The garbage collection system runs in a thread of its own. Since the thread scheduling algorithm is not specified by Java, you cannot know when, or if, the thread will run. Generally, of course, in the absence of high priority runnable threads, the garbage collector will get its turn. However, the uncertainty surrounding thread scheduling is one of the main reasons there are no guarantees about when, or even if, the garbage collector will reclaim memory. Even calling System.gc() or Runtime.gc() does not force the garbage collector to run.
If the JVM starts to run short of memory, the garbage collector will be set running before an out-of-memory error occurs. This does not happen if the system is running short of system resources, such as file handles, network sockets, or windows. This is the purpose of the dispose() method of the Window class and the close() method of the stream classes.
In general, the limitations of the garbage collector can be summed up as follows: No promises are made regarding when, how fast, or even if the garbage collector will recover a given unreferenced object from memory.
Exam Essentials
Understand memory reclamation and the circumstances under which memory will be reclaimed. If an object is still accessible to any live thread, that object will certainly not be collected. This is true even if the program will never access the object again—the logic is simple and cannot make inferences about the semantics of the code. No guarantees are made about reclaiming available memory or the timing of reclamation if it does occur. In a standard JVM, there is no entirely reliable, platform- independent way to force garbage collection.
Understand System.gc() and Runtime.gc() and their effects on garbage collection. The gc() methods in the System and Runtime classes make it more likely that garbage collection will run but do not guarantee it; for example, other threads might retain the CPU.
Recognize the significance of writing null into a variable. Simply abandoning a variable and allowing it to retain its reference value is likely to cause wasted memory, since any valid reference prevents an object from being garbage collected. To indicate to the runtime system that a reference is no longer in use, thereby making it possible for an unused object to be collected, assign null into a variable to delete the old reference. Of course, writing null does not of itself make the object collectable; that occurs only when no more accessible references exist.
Key Terms and Concepts
Live reference A reference that is accessible to a live thread.
Live thread A thread that has been started but has not yet died.
Memory leak An area of memory that will not be used by the program but that will not be reclaimed for reuse. Java only partially protects against this problem. Write null into references you have finished with to help yourself.
Referenced memory Memory that is being used for storage of an object that is accessible by a live reference.
Runtime.gc() gc() is a static method in the java.lang.Runtime class. By calling the method, you request that the garbage collector run. However, calling the method does not guarantee that the garbage collector will run, nor does it guarantee any limiting timescale in which the garbage collector might run.
System.gc() Another way to request garbage collection, with the same limitations as Runtime.gc().
Unreferenced memory Memory that is not being used for storage of any object accessible by a live reference.

Sample Questions
1. Which memory management problems are addressed by garbage collection?
A. Accidental deallocation of memory that is still in use
B. Failure to reclaim all unneeded memory
C. Failure to reclaim inaccessible memory
D. Insufficient physical memory
E. Insufficient virtual memory

2. Which is true?
A. Calling System.gc() causes garbage collection to occur, but the time for the process to complete is unspecified.
B. Calling Runtime.gc() causes garbage collection to occur, but the time for the process to complete is unspecified.
C. Memory leaks are impossible in Java.
D. Memory is used more efficiently in Java.
E. Memory corruption due to double use of memory is impossible in Java.

3. What is the effect of calling System.gc()?
A. Garbage collection occurs immediately.
B. Garbage collection occurs but not necessarily immediately.
C. Garbage collection might occur soon, if other system behavior permits.

4. In the following program, which of the objects can be released at point X on line 10 (assuming there is further behavior between line 10 and the program’s exit)?
1. public class Test {
2. private Object o = new Object();
3. private static final Object p = new Object();
4.
5. public static void main(String [] args) {
6. Test t = new Test();
7. Test u = new Test();
8. t.o = null;
9. method(u);
10. // point X, other behavior follows
11. }
12.
13. public static void method(Object u) {
14. Object q = new Object();
15. u = null;
16. }
17. }
A. Variable o in Test object t
B. Variable p in the Test class
C. Variable o in Test object u
D. Variable q in the method method()
E. Variable t in the method main()
F. Variable u in the method main()



Answers
1. A, C. Memory cannot be accidentally deallocated; any live reference prevents this. Inaccessible memory is precisely what the garbage collector looks for, so C is true. However, unneeded memory that is still accessible by a live reference will not be collected and will waste space, so B is false. Similarly, if there is insufficient memory, either physical or virtual, the garbage collector cannot help. Either the program will fail due to insufficient virtual memory, or the virtual memory system will thrash if there is insufficient physical memory.
2. E. Calling gc() in either of its guises does not guarantee that the garbage collector will run, so A and B are false. Memory leaks can happen if you fail to null out accessible references to unneeded memory. Memory is not used any more efficiently, so D is false. However, double use of memory is impossible, since accessible memory is never returned to the heap for reuse, so it cannot be accidentally reallocated.
3. C. As the documentation notes, calling the gc() method "suggests" that the system expend effort to run the garbage collection system. So, only C is true.
4. A, D. Because line 8 writes null into the member variable t.o, and t.o was the only reference to that object, it becomes collectible immediately after line 8, making A true. Variable p is static and final, so as long as the class is loaded, the target of the reference cannot be collected. In the code, variable u at line 7 is left unchanged, as is member o. Therefore, C is false since the object remains accessible at least until line 10. At line 16, when the method method() returns, the local variable q goes out of scope, and the object it refers to becomes unreferenced. Therefore, D is true. Although member t.o is set to null at line 8, the variable t is not nulled out; therefore the object it refers to cannot be collected, and E is false. In lines 13 and 15, a local variable called u is declared and nulled out; however, this is a second reference to the object that variable u declared at line 7. Therefore, even though it is set to null at line 15, a live accessible reference remains at line 10, making F false.

SCJP-EXCEPTIONS

Exceptions in Java
The full story of exceptions in the Java language and virtual machine
Summary
For those of you who need a refresher on exceptions, this cover story companion piece is a valuable tutorial on the nuts and bolts of what exceptions are and how they work in the Java language and virtual machine. Bill Venners describes in detail exception mechanisms built into the Java programming language. He also discusses exception classes and objects, throwing and catching exceptions, the method invocation stack, the throws clause, checked vs. unchecked exceptions, and finally clauses. (6,000 words)
By Bill Venners


Exceptions are the customary way in Java to indicate to a calling method that an abnormal condition has occurred. This article is a companion piece to this month's Design Techniques installment, which discusses how to use exceptions appropriately in your programs and designs. Look to this companion article for a tutorial on the nuts and bolts of what exceptions are and how they work in the Java language and virtual machine.
When a method encounters an abnormal condition (an exception condition) that it can't handle itself, it may throw an exception. Throwing an exception is like throwing a beeping, flashing red ball to indicate there is a problem that can't be handled where it occurred. Somewhere, you hope, this ball will be caught and the problem will be dealt with. Exceptions are caught by handlers positioned along the thread's method invocation stack. If the calling method isn't prepared to catch the exception, it throws the exception up to its calling method, and so on. If one of the threads of your program throws an exception that isn't caught by any method along the method invocation stack, that thread will expire. When you program in Java, you must position catchers (the exception handlers) strategically, so your program will catch and handle all exceptions from which you want your program to recover.
Exception classes
In Java, exceptions are objects. When you throw an exception, you throw an object. You can't throw just any object as an exception, however -- only those objects whose classes descend from Throwable. Throwable serves as the base class for an entire family of classes, declared in java.lang, that your program can instantiate and throw. A small part of this family is shown in Figure 1.
As you can see in Figure 1, Throwable has two direct subclasses, Exception and Error. Exceptions (members of the Exception family) are thrown to signal abnormal conditions that can often be handled by some catcher, though it's possible they may not be caught and therefore could result in a dead thread. Errors (members of the Error family) are usually thrown for more serious problems, such as OutOfMemoryError, that may not be so easy to handle. In general, code you write should throw only exceptions, not errors. Errors are usually thrown by the methods of the Java API, or by the Java virtual machine itself.


Figure 1. A partial view of the Throwable family
In addition to throwing objects whose classes are declared in java.lang, you can throw objects of your own design. To create your own class of throwable objects, you need only declare it as a subclass of some member of the Throwable family. In general, however, the throwable classes you define should extend class Exception. They should be "exceptions." The reasoning behind this rule will be explained later in this article.
Whether you use an existing exception class from java.lang or create one of your own depends upon the situation. In some cases, a class from java.lang will do just fine. For example, if one of your methods is invoked with an invalid argument, you could throw IllegalArgumentException, a subclass of RuntimeException in java.lang.
Other times, however, you will want to convey more information about the abnormal condition than a class from java.lang will allow. Usually, the class of the exception object itself indicates the type of abnormal condition that was encountered. For example, if a thrown exception object has class IllegalArgumentException, that indicates someone passed an illegal argument to a method. Sometimes you will want to indicate that a method encountered an abnormal condition that isn't represented by a class in the Throwable family of java.lang.
As an example, imagine you are writing a Java program that simulates a customer of a virtual café drinking a cup of coffee. Consider the exceptional conditions that might occur while the customer sips. The class hierarchy of exceptions shown in Figure 2 represents a few possibilities.


Figure 2. Exception hierarchy for coffee sipping
If the customer discovers, with dismay, that the coffee is cold, your program could throw a TooColdException. On the other hand, if the customer discovers that the coffee is overly hot, your program could throw a TooHotException. These conditions could be exceptions because they are (hopefully) not the normal situation in your café. (Exceptional conditions are not necessarily rare, just outside the normal flow of events.) The code for your new exception classes might look like this:

// In Source Packet in file except/ex1/TemperatureException.java
class TemperatureException extends Exception {
}

// In Source Packet in file except/ex1/TooColdException.java
class TooColdException extends TemperatureException {
}

// In Source Packet in file except/ex1/TooHotException.java
class TooHotException extends TemperatureException {
}
This family of classes, the TemperatureException family, declares three new types of exceptions for your program to throw. Note that each exception indicates by its class the kind of abnormal condition that would cause it to be thrown: TemperatureException indicates some kind of problem with temperature; TooColdException indicates something was too cold; and TooHotException indicates something was too hot. Note also that TemperatureException extends Exception -- not Throwable, Error, or any other class declared in java.lang.
Throwing exceptions
To throw an exception, you simply use the throw keyword with an object reference, as in:

throw new TooColdException();
The type of the reference must be Throwable or one of its subclasses.
The following code shows how a class that represents the customer, class VirtualPerson, might throw exceptions if the coffee didn't meet the customer's temperature preferences. Note that Java also has a throws keyword in addition to the throw keyword. Only throw can be used to throw an exception. The meaning of throws will be explained later in this article.

// In Source Packet in file except/ex1/VirtualPerson.java
class VirtualPerson {

private static final int tooCold = 65;
private static final int tooHot = 85;

public void drinkCoffee(CoffeeCup cup) throws
TooColdException, TooHotException {

int temperature = cup.getTemperature();
if (temperature <= tooCold) {
throw new TooColdException();
}
else if (temperature >= tooHot) {
throw new TooHotException();
}
//...
}
//...
}

// In Source Packet in file except/ex1/CoffeeCup.java
class CoffeeCup {
// 75 degrees Celsius: the best temperature for coffee
private int temperature = 75;
public void setTemperature(int val) {
temperature = val;
}
public int getTemperature() {
return temperature;
}
//...
}
Catching exceptions
To catch an exception in Java, you write a try block with one or more catch clauses. Each catch clause specifies one exception type that it is prepared to handle. The try block places a fence around a bit of code that is under the watchful eye of the associated catchers. If the bit of code delimited by the try block throws an exception, the associated catch clauses will be examined by the Java virtual machine. If the virtual machine finds a catch clause that is prepared to handle the thrown exception, the program continues execution starting with the first statement of that catch clause.
As an example, consider a program that requires one argument on the command line, a string that can be parsed into an integer. When you have a String and want an int, you can invoke the parseInt() method of the Integer class. If the string you pass represents an integer, parseInt() will return the value. If the string doesn't represent an integer, parseInt() throws NumberFormatException. Here is how you might parse an int from a command-line argument:

// In Source Packet in file except/ex1/Example1.java
class Example1 {
public static void main(String[] args) {

int temperature = 0;
if (args.length > 0) {
try {
temperature = Integer.parseInt(args[0]);
}
catch(NumberFormatException e) {
System.out.println(
"Must enter integer as first argument.");
return;
}
}
else {
System.out.println(
"Must enter temperature as first argument.");
return;
}

// Create a new coffee cup and set the temperature of
// its coffee.
CoffeeCup cup = new CoffeeCup();
cup.setTemperature(temperature);

// Create and serve a virtual customer.
VirtualPerson cust = new VirtualPerson();
VirtualCafe.serveCustomer(cust, cup);
}
}
Here, the invocation of parseInt() sits inside a try block. Attached to the try block is a catch clause that catches NumberFormatException:

catch(NumberFormatException e) {
System.out.println(
"Must enter integer as first argument.");
return;
}
The lowercase character e is a reference to the thrown (and caught) NumberFormatException object. This reference could have been used inside the catch clause, although in this case it isn't. (Examples of catch clauses that use the reference are shown later in this article.)
If the user types Harumph as the first argument to the Example1 program, parseInt() will throw a NumberFormatException exception and the catch clause will catch it. The program will print:

Must enter integer as first argument.
Although the above example had only one catch clause, you can have many catch clauses associated with a single try block. Here's an example:

// In Source Packet in file except/ex1/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee is just right.");
}
catch (TooColdException e) {
System.out.println("Coffee is too cold.");
// Deal with an irate customer...
}
catch (TooHotException e) {
System.out.println("Coffee is too hot.");
// Deal with an irate customer...
}
}
}
If any code inside a try block throws an exception, its catch clauses are examined in their order of appearance in the source file. For example, if the try block in the above example throws an exception, the catch clause for TooColdException will be examined first, then the catch clause for TooHotException. During this examination process, the first catch clause encountered that handles the thrown object's class gets to "catch" the exception. The ordering of catch-clause examination matters because it is possible that multiple catch clauses of a try block could handle the same exception.
catch clauses indicate the type of abnormal condition they handle by the type of exception reference they declare. In the example above, the catch clauses declare exception type TooColdException and TooHotException. Had a single catch clause declared a TemperatureException, a thrown TooColdException or TooHotException still would have been caught, because TemperatureException is the superclass of both these classes. In the object-oriented way of thinking, a TooColdException is a TemperatureException, therefore, a catch clause for TemperatureException also will catch a thrown TooColdException. An example of this is shown below:

// In Source Packet in file except/ex2/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee is just right.");
}
catch (TemperatureException e) {
// This catches TooColdException, TooHotException,
// as well as TemperatureException.
System.out.println("Coffee is too cold or too hot.");
// Deal with an irate customer...
}
}
}
Multiple catch clauses could handle the same exception because you may, for example, declare two catch clauses, one for TooColdException and another for TemperatureException. In this case, however, you must place the catch clause for TooColdException above the one for TemperatureException, or the source file won't compile. If a catch clause for TemperatureException could be declared before a catch clause for TooColdException, the first catch clause would catch all TooColdExceptions, leaving nothing for the second catch clause to do. The second catch clause would never be reached. The general rule is: subclass catch clauses must precede superclass catch clauses. Here's an example of both orders, only one of which compiles:

// In Source Packet in file except/ex3/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee is just right.");
}
catch (TemperatureException e) {
// This catches TooColdException, TooHotException,
// as well as TemperatureException.
System.out.println("Coffee is too cold or too hot.");
// Deal with an irate customer...
}
// THIS WON'T COMPILE, BECAUSE THIS catch clause
// WILL NEVER BE REACHED.
catch (TooColdException e) {
System.out.println("Coffee is too cold.");
}
}
}

// In Source Packet in file except/ex4/VirtualCafe.java
// This class compiles fine.
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee is just right.");
}
catch (TooColdException e) {
System.out.println("Coffee is too cold.");
// Deal with an irate customer...
}
catch (TemperatureException e) {
// This catches TooHotException as well
// as TemperatureException.
System.out.println(
"There's temperature trouble in this coffee.");
// Deal with an irate customer...
}
}
}
Embedding information in an exception object
When you throw an exception, you are performing a kind of structured go-to from the place in your program where an abnormal condition was detected to a place where it can be handled. The Java virtual machine uses the class of the exception object you throw to decide which catch clause, if any, should be allowed to handle the exception. But an exception doesn't just transfer control from one part of your program to another, it also transmits information. Because the exception is a full-fledged object that you can define yourself, you can embed information about the abnormal condition in the object before you throw it. The catch clause can then get the information by querying the exception object directly.
The Exception class allows you to specify a String detail message that can be retrieved by invoking getMessage() on the exception object. When you define an exception class of your own, you can give client programmers the option of specifying a detail message like this:

// In Source Packet in file except/ex5/UnusualTasteException.java
class UnusualTasteException extends Exception {
UnusualTasteException() {
}
UnusualTasteException(String msg) {
super(msg);
}
}
Given the above declaration of UnusualTasteException, client programmers could create an instance in one of two ways:
1. new UnusualTasteException()
2. new UnusualTasteException("This coffee tastes like tea.")
A catch clause can then query the object for a detail string, like this:

// In Source Packet in file except/ex5/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee tastes just right.");
}
catch (UnusualTasteException e) {
System.out.println(
"Customer is complaining of an unusual taste.");
String s = e.getMessage();
if (s != null) {
System.out.println(s);
}
// Deal with an unhappy customer...
}
}
}
When you need to embed more information into an exception object than you can represent with a String, you can add data and access methods to your exception class. For example, you could define the temperature exception classes like this:

// In Source Packet in file except/ex6/TemperatureException.java
abstract class TemperatureException extends Exception {
private int temperature; // in Celsius
public TemperatureException(int temperature) {
this.temperature = temperature;
}
public int getTemperature() {
return temperature;
}
}

// In Source Packet in file except/ex6/TooColdException.java
class TooColdException extends TemperatureException {
public TooColdException(int temperature) {
super(temperature);
}
}

// In Source Packet in file except/ex6/TooHotException.java
class TooHotException extends TemperatureException {
public TooHotException(int temperature) {
super(temperature);
}
}
Given a TemperatureException family as defined above, catch clauses can query the exception object to find out the precise temperature that caused the problem. The temperature field of the exception object must be set when the object is created, as in:

// In Source Packet in file except/ex6/VirtualPerson.java
class VirtualPerson {

private static final int tooCold = 65;
private static final int tooHot = 85;

public void drinkCoffee(CoffeeCup cup) throws
TooColdException, TooHotException {

int temperature = cup.getTemperature();
if (temperature <= tooCold) {
throw new TooColdException(temperature);
}
else if (temperature >= tooHot) {
throw new TooHotException(temperature);
}
//...
}
//...
}
Wherever the exception is caught, the catch clause can easily determine the actual temperature of the coffee and act accordingly, as in:

// In Source Packet in file except/ex6/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup) {

try {
cust.drinkCoffee(cup);
System.out.println("Coffee is just right.");
}
catch (TooColdException e) {
int temperature = e.getTemperature();
System.out.println("Coffee temperature is "
+ temperature + " degrees Celsius.");
if (temperature > 55 && temperature <= 65) {
System.out.println("Coffee is cooling off.");
// Add more hot coffee...
}
else if (temperature > 0 && temperature <= 55) {
System.out.println("Coffee is too cold.");
// Give customer a new cup of coffee with the
// proper temperature...
}
else if (temperature <= 0) {
System.out.println("Coffee is frozen.");
// Deal with an irate customer...
}
}
catch (TooHotException e) {
int temperature = e.getTemperature();
System.out.println("Coffee temperature is "
+ temperature + " degrees Celsius.");
if (temperature >= 85 && temperature < 100) {
System.out.println("Coffee is too hot.");
// Ask customer to let it cool a few minutes...
}
else if (temperature >= 100 && temperature < 2000) {
System.out.println(
"Both coffee and customer are steamed.");
// Deal with an irate customer...
}
else if (temperature >= 2000) {
System.out.println(
"The coffee is plasma.");
// Deal with a very irate customer...
}
}
}
}
The program could deal with the temperature problem differently depending upon the coffee's actual temperature. If the coffee is just a little cold, the program could add more hot coffee to the cup. If the coffee is so cold that the customer's lips were instantly frozen to the cup, alternative measures could be taken.
Exceptions and the method invocation stack
Code inside a try block is in a sense surrounded by the catch clauses associated with the try block. When an exception is thrown, the surrounding catch clauses are examined in inside-out order. You can nest try blocks inside try blocks, in effect building up more and more layers of catch clauses that surround the code. When a method is invoked from within a try block, the catch clauses associated with that try block surround the code in the invoked method as well. If that method has try blocks and catch clauses, they are added as inner surrounding layers. What this means is that an exception may be thrown far up the method invocation stack before landing in a catch clause that can handle it.
As an example, consider the following exception classes, which are simpler versions of exceptions introduced in examples above:

// In Source Packet in file except/ex7/TemperatureException.java
class TemperatureException extends Exception {
}

// In Source Packet in file except/ex7/TooColdException.java
class TooColdException extends TemperatureException {
}

// In Source Packet in file except/ex7/TooHotException.java
class TooHotException extends TemperatureException {
}

// In Source Packet in file except/ex7/UnusualTasteException.java
class UnusualTasteException extends Exception {
}
When the drinkCoffee() method of class VirtualPerson is invoked, it throws one of these four exceptions, chosen at random:

// In Source Packet in file except/ex7/VirtualPerson.java
class VirtualPerson {

public void drinkCoffee(CoffeeCup cup) throws TooColdException,
TemperatureException, UnusualTasteException {

try {
int i = (int) (Math.random() * 4.0);
switch (i) {
case 0:
throw new TooHotException();

case 1:
throw new TooColdException();

case 2:
throw new UnusualTasteException();

default:
throw new TemperatureException();
}
}
catch (TooHotException e) {
System.out.println("This coffee is too hot.");
// Customer will wait until it cools to an
// acceptable temperature.
}
}
//...
}
If variable i in the drinkCoffee() method above happens to be set to a value of 0 the switch statement will instantiate and throw a TooHotException. Because the switch statement itself is enclosed within a try block that has a catch clause for TooHotException, execution continues at that catch clause. The program prints out:

This coffee is too hot.
If variable i in the drinkCoffee() method above happens to be set to the value of 1, the switch statement will instantiate and throw a TooColdException. When this exception is thrown, the Java virtual machine will first check the catch clauses of the try block that surrounds the switch statement. In this case, however, no catch clause matches the thrown exception.
Because the TooColdException is not caught by the drinkCoffee() method, the Java virtual machine throws the exception up the method invocation stack to the method that invoked drinkCoffee(). As used here, a method invocation stack (or call stack) is a list of the methods that have been invoked by a thread, starting with the first method the thread invoked and ending with the current method. A method invocation stack shows the path of method invocations a thread took to arrive at the current method.
A graphical representation of the method invocation stack for drinkCoffee() is shown in Figure 3. In this figure, the method invocation stack is shown on the right and the corresponding Java stack is shown on the left. The Java stack is where methods keep their state inside the Java virtual machine. Each method gets a stack frame (or frame), which is pushed onto the stack when the method is invoked and popped from the stack when the method completes. The frame is an area in memory that contains the method's local variables, parameters, return value, and other information needed by the Java virtual machine to execute the method. In Figure 3, the stack is shown growing downwards. The top of the stack is at the bottom of the picture.


Figure 3. The method invocation stack for drinkCoffee()
When a method completes by executing a return statement, or by successfully executing the last statement in a method declared as void, it is said to complete normally. The Java virtual machine pops the returning method's stack frame, and continues executing just after the method invocation in the calling method. The calling method becomes the current method and its stack frame becomes the current frame.
When a method throws an exception that it doesn't catch itself, it is said to complete abruptly. Methods do not return a value when they complete abruptly, though they do pass along an exception object.
For example, when the drinkCoffee() method throws a TooColdException, it completes abruptly. Because the exception isn't caught by drinkCoffee(), the Java virtual machine pops drinkCoffee()'s stack frame. It then examines the next method up the invocation stack, in this case the serveCustomer() method of VirtualCafe, to see if it has a catch clause prepared to handle the exception.
Here's the code for VirtualCafe:

// In Source Packet in file except/ex7/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup)throws TemperatureException,
UnusualTasteException {

try {
cust.drinkCoffee(cup);
}
catch (TooColdException e) {
System.out.println("This coffee is too cold.");
// Add more hot coffee...
}
}
}
The serveCustomer() method above does indeed surround its invocation of drinkCoffee() with a try block that has an attached catch clause for TooColdException. So the exception stops here. The Java virtual machine makes the serveCustomer() method's stack frame current and continues execution at the first statement inside the catch clause. The program prints out:

This coffee is too cold.
If variable i in the drinkCoffee() method above happens to be set to the value of 2, the switch statement will instantiate and throw an UnusualTasteException. When this exception is thrown, the Java virtual machine will first check the catch clauses of the try block that surrounds the switch statement. In this case, no catch clause matches the thrown exception. The virtual machine will then pop drinkCoffee()'s stack frame and examine the serveCustomer() method. But in serveCustomer(), no catch clause attached to the try block matches the thrown exception either. The virtual machine will therefore pop serveCustomer()'s stack frame and examine the next method up the invocation stack: the main() method of class Example7.
Here's the code for Example7:

// In Source Packet in file except/ex7/Example7.java
class Example7 {
public static void main(String[] args)
throws TemperatureException {

// Create a new coffee cup.
CoffeeCup cup = new CoffeeCup();

// Create and serve a virtual customer.
try {
VirtualPerson cust = new VirtualPerson();
VirtualCafe.serveCustomer(cust, cup);
}
catch (UnusualTasteException e) {
System.out.println("This coffee has an unusual taste.");
}
}
}
This main() method was farsighted enough to surround its invocation of serveCustomer() with a try block that includes a catch clause for UnusualTasteException. Thus, the Java virtual machine will make the main() method's stack frame current and will continue execution at the first statement in the catch clause. The program will print:

This coffee has an unusual taste.
In the UnusualTasteException case, both drinkCoffee() and serveCoffee() methods completed abruptly. The Java virtual machine popped two frames from the Java stack, stopping its popping only when it reached the main() method.
The last case in this example occurs if the variable i in the drinkCoffee() method gets set to a value greater than 2. In this case, the switch statement will instantiate and throw a TemperatureException. When this exception is thrown, the Java virtual machine will go through its usual procedure of examining methods for catch clauses and popping frames for methods that can't handle the exception. The virtual machine will examine drinkCoffee(), pop its frame, examine serveCustomer(), pop its frame, examine main(), and pop its frame. At this point, however, the virtual machine has run out of frames. It can't go any further up the method invocation stack because main() was the first method invoked by the thread.
Because none of the methods on the invocation stack is prepared to handle the TemperatureException, the exception is "uncaught." It will be handled by a default handler and result in the death of the thread. Because this is the main thread of the Example7 application and the application didn't fire off any other threads that are still running when the main thread dies, the application terminates. (A dead thread doesn't always cause the death of its application, only when a dying thread is the last "non-daemon" thread running inside the application.) In most Java runtime environments, the default handler for an uncaught exception will print out a stack trace when a thread dies. For example, the java program from JDK 1.1.1 prints the following when the main thread of Example7 dies due to an uncaught TemperatureException:

TemperatureException
at VirtualPerson.drinkCoffee(VirtualPerson.java:20)
at VirtualCafe.serveCustomer(VirtualCafe.java:9)
at Example7.main(Example7.java:12)
The throws clause
As you may have guessed from the examples above, the Java language requires that a method declare in a throws clause the exceptions that it may throw. A method's throws clause indicates to client programmers what exceptions they may have to deal with when they invoke the method.
For example, the drinkCoffee() method of class VirtualPerson, shown below, declares three exceptions in its throws clause: TooColdException, TemperatureException, and UnusualTasteException. These are the three exceptions that the method throws but doesn't catch. The method also may throw TooHotException, but this exception doesn't appear in the throws clause because drinkCoffee() catches and handles it internally. Only exceptions that will cause a method to complete abruptly should appear in its throws clause.

// In Source Packet in file except/ex7/VirtualPerson.java
class VirtualPerson {

public void drinkCoffee(CoffeeCup cup) throws TooColdException,
TemperatureException, UnusualTasteException {

try {
int i = (int) (Math.random() * 4.0);
switch (i) {
case 0:
throw new TooHotException();

case 1:
throw new TooColdException();

case 2:
throw new UnusualTasteException();

default:
throw new TemperatureException();
}
}
catch (TooHotException e) {
System.out.println("This coffee is too hot.");
// Customer will wait until it cools to an
// acceptable temperature.
}
}
//...
}
In the drinkCoffee() method above, each exception declared in the throws clause is explicitly thrown by the method via a throw statement. This is one of two ways a method can complete abruptly. The other way is by invoking another method that completes abruptly.
An example of this is VirtualCafe's serveCustomer() method, shown below, that invokes VirtualPerson's drinkCoffee() method. The serveCustomer() method contains no throw statements, but it does declare two exceptions in its throws clause: TemperatureException and UnusualTasteException. These are two of three exceptions that may be thrown by drinkCoffee(), which serveCustomer() invokes. The third exception, TooColdException, doesn't appear in the throws clause because serveCustomer() catches and handles it internally. Only those exceptions that will cause the serveCustomer() method to complete abruptly appear in its throws clause.

// In Source Packet in file except/ex7/VirtualCafe.java
class VirtualCafe {

public static void serveCustomer(VirtualPerson cust,
CoffeeCup cup)throws TemperatureException,
UnusualTasteException {

try {
cust.drinkCoffee(cup);
}
catch (TooColdException e) {
System.out.println("This coffee is too cold.");
// Add more hot coffee...
}
}
}
Although a throws clause lists exceptions that may cause a method to complete abruptly, the list is not necessarily complete. Not everything that can be thrown by a method need be put in a throws clause.
Checked vs. unchecked exceptions
There are two kinds of exceptions in Java, checked and unchecked, and only checked exceptions need appear in throws clauses. The general rule is: Any checked exceptions that may be thrown in a method must either be caught or declared in the method's throws clause. Checked exceptions are so called because both the Java compiler and the Java virtual machine check to make sure this rule is obeyed.
Whether or not an exception is "checked" is determined by its position in the hierarchy of throwable classes. Figure 4 shows that some parts of the Throwable family tree contain checked exceptions while other parts contain unchecked exceptions. To create a new checked exception, you simply extend another checked exception. All throwables that are subclasses of Exception, but not subclasses of RuntimeException are checked exceptions.


Figure 4. Checked and unchecked throwables
The conceptual difference between checked and unchecked exceptions is that checked exceptions signal abnormal conditions that you want client programmers to deal with. For instance, because the drinkCoffee() method allocates memory with the new operator, it could potentially complete abruptly by throwing an OutOfMemoryError. This is not a checked exception, because it's not a subclass of Exception. It's a subclass of Error. Conceptually, OutOfMemoryError isn't a checked exception because you don't want client programmers to have to deal directly with the fact that drinkCoffee() could complete abruptly due to low memory.
When you place an exception in a throws clause, it forces client programmers who invoke your method to deal with the exception, either by catching it or by declaring it in their own throws clause. If they don't deal with the exception in one of these two ways, their classes won't compile. For example, because the drinkCoffee() method declares three exceptions in its throws clause, the serveCustomer() method, which invokes drinkCoffee(), has to deal with those three exceptions. In this case, serveCustomer() catches one exception, TooColdException, but not the other two. If serveCustomer() hadn't declared in its throws clause the other two exceptions, TemperatureException and UnusualTasteException, the VirtualCafe class would not have compiled.
Most unchecked throwables declared in java.lang (subclasses of Error and RuntimeException) are problems that would be detected by the Java virtual machine. Errors usually signal abnormal conditions that you wouldn't want a program to handle. Problems with linking, such as NoClassDefFoundError, or memory, such as StackOverflowError, could happen just about anywhere in a program. In the rare cases in which they happen, it is usually reasonable that the thread terminate.
Although most runtime exceptions (members of the RuntimeException family) also are thrown by the Java virtual machine itself, they usually are more an indication of software bugs. Problems with arrays, such as ArrayIndexOutOfBoundsException, or passed parameters, such as IllegalArgumentException, also could happen just about anywhere in a program. When exceptions like these are thrown, you'll want to fix the bugs that caused them to be thrown. You won't, however, want to force client programmers to wrap every invocation of a method that uses arrays with a catch clause for ArrayIndexOutOfBoundsException.
You can throw and catch unchecked exceptions just like checked exceptions, but the Java Language Specification advises against throwing errors. It is intended that errors be thrown only by the Java runtime. You may, however, reasonably throw runtime exceptions. You can throw a runtime exception declared in java.lang or declare your own subclasses of RuntimeException.
To decide whether to throw a checked exception or an unchecked runtime exception, you must look at the abnormal condition you are signalling. If you are throwing an exception to indicate an improper use of your class, you are signalling a software bug. The class of exception you throw probably should descend from RuntimeException, which will make it unchecked. Otherwise, if you are throwing an exception to indicate not a software bug but an abnormal condition that client programmers should deal with every time they use your method, your exception should be checked.
The finally clause
Once a Java virtual machine has begun to execute a block of code -- the statements between two matching curly braces -- it can exit that block in any of several ways. It could, for example, simply execute past the closing curly brace. It could encounter a break, continue, or return statement that causes it to jump out of the block from somewhere in the middle. Or, if an exception is thrown that isn't caught inside the block, it could exit the block while searching for a catch clause.
Given that a block can be exited in many ways, it is important to be able to ensure that something happens upon exiting a block, no matter how the block is exited. For example, if you open a file in a method, you may want to ensure the file gets closed no matter how the method completes. In Java, you express such a desire with a finally clause.
To use a finally clause, you simply: (1) Enclose the code that has multiple exit points in a try block; and (2) place the code that must be executed when the try block is exited in a finally clause.
Here's an example:

try {
// Block of code with multiple exit points
}
finally {
// Block of code that must always be executed when the try block
// is exited, no matter how the try block is exited
}
At least one clause, either catch or finally, must be associated with each try block. If you have both catch clauses and a finally clause with the same try block, you must put the finally clause after all the catch clauses, as in:

// In Source Packet in file except/ex8/VirtualPerson.java
class VirtualPerson {

public void drinkCoffee(CoffeeCup cup) {

try {
int i = (int) (Math.random() * 4.0);
switch (i) {
case 0:
throw new TooHotException();

case 1:
throw new TooColdException();

case 2:
throw new UnusualTasteException();

default:
System.out.println("This coffee is great!");
}
}
catch (TooHotException e) {
System.out.println("This coffee is too hot.");
}
catch (TooColdException e) {
System.out.println("This coffee is too cold.");
}
catch (UnusualTasteException e) {
System.out.println("This coffee is too strong.");
}
finally {
System.out.println("Can I please have another cup?");
}
}
//...
}
If during execution of the code within a try block, an exception is thrown that is handled by a catch clause associated with the try block, the finally clause will be executed after the catch clause. For example, if a TooColdException exception is thrown during execution of the try block above, the program would print the following:

This coffee is too cold.
Can I please have another cup?
If an exception is thrown that is not handled by a catch clause associated with the try block, the finally clause is still executed. The Java virtual machine will execute the code of the finally clause before it continues searching elsewhere for an appropriate catch clause. There is no way to leave a try block without executing the code of its finally clause.
You can do anything inside a finally clause that you can do elsewhere, including executing break, continue, or return statements, or throwing exceptions. Such actions inside a finally clause, however, can have some surprising effects. For example, consider a finally clause that is entered because of an uncaught exception. If the finally clause executes a return, the method would complete normally via the return, not abruptly by throwing the exception. The exception would have in effect been handled by the finally clause instead of a catch clause.
As another example, consider a finally clause that is entered because a return true; statement was executed inside the try block. If the finally clause executes a return false; statement, the method will return false.
Conclusion
Java goes to great lengths to help you deal with error conditions. Java's exception mechanisms give you a structured way to perform a go-to from the place where an error occurs to the code that knows how to handle the error. These mechanisms also enable you to force client programmers (those who use your code by calling your methods) to deal with the possibility of an error condition encountered by your code. But Java's mechanisms do not force you to design your programs to take advantage of these capabilities. In the end, if you want your programs to handle error conditions in a structured, methodical way, you must use the exception mechanisms correctly.
For advice on how to put the exception mechanisms described in this article to use in your programs and designs, see this month's Design Techniques column, "Designing with exceptions."

About the author
Bill Venners has been writing software professionally for 12 years. Based in Silicon Valley, he provides software consulting and training services under the name Artima Software Company. Over the years he has developed software for the consumer electronics, education, semiconductor, and life insurance industries. He has programmed in many languages on many platforms: assembly language on various microprocessors, C on Unix, C++ on Windows, Java on the Web. He is author of the book: Inside the Java Virtual Machine, published by McGraw-Hill.
Resources
• Source packet that contains the example code used in this article
http://www.artima.com/flexiblejava/code.html
• An applet that demonstrates how exceptions work inside the JVM
http://www.artima.com/insidejvm/applets/PlayBall.html
• An applet that demonstrates how finally clauses work inside the JVM
http://www.artima.com/insidejvm/applets/HopAround.html
• The Exceptions chapter of the Java Language Specification
http://java.sun.com/docs/books/jls/html/11.doc.html
• An explanation of try-catch-finally blocks from the Java Language Specification
http://java.sun.com/docs/books/jls/html/14.doc.html#79311
• Exceptions from the perspective of the JVM
http://java.sun.com/docs/books/vmspec/html/Concepts.doc.html#22727