9.6 Other Attributes

Any attributes the JVM implementation isn't expecting may be ignored. The only attributes that are absolutely crucial for proper functioning of a JVM are the Code attribute, discussed earlier, and the ConstantValue attribute, which is used to initialize fields. This section discusses some of the attributes defined in The Java Virtual Machine.

Attributes are not reflected directly in an Oolong program. A ConstantValue attribute added to a field if the Oolong program has an initializer for the field. Use of the .throws directive causes an Exceptions attribute to be added to the method.

9.6.1 ConstantValue Attribute

The ConstantValue attribute is used to initialize static final fields. The ConstantValue class contains a reference to an Integer, Float, Long, Double, or String constant, which is the initial value of the field. The field is initialized to that value by the JVM. For example, suppose you have a class Human that defines the standard temperature of the human body as 98.6 degrees:

 class Human {    public static final double standardTemperature = 98.6; } 

When this class is compiled, the definition of the standardTemperature field is

 0000d2 0019               access flags = 25 0000d4 0012               name = #18<StandardTemperature> 0000d6 000b               descriptor = #11<D> 0000d8 0001               1 field/method attributes:                           field/method attribute 0 0000da 000a                   name = #10<ConstantValue> 0000dc 00000002               length = 2 0000e0 0004                   Constant value: #4 

The field is named StandardTemperature, and it is a double. It has a ConstantValue attribute, which is defined by constant 4. The definition of constant 4 is

 000015 064058a66666666666 4. Double 98.6 

When this class is loaded, the value of the field is initialized to 98.6. No code is required to set the value of this field. This makes it easier to analyze the code for the purpose of making optimizations, because the field's value is always the same. The JVM can internally replace an instruction like

 getstatic Human/standardTemperature D 

with

 ldc 98.6 

which is usually faster.

The JVM implementation is required to understand this attribute, since failure to assign the value to the field would cause programs to execute incorrectly. All other attributes (besides Code) are useful to debuggers, Java compilers, optimizing JVMs, and other programs, but virtual machines may safely ignore them.

9.6.2 Exceptions Attribute

The Exceptions attribute is added to a method definition to name the exceptions that may be thrown by this method. It contains a list of the classes specified in the .throws directive of an Oolong program or the throws clause of a Java program.

For example, this fragment of a ClassLoader throws a ClassNotFoundException:

 public Class loadClass(String name, boolean resolve)    throws ClassNotFoundException {    // Load the class } 

Compiled into JVM code, it becomes

 00068f 0001               access flags = 1 000691 007f               name = #127<loadClass> 000693 0055               descriptor = #85 000695 0002               2 field/method attributes:                          field/method attribute 0 000697 005d                   name = #93<Code> 000699 000002de               length = 734 00069d 0005                   max stack: 5 00069f 0007                   max locals: 7 0006a1 000001f6               code length: 502     .                              .     .                              .     .                              .                      field/method attribute 1 00097b 0060               name = #96<Exceptions> 00097d 00000004           length = 4 000981 0001               Exception table length: 1 000983 0017               0. exception table entry: #23 

There are two attributes for this method: the Code attribute, which contains the implementation of the method, and the Exceptions attribute. After the attribute header, the Exceptions attribute has two bytes giving the number of classes. In this case, there is just one. This is followed by a list of exceptions, each two bytes long, representing an address in the constant pool. Each constant must be a Class constant naming the exception class.

The relevant parts of the constant pool are

 00004c 070078             23. Class name #120 0004ca 010020             120. UTF length=32 0004cd 6a61 7661 2f6c 616e 672f 436c 6173 734e   java/lang/ClassN 0004dd 6f74 466f 756e 6445 7863 6570 7469 6f6e   otFoundException 

Java compilers use this information to enforce the rule that exceptions must either be explicitly caught or listed in the throws clause of the method. When a class references a method or field in another class, the compiler does not need the source code to enforce this rule. It can determine which exceptions are thrown based on the Exceptions attribute in the compiled class file. Even though the information is available, this rule is not enforced by the JVM.

9.6.3 InnerClasses Attribute

The InnerClasses attribute was introduced to the Java platform in version 1.1. The Java virtual machine provides no special support for nesting classes within classes; all classes are top-level classes. Classes that are defined within another class are given special names to avoid naming conflicts. For example, this implementation of a Stack class uses an inner class nameEnumerator:

 public class Stack {    // Push, pop, etc. methods go here    class Enumerator implements java.util.Enumeration    {        // Definitions for hasMoreElements and nextElement go here    }    public java.util.Enumeration elements()    {        return new Enumerator();    } } 

When this code is compiled, two class files are produced: Stack and Stack$Enumerator. Stack$Enumerator contains the definition of Enumerator within the Stack class. Whenever either refers to Enumerator, it really means Stack$Enumerator.

An attribute is added to each class at the file level to point out that the two classes are related. This is called the InnerClasses attribute, and for Stack it looks like this:

 000185 0010              name = #16<InnerClasses> 000187 0000000a          length = 10 00018b 0001              number of classes = 1 00018d 0002                  inner class: #2 00018f 0001                  outer class: #1 000191 000e                  inner name: #14 000193 0002                  flags: 2 

The relevant constants are

 00000a 070014             1. Class name #20 00000d 070015             2. Class name #21 000076 01000a             14. UTF length=10 000079 456e 756d 6572 6174 6f72                 Enumerator 0000cf 010005             20. UTF length=5 0000d2 5374 6163 6b                             Stack 0000d7 010010             21. UTF length=16 0000da 5374 6163 6b24 456e 756d 6572 6174 6f72    Stack$Enumerator 

The first four bytes of the attribute data name the inner class and the outer class: Stack and Stack$Enumerator. The next two bytes give the name of the inner class before it was mangled: Enumerator. By explicitly providing the name, it relieves the program from having to know any conventions about how the mangled name was created.

Finally, the flags tell what access is permitted to the class. These flags are the same as for top-level classes, as shown in section 9.3. The 2 indicates that this is a private class.



Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net