📄 chap05.html
字号:
</I><P>For each type it loads, a Java Virtual Machine must store a <I>constant pool</I>. A constant pool is an ordered set of constants used by the type, including literals (string, integer, and floating point constants) and symbolic references to types, fields, and methods. Entries in the constant pool are referenced by index, much like the elements of an array. Because it holds symbolic references to all types, fields, and methods used by a type, the constant pool plays a central role in the dynamic linking of Java programs. The constant pool is described in more detail later in this chapter and in Chapter 6, "The Java Class File."</P>
<I><P>Field Information</P>
</I><P>For each field declared in the type, the following information must be stored in the method area. In addition to the information for each field, the order in which the fields are declared by the class or interface must also be recorded. Here韘 the list for fields:</P>
<UL><LI> The field韘 name
<LI> The field韘 type
<LI> The field韘 modifiers (some subset of <FONT FACE="Courier New">public</FONT>, <FONT FACE="Courier New">private</FONT>, <FONT FACE="Courier New">protected</FONT>, <FONT FACE="Courier New">static</FONT>, <FONT FACE="Courier New">final</FONT>, <FONT FACE="Courier New">volatile</FONT>, <FONT FACE="Courier New">transient</FONT>)</UL>
<I><P>Method Information</P>
</I><P>For each method declared in the type, the following information must be stored in the method area. As with fields, the order in which the methods are declared by the class or interface must be recorded as well as the data. Here韘 the list:</P>
<UL><LI> The method韘 name
<LI> The method韘 return type (or <FONT FACE="Courier New">void</FONT>)
<LI> The number and types (in order) of the method韘 parameters
<LI> The method韘 modifiers (some subset of <FONT FACE="Courier New">public</FONT>, <FONT FACE="Courier New">private</FONT>, <FONT FACE="Courier New">protected</FONT>, <FONT FACE="Courier New">static</FONT>, <FONT FACE="Courier New">final</FONT>, <FONT FACE="Courier New">synchronized</FONT>, <FONT FACE="Courier New">native</FONT>, <FONT FACE="Courier New">abstract</FONT>)</UL>
<P>In addition to the items listed above, the following information must also be stored with each method that is not abstract or native:</P>
<UL><LI> The method韘 bytecodes
<LI> The sizes of the operand stack and local variables sections of the method韘 stack frame (these are described in a later section of this chapter)
<LI> An exception table (this is described in Chapter 17, "Exceptions")</UL>
<I><P>Class Variables</P>
</I><P>Class variables are shared among all instances of a class and can be accessed even in the absence of any instance. These variables are associated with the class--not with instances of the class--so they are logically part of the class data in the method area. Before a Java Virtual Machine uses a class, it must allocate memory from the method area for each non-final class variable declared in the class.</P>
<P>Constants (class variables declared final) are not treated in the same way as non-final class variables. Every type that uses a final class variable gets a copy of the constant value in its own constant pool. As part of the constant pool, final class variables are stored in the method area--just like non-final class variables. But whereas non-final class variables are stored as part of the data for the type that <I>declares</I> them, final class variables are stored as part of the data for any type that <I>uses</I> them. This special treatment of constants is explained in more detail in Chapter 6, "The Java Class File."</P>
<I><P>A Reference to Class <FONT FACE="Courier New">ClassLoader</FONT></P>
</I><P>For each type it loads, a Java Virtual Machine must keep track of whether or not the type was loaded via the primordial class loader or a class loader object. For those types loaded via a class loader object, the virtual machine must store a reference to the class loader object that loaded the type. This information is stored as part of the type韘 data in the method area.</P>
<P>The virtual machine uses this information during dynamic linking. When one type refers to another type, the virtual machine requests the referenced type from the same class loader that loaded the referencing type. This process of dynamic linking is also central to the way the virtual machine forms separate name spaces. To be able to properly perform dynamic linking and maintain multiple name spaces, the virtual machine needs to know what class loader loaded each type in its method area. The details of dynamic linking and name spaces are given in Chapter 8, "The Linking Model."</P>
<I><P>A Reference to Class <FONT FACE="Courier New">Class</FONT></P>
</I><P>An instance of class <FONT FACE="Courier New">java.lang.Class</FONT> is created by the Java Virtual Machine for every type it loads. The virtual machine must in some way associate a reference to the <FONT FACE="Courier New">Class</FONT> instance for a type with the type韘 data in the method area.</P>
<P>Your Java programs can obtain and use references to <FONT FACE="Courier New">Class</FONT> objects. One static method in class <FONT FACE="Courier New">Class</FONT>, allows you to get a reference to the <FONT FACE="Courier New">Class</FONT> instance for any loaded class:</P>
<P><FONT FACE="Courier New">begin</FONT></P>
<FONT FACE="Courier New"><P>// A method declared in class java.lang.Class:</P>
<P>public static Class forName(String className);</P>
</FONT><P><FONT FACE="Courier New">end</FONT></P>
<P>If you invoke <FONT FACE="Courier New">forName("java.lang.Object")</FONT>, for example, you will get a reference to the <FONT FACE="Courier New">Class</FONT> object that represents <FONT FACE="Courier New">java.lang.Object</FONT>. If you invoke <FONT FACE="Courier New">forName("java.util.Enumeration")</FONT>, you will get a reference to the <FONT FACE="Courier New">Class</FONT> object that represents the <FONT FACE="Courier New">Enumeration</FONT> interface from the <FONT FACE="Courier New">java.util</FONT> package. You can use <FONT FACE="Courier New">forName()</FONT> to get a <FONT FACE="Courier New">Class</FONT> reference for any loaded type from any package, so long as the type can be (or already has been) loaded into the current name space. If the virtual machine is unable to load the requested type into the current name space, <FONT FACE="Courier New">forName()</FONT> will throw <FONT FACE="Courier New">ClassNotFoundException</FONT>.</P>
<P>An alternative way to get a <FONT FACE="Courier New">Class</FONT> reference is to invoke <FONT FACE="Courier New">getClass()</FONT> on any object reference. This method is inherited by every object from class <FONT FACE="Courier New">Object</FONT> itself:</P>
<P><FONT FACE="Courier New">begin</FONT></P>
<FONT FACE="Courier New"><P>// A method declared in class java.lang.Object:</P>
<P>public final Class getClass();</P>
</FONT><P><FONT FACE="Courier New">end</FONT></P>
<P>If you have a reference to an object of class <FONT FACE="Courier New">java.lang.Integer</FONT>, for example, you could get the <FONT FACE="Courier New">Class</FONT> object for <FONT FACE="Courier New">java.lang.Integer</FONT> simply by invoking <FONT FACE="Courier New">getClass()</FONT> on your reference to the <FONT FACE="Courier New">Integer</FONT> object.</P>
<P>Given a reference to a <FONT FACE="Courier New">Class</FONT> object, you can find out information about the type by invoking methods declared in class <FONT FACE="Courier New">Class</FONT>. If you look at these methods, you will quickly realize that class <FONT FACE="Courier New">Class</FONT> gives the running application access to the information stored in the method area. Here are some of the methods declared in class <FONT FACE="Courier New">Class</FONT>:</P>
<P><FONT FACE="Courier New">begin</FONT></P>
<FONT FACE="Courier New"><P>// Some of the methods declared in class java.lang.Class:</P>
<P>public String getName();</P>
<P>public Class getSuperClass();</P>
<P>public boolean isInterface();</P>
<P>public Class[] getInterfaces();</P>
<P>public ClassLoader getClassLoader()</P>
</FONT><P><FONT FACE="Courier New">end</FONT></P>
<P>These methods just return information about a loaded type. <FONT FACE="Courier New">getName()</FONT> returns the fully qualified name of the type. <FONT FACE="Courier New">getSuperClass()</FONT> returns the <FONT FACE="Courier New">Class</FONT> instance for the type韘 direct superclass. If the type is class <FONT FACE="Courier New">java.lang.Object</FONT> or an interface, none of which have a superclass, <FONT FACE="Courier New">getSuperClass()</FONT> returns <FONT FACE="Courier New">null</FONT>. <FONT FACE="Courier New">isInterface()</FONT> returns <FONT FACE="Courier New">true</FONT> if the <FONT FACE="Courier New">Class</FONT> object describes an interface, <FONT FACE="Courier New">false</FONT> if it describes a class. <FONT FACE="Courier New">getInterfaces()</FONT> returns an array of <FONT FACE="Courier New">Class</FONT> objects, one for each direct superinterface. The superinterfaces appear in the array in the order they are declared as superinterfaces by the type. If the type has no direct superinterfaces, <FONT FACE="Courier New">getInterfaces()</FONT> returns an array of length zero. <FONT FACE="Courier New">getClassLoader()</FONT> returns a reference to the <FONT FACE="Courier New">ClassLoader</FONT> object that loaded this type, or <FONT FACE="Courier New">null</FONT> if the type was loaded by the primordial class loader. All this information comes straight out of the method area.</P>
<I><P>Method Tables</P>
</I><P>The type information stored in the method area must be organized to be quickly accessible. In addition to the raw type information listed above, implementations may include other data structures that speed up access to the raw data. One example of such a data structure is a <I>method table</I>. For each non-abstract class a Java Virtual Machine loads, it could generate a method table and include it as part of the class information it stores in the method area. A method table is an array of direct references to all the instance methods that may be invoked on a class instance, including instance methods inherited from superclasses. (A method table isn韙 helpful in the case of abstract classes or interfaces, because the program will never instantiate these.) A method table allows a virtual machine to quickly locate an instance method invoked on an object. Method tables are described in detail in Chapter 8, "The Linking Model."</P>
<I><P>An Example of Method Area Use</P>
</I><P>As an example of how the Java Virtual Machine uses the information it stores in the method area, consider these classes:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file jvm/ex2/Lava.java
<P>class Lava {</P>
<P> </P>
<P> private int speed = 5; // 5 kilometers per hour</P>
<P> </P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -