getstatic <field-spec> <descriptor><field-spec> is composed of two parts, a classname and a fieldname. The classname is all of the characters in the <field-spec> up to the last '/' character, and the fieldname is the rest of the characters after the last '/'. For example:
foo/baz/AnotherClass/aVeryLongFieldName -- classname -------/-- fieldname -----{{JM - can we turn this into a nicer diagram?}}
<descriptor> is the Java type descriptor for the field, for example Ljava/io/PrintStream;
In Jasmin, the .field directive is used to add a field to a class. See Chapter 16 for a description of this and other Jasmin directives.
Stack Before Before
or, for static fields that hold doubles or longs: After ... value ...
Description After ... value-word1 value-word2 ...
getstatic pops objectref (a reference to an object) from the stack, retrieves the value of the static field (also known as a class field) identified by <field-spec> from objectref, and pushes the one-word or two-word value onto the operand stack.
For example, when you write the Java expression:
PrintStream obj = java.lang.System.out;this generates a call to getstatic like:
getstatic java/lang/System/out Ljava/io/PrintStream; astore_1 ; store the object reference result in local variable 1In Jasmin, getstatic takes two parameters, <field-spec> and <descriptor>. <field-spec> provides classname, the name of the class that defines the static field, as well fieldname, as the name of the field. In the example above, the <field-spec> is "java/lang/System/out", indicating that the classname is "java/lang/System" and the fieldname is "out". <descriptor> indicates the type of data held in the field, and is a standard Java type descriptor (see Chapter 4). In the example above, <descriptor> is "Ljava/io/PrintStream;", i.e. a reference to a PrintStream object.
getstatic first resolves classname into a Java class. Then it locates the fieldname in that class, determining the width of the field (in bytes) and its offset (in bytes) from the base of the class's static data. The type of the field must match <descriptor>. See Chapter 7 for more on how fields are resolved
To retrieve the value for the field, getstatic obtains the bytes starting at offset and extending for width bytes from the start of the class's static data, expands it to either a 4-byte or 8-byte value, and pushes the value onto the operand stack.
Bytecode
In bytecode, the getstatic opcode is followed by a 16-bit unsigned integer index. This is the index of an entry in the constant pool of the current class. The entry is tagged a CONSTANT_Fieldref entry. The fieldref entry lists a CONSTANT_Class entry in the constant pool whose name is the classname given in <field-spec>, as well as a CONSTANT_NameAndType entry in the constant pool, whose name is the fieldname given in <field-spec>, and whose descriptor is the string given by <descriptor>.
Type | Description |
u1 | getstatic opcode = 0xB2 (178) |
u2 | index |
See Also
putfield, getfield, putstatic
Notes
Fields cannot be overriden, although they can be 'shadowed'. For example, with the two classes:
class A { static int x; } and class B extends A { static int x; }then the runtime system will allocate storage for both the static field "A/x" and the static field "B/x". Which field is accessed is determined by the class name given in <field-spec>.