To add a field to a class, use the .field directive. Every field has a name and a type. The type determines what kinds of values may be stored in that field. For example:
.field age I ; Name: age Type: int .field weight F ; Name: weight Type: float .field name Ljava/lang/String; ; Name: name Type: String .field friends [LPerson; ; Name: friends Type: Person array
The last part of a .field directive is called the field descriptor. A descriptor is a written name for a type. Most of the descriptors are single letters, like I for int and F for float. Some are less obvious, like Z for boolean or J for long. Table 2.2 summarizes the field descriptors. The last entry in the table (void) isn't a valid field type. We encounter this type later when we work with methods.
If the value of a field is a reference to an object of type classname, then the descriptor is Lclassname;. In this case, the semicolon (;) is used to mark the end of the descriptor, not to begin a comment. For example,
.field out Ljava/io/PrintStream; ; a PrintStream .field me LI; ; A class named I, not an int
In an array descriptor, the number of dimensions is signified by the number of left brackets ([) at the beginning. Following the left brackets is the element type of the array:
.field scores [I ; Array of ints .field nicknames [Ljava/lang/String; ; Array of Strings .field matrix [[F ; Array of array of ; floats
You may have two different fields with the same name but different types:
.field grade C ; Grade on last assignment, as a char .field grade F ; Slope of the road, as a float
Fields may be protected so that they may be accessed only from code within certain classes. This is done by adding keywords to the .field directive. These keywords are familiar to Java programmers, though unlike Java they may appear in any order.
The general form of the .field directive is
.field modifier1 modifier2 ... name type = value
The modifiers are shown in Table 2.3. If none of the public, private, or protected keywords is given, then the field is given package access. It may be accessed from any class with the same package name but not from classes with different packages.
The protected keyword is a little misleading. A field that is protected is actually a little less protected than one with package access. It may be accessed from any subclass, as well as from any class within the package. Consider the declarations
.class public language/Greeting .field protected introduction Ljava/lang/String; .end class .class deadLanguages/OldEnglish .super language/Greeting .end class .class language/Translator .super java/lang/Object .end class .class language/linguistics/Greeting .super java/lang/Object .end class
The protected field language/Greeting/introduction may be accessed from any method in deadLanguages/OldEnglish, since it has language/Greeting as a superclass. It may also be accessed from language/Translator, since it's in the same package as language/Greeting. However, it may not be accessed from language/linguistics/Greeting, since it is in a different package from language/Greeting.
The last part of the .field directive, = value, is optional. It can be used only with static fields. If it's present, the value must be a constant of the same type as the field. When the object is created, the field is initialized to that value instead of the default value for the field (0 for the numeric fields, null for reference fields). For example:
; A public String field initialized to "Hello" .field public static introduction Ljava/lang/String; = "Hello" ; An int field with default access initialized to 999 .field static numberOfCheeseburgers I = 999 ; A protected PrintStream field initialized to null .field protected static out Ljava/io/PrintStream; ; This initializer is ignored, because the field isn't static .field public columbusDiscoversAmerica = 1492
The initial value is limited to the numeric types (int, float, long, or double) or a String. Java permits you to initialize fields to objects
public Bicycle my_wheels = new MountainBike();
but in the JVM the initialization has to be a separate step from the declaration. If the field is not static, or if it is static but initialized to some other type of object besides String, then you should put code in the initializing method to initialize the field. See section 4.2 for more about initialization.