Recent top five:
Let's talk about exceptions ...
How do you handle exceptions? Do you think upfront about the type of exceptions that you want to catch or do you just let
the outside world handle it?
-- Jeroen van Bergen in JW Blogs
Instance methods require an instance before they can be invoked, whereas class methods do not.
Instance methods use dynamic (late) binding, whereas class methods use static (early) binding.
When the Java virtual machine invokes a class method, it selects the method to invoke based on the type of the object reference, which is always known at compile-time. On the other hand, when the virtual machine invokes an instance method, it selects the method to invoke based on the actual class of the object, which may only be known at run time.
The JVM uses two different instructions, shown in the following table, to invoke these two different kinds of methods: invokevirtual for instance methods, and invokestatic for class methods.
| Opcode | Operand(s) | Description |
|---|
invokevirtual |
indexbyte1, indexbyte2 |
pop objectref and args, invoke method at constant pool index |
invokestatic |
indexbyte1, indexbyte2 |
pop args, invoke static method at constant pool index |
invokevirtual and invokestatic, refer to a constant pool entry that initially contains a symbolic reference. (See my earlier column, "The Java class file lifestyle," for a description of constant pool.) The symbolic reference is a bundle of information that uniquely identifies a method,
including the class name, method name, and method descriptor. (A method descriptor is the method's return type and the number
and types of its arguments.) The first time the Java virtual machine encounters a particular invoke instruction, the symbolic
reference must be resolved.To resolve a symbolic reference, the JVM locates the method being referred to symbolically and replaces the symbolic reference with a direct reference. A direct reference, such as a pointer or offset, allows the virtual machine to invoke the method more quickly if the reference is ever used again in the future.
For example, upon encountering an invokevirtual instruction, the Java virtual machine forms an index into the constant pool of the current class from the indexbyte1 and indexbyte2 operands that follow the invokevirtual opcode. The constant pool entry contains a symbolic reference to the method to invoke. The process of resolving symbolic
references in the constant pool is how the JVM performs dynamic linking.
The objectref and args (or just args, in the case of a class method) must be pushed onto the calling method's operand stack by the bytecode instructions that precede the invoke instruction.
Adding a new frame onto the Java stack when a method is invoked is called "pushing" a stack frame; removing a frame when a method returns is called "popping" a stack frame. The Java stack is made up solely of these frames.
In the case of an instance method, the virtual machine pops the objectref and args from the operand stack of the calling method's
stack frame. The JVM creates a new stack frame and places the objectref on the new stack frame as local variable 0, and all
the args as local variable 1, 2, and so on. The objectref is the implicit this pointer that is passed to any instance method.
For a class method, the virtual machine just pops the args from the operand stack of the calling method's frame and places them onto the new stack frame as local variable 0, 1, 2, and so on.
Once the objectref and args (or just the args, for a class method) have been placed into the local variables of the new frame, the virtual machine makes the new stack frame current and sets the program counter to point to the first instruction in the new method.
The JVM specification does not require a particular implementation for the Java stack. Frames could be allocated individually from a heap, or they could be taken from contiguous memory, or both. If two frames are contiguous, however, the virtual machine can just overlap them such that the top of the operand stack of one frame forms the bottom of the local variables of the next. In this scheme, the virtual machine need not copy objectref and args from one frame to another, because the two frames overlap. The operand stack word containing objectref in the calling method's frame would be the same memory location as local variable 0 of the new frame.