Dynamic linking
Because Java programs are dynamically linked, references to methods
initially are symbolic. All invoke instructions, such as
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.

Verification
During resolution, the JVM also performs several verification checks.
These checks ensure that Java language rules are followed and that the
invoke instruction is safe to execute. For example, the virtual
machine first makes sure the symbolically referenced method exists. If
it exists, the virtual machine checks to make sure the current class
can legally access the method. For example, if the method is private,
it must be a member of the current class. If any of these checks fail,
the Java virtual machine throws an exception.

Objectref and args
Once the method has been resolved, the Java virtual machine is ready to
invoke it. If the method is an instance method, it must be invoked on
an object. For every instance method invocation, the virtual machine
expects a reference to the object (objectref) to be on the stack. In
addition to objectref, the virtual machine expects the arguments (args)
required by the method, if any, to be on the stack. If the method is a
class method, only the args are on the stack. Class methods don't
require an objectref because they aren't invoked on an object.

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.

Pushing and popping the stack frame
To invoke a method, the Java virtual machine creates a new stack
frame for the method. The stack frame contains space for the
method's local variables, its operand stack, and any other information
required by a particular virtual machine implementation. The size of
the local variables and operand stack are calculated at compile-time
and placed into the class file, so the virtual machine knows just how
much memory will be needed by the method's stack frame. When the JVM
invokes a method, it creates a stack frame of the proper size for that
method.

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.