Brought to you by EarthWeb
ITKnowledge Logo Login Graphic
How smart are you?  Guess the computing class below. ZD University
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


There’s only one new opcode in any of these: athrow. Exception handling is implemented mostly with a series of goto instructions. For example, look at the catchException() method:

     void catchException() {
   0   iconst_5
   1   newarray 10
   3   astore_1
   4   aload_1
   5   iconst_5
   6   bipush 7
   8   iastore
   9   return
   10   astore_2
   11   getstatic 17
   14   aload_2
   15   invokevirtual 20
   18   return

    }

The catch clause is not actually included in the byte code as such. One block of code from instruction 0 through instruction 9 handles the normal form of execution. It’s terminated with the return opcode in instruction 9. Then the catch clause is included in instruction 10 through instruction 15. The ExceptionsTable for a method tells the virtual machine which sets of instructions handle which exceptions.

The throwCheckedException() and throwRuntimeException() methods are very similar and quite simple. In essence, each just creates a new Exception object on the stack using standard constructors. Then, when the exception is on top of the stack, ready to go, the athrow instruction actually throws it. When the program runs, the virtual machine will see this exception and will work its way up the call chain looking for the nearest catch clause that can handle the exception. If it doesn’t find one, it shuts down the thread that threw the exception.

     void finallyTest() {

    0   aload_0
    1   invokevirtual 13
    4   goto 14
    7   astore_3
    8   getstatic 17
    11   aload_3
    12   invokevirtual 20
    15   goto 3
    18   jsr 10
    21   return
    22   astore_1
    23   jsr 5
    26   aload_1
    27   athrow
    28   astore_2
    29   getstatic 18
    32   ldc 2
    34   invokevirtual 19
    37   ret 2

     }

The finallyTest() method demonstrates one more instruction, jsr. The jsr opcode ensures that the code in a finally clause is executed. You should notice that there are two jsr instructions: one in line 18 and one in line 23. The jsr at line 18 jumps 10 places ahead to line 28. The jsr at line 23 jumps five places ahead, also to line 28. They’re both executing the same finally clause, one from inside the main body of the code and one from inside the catch clause. The ret instruction in line 37 causes control to return to the point in the method where it started. It is not the same as the return instruction that exits the method.

Type checking

Two opcodes check the types of values operated on. The opcode instanceof implements the instanceof operator and compares the types of two references on the stack, whereas checkcast checks to see whether a cast between two types is permitted.

instanceof

The instanceof instruction is used to compile the instanceof operator. It determines whether a particular object is an instance of a specified class. A reference to the object is popped from the stack. The two bytes after the instanceof instruction in the code array are an index into the constant pool where a ClassInfo structure will be found. If the object is a non-null instance of the class, then the int value 1 is pushed onto the stack. Otherwise, 0 is pushed onto the stack. Whether an object is an instance of a class is determined exactly as it is for the instanceof operator in .java source code.

checkcast

The checkcast instruction pops a reference from the stack and compares that object to a ClassInfo structure in the constant pool. The index to the ClassInfo structure in the constant pool is read from the two bytes in the code array immediately following the checkcast instruction. If the object can be cast to the given type, then the reference to it is pushed back onto the stack. There is thus no net change in the stack. However, if the object may not be cast to the specified type, then a ClassCastException is thrown. The rules for determining whether to push back the reference or throw an exception are the same as the rules given in the Java Language Specification for determining whether a cast is permitted.

The checkcast instruction behaves very much like the instanceof instruction. The two differences are what each instruction does to the stack and the treatment of null. Instanceof puts an int onto the stack. Checkcast puts a reference onto the stack or throws a ClassCastException. Null is not an instance of any type, but it may be cast to any type.

Threads: monitorenter and monitorexit

Most of Java’s thread support is either in the class libraries or in other parts of the virtual machine. The only part that requires direct byte code support is synchronization. There are two instructions that allow a thread to place and release locks on objects. These are monitorenter and monitorexit.

Each object is associated with a unique monitor. When a thread executes the monitorenter instruction, it pops a reference to an object from the stack and tries to take possession of the monitor for that object. If some other thread already possesses that monitor, then this thread stops and waits for the monitor to be released. To release a monitor, a thread uses the monitorexit instruction. A reference to the object whose monitor is to be released is popped from the stack.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.