Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


Fields

The getfield instruction pops a reference from the stack. This reference is used as an index into the constant pool to get a FieldRef out of the pool. The FieldRef is used by the virtual machine to find the appropriate field and put its value on the stack.

For example, consider the simple class in Listing 5-5. It compiles to the byte codes shown in Listing 5-6.

Listing 5-5 FieldExample

  public class FieldExample {

   int i;

  public int getField() {

   return i;

  }

  public void setField(int i) {

   this.i = i;

  }

  }

Listing 5-6 FieldExample in byte code

  public class FieldExample extends java.lang.Object  {

   int i;

   public int getField() {

  0  aload_0
  1  getfield
  2  0
  3  4
  4  ireturn

   }


   public void setField(int) {

  0  aload_0
  1  iload_1
  2  putfield
  3  0
  4  4
  5  return

   }


   public void <init>() {

  0  aload_0
  1  invokespecial
  2  0
  3  3
  4  return

   }

  }

The first instruction in both the getField() and setField() methods is aload_0. This loads the reference from the zeroth local variable onto the stack. In a non-static method, this is always a reference to the current object.

The next instruction in the getField() method is getfield. This pushes the value of the fourth entry in the constant pool onto the stack. There’s not enough information here yet to tell what that entry is. I’ll soon revise the Disassembler class to make it more obvious exactly what that entry is. Then the value is returned.

The setField() method also begins by pushing a reference to the current object onto the stack with aload_0. Then the first argument to the method, local variable 1, is pushed onto the stack. The putfield instruction pops this value from the stack and puts it in the field referred to by constant pool entry 4. Again, you don’t know exactly what that field is from the byte code alone. You also need to look at the constant pool.


Note:  There’s a third method in the byte code for the FieldExample class: public void <init>(). It’s more than a little disconcerting because there was no <init> method in the source code. In fact, <init> isn’t even a legal Java identifier because of the angle brackets.

<init> is a constructor. In .java byte code, all constructors are named <init> rather than the name of the class as in .java source code. Furthermore, all classes have at least one constructor, by default a constructor with no arguments, even if the source code does not. Constructors are discussed in more detail later in this chapter.


Static fields are similar except that the getstatic and putstatic instructions are used instead of getfield and putfield. The two bytes following the instruction are an index into the constant pool. That entry in the constant pool should contain a FieldRef structure. With getstatic, the value of that field is pushed onto the static. With putstatic, a value is popped from the stack and stored in that field.

Methods

There are four instructions in Java to call methods: invokevirtual, invokespecial, invokeinterface, and invokestatic. Invokevirtual is used for normal method calls. The invokeinterface instruction is used to call methods defined in interfaces. The invokestatic instruction is used to call static methods. Finally, the invokespecial instruction is used to call methods in the superclasses of the current object.

Although these instructions differ in the kinds of methods they invoke, they all behave similarly. Each reads the next two bytes in the code array as an index into the constant pool. That pool entry is a Methodref. The Methodref is inspected to find out what arguments the method takes. These are popped from the stack and placed in the local variable array of the invoked method. Then control moves to the invoked method. If the invoked method returns a value, that value is pushed onto the stack of the current method.

For example, consider the disassembly of the HelloWorld program in Listing 5-7. The main() method first gets the seventh static field from the constant pool. The seventh static field in the constant pool is another index into the constant pool, 4. The fourth entry in the constant pool is still another index into the constant pool, 28. Finally, the 28th entry in the constant pool is the static field you want, java.lang.System. A reference to this static object is placed on the operand stack.

Next, the ldc instruction pushes the first item in the constant pool onto the stack. The first item in the pool is a string, the UTF8 value of which is stored at position 29. Therefore, a new string object is created with the value at position 29 in the pool “Hello World!” A reference to this string is pushed onto 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.