📄 constantpool.doc.html
字号:
</ol><a name="79473"></a><h3>5.3.3 Creating Array Classes</h3><a name="79474"></a>The following steps are used to create the array class C denoted by N using class loader L. Class loader L may be either the bootstrap class loader or a user-defined class loader.<p><a name="79898"></a>If L has already been recorded as an initiating loader of an array class with the same component type as N, that class is C, and no array class creation is necessary. Otherwise, the following steps are performed to create C:<p><ol><a name="79479"></a><li>If the component type is a reference type, the algorithm of this section <a href="ConstantPool.doc.html#72007">(§5.3)</a> is applied recursively using class loader L in order to load and thereby create the component type of C. <p><a name="79480"></a><li>The Java virtual machine creates a new array class with the indicated component type and number of dimensions. If the component type is a reference type, C is marked as having been defined by the defining class loader of the component type. Otherwise, C is marked as having been defined by the bootstrap class loader. In any case, the Java virtual machine then records that L is an initiating loader for C <a href="ConstantPool.doc.html#78621">(§5.3.4)</a>. If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type. Otherwise, the accessibility of the array class is <code>public</code>.</ol><a name="78621"></a><h3>5.3.4 Loading Constraints</h3><a name="78364"></a>Ensuring type safe linkage in the presence of class loaders requires special care. It is possible that when two different class loaders initiate loading of a class or interface denoted by N, the name N may denote a different class or interface in each loader.<p><a name="78431"></a>When a class or interface C = <N1, L1> makes a symbolic reference to a field or method of another class or interface D = <N2, L2> , the symbolic reference includes a descriptor specifying the type of the field, or the return and argument types of the method. It is essential that any type name N mentioned in the field or method descriptor denote the same class or interface when loaded by L1 and when loaded by L2.<p><a name="85649"></a>To ensure this, the Java virtual machine imposes <i>loading constraints</i> of the form N<sup>L1</sup> = N<sup>L2</sup> during preparation <a href="ConstantPool.doc.html#71421">(§5.4.2)</a> and resolution <a href="ConstantPool.doc.html#73492">(§5.4.3)</a>. To enforce these constraints, the Java virtual machine will, at certain prescribed times (see <a href="ConstantPool.doc.html#79383">§5.3.1</a>, <a href="ConstantPool.doc.html#79441">§5.3.2</a>, <a href="ConstantPool.doc.html#79473">§5.3.3</a>, and <a href="ConstantPool.doc.html#79388">§5.3.5</a>), record that a particular loader is an initiating loader of a particular class. After recording that a loader is an initiating loader of a class, the Java virtual machine must immediately check to see if any loading constraints are violated. If so, the record is retracted, the Java virtual machine throws a <code>LinkageError</code>, and the loading operation that caused the recording to take place fails.<p><a name="85674"></a>Similarly, after imposing a loading constraint (see <a href="ConstantPool.doc.html#71421">§5.4.2</a>, <a href="ConstantPool.doc.html#71685">§5.4.3.2</a>, <a href="ConstantPool.doc.html#86899">§5.4.3.3</a>, and <a href="ConstantPool.doc.html#71722">§5.4.3.4</a>), the Java virtual machine must immediately check to see if any loading constraints are violated. If so, the newly imposed loading constraint is retracted, the Java virtual machine throws a <code>LinkageError</code>, and the operation that caused the constraint to be imposed (either resolution or preparation, as the case may be) fails.<p><a name="85676"></a>The situations described here are the only times at which the Java virtual machine checks whether any loading constraints have been violated. A loading constraint is <em>violated</em> if, and only if, all the following four conditions hold:<p><ul><li>There exists a loader L such that L has been recorded by the Java virtual machine as an initiating loader of a class C named N.<p><li>There exists a loader L<i>'</i> such that L<i>'</i> has been recorded by the Java virtual machine as an initiating loader of a class C<i>'</i> named N.<p><li>The equivalence relation defined by the (transitive closure of the) set of imposed constraints implies N <sup>L</sup> = N <sup>L'</sup>.<p><li>C <img src="chars/notequal.gif"> C  <i>'</i>.</ul><a name="85310"></a>A full discussion of class loaders and type safety is beyond the scope of this specification. For a more comprehensive discussion, readers are referred to <i>Dynamic Class Loading in the Java Virtual Machine</i> by Sheng Liang and Gilad Bracha (Proceedings of the 1998 ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages and Applications).<p><a name="79388"></a><h3>5.3.5 Deriving a Class from a <code>class</code> File Representation</h3><a name="79389"></a>The following steps are used to derive the nonarray class or interface C denoted by N  using loader L from a purported representation in <code>class</code> file format.<p><ol><a name="79390"></a><li>First, the Java virtual machine determines whether it has already recorded that L is an initiating loader of a class or interface denoted by N. If so, this creation attempt is invalid and loading throws a <code>LinkageError</code>.<p><a name="79391"></a><li>Otherwise, the Java virtual machine attempts to parse the purported representation. However, the purported representation may not in fact be a valid representation of C. <p>This phase of loading must detect the following errors:<p><ul><li>If the purported representation is not in <code>class</code> file format (<a href="ClassFile.doc.html#74353">§4.1</a>, pass 1 of <a href="ClassFile.doc.html#9766">§4.9.1</a>), loading throws an instance of <code>ClassFormatError</code>.<p><li>Otherwise, if the purported representation is not of a supported major or minor version (<a href="ClassFile.doc.html#74353">§4.1)</a>, loading throws an instance of <code>UnsupportedClassVersionError</code>.<a href="#81526"><sup>2</sup></a><p><li>Otherwise, if the purported representation does not actually represent a class named N, loading throws an instance of <code>NoClassDefFoundError</code> or an instance of one of its subclasses.</ul><p><a name="79410"></a><li>If C has a direct superclass, the symbolic reference from C to its direct superclass is resolved using the algorithm of <a href="ConstantPool.doc.html#71636">Section 5.4.3.1</a>. Note that if C is an interface it must have <code>Object</code> as its direct superclass, which must already have been loaded. Only <code>Object</code> has no direct superclass.<p>Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:<p><ul><li>If the class or interface named as the direct superclass of C is in fact an interface, loading throws an <code>IncompatibleClassChangeError</code>.<p><li>Otherwise, if any of the superclasses of C is C itself, loading throws a <code>ClassCircularityError</code>.</ul><p><a name="79420"></a><li>If C has any direct superinterfaces, the symbolic references from C to its direct superinterfaces are resolved using the algorithm of <a href="ConstantPool.doc.html#71636">Section 5.4.3.1</a>.<p>Any exceptions that can be thrown due to class or interface resolution can be thrown as a result of this phase of loading. In addition, this phase of loading must detect the following errors:<p><ul><li>If any of the classes or interfaces named as direct superinterfaces of C is not in fact an interface, loading throws an <code>IncompatibleClassChangeError</code>.<p><li>Otherwise, if any of the superinterfaces of C is C itself, loading throws a <code>ClassCircularityError</code>.</ul><p><a name="80174"></a><li>The Java virtual machine marks C as having L as its defining class loader and records that L is an initiating loader of C <a href="ConstantPool.doc.html#78621">(§5.3.4)</a>.</ol><a name="71418"></a><hr><h2>5.4 Linking</h2><a name="71814"></a>Linking a class or interface <a href="Concepts.doc.html#22574">(§2.17.3)</a> involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary. Resolution of symbolic references in the class or interfaceis an optional part of linking.<p><a name="71817"></a><h3>5.4.1 Verification</h3><a name="71568"></a>The representation of a class or interface is <i>verified</i> <a href="ClassFile.doc.html#88597">(§4.9)</a> to ensure that its binary representation is structurally valid (passes 2 and 3 of <a href="ClassFile.doc.html#9766">§4.9.1</a>). Verification may cause additional classes and interfaces to be loaded <a href="ConstantPool.doc.html#72007">(§5.3)</a> but need not cause them to be prepared or verified.<p><a name="73849"></a><p><a name="87759"></a>Verification must detect the following error:<p><ul><li>If the representation of the class or interface does not satisfy the static or structural constraints listed in <a href="ClassFile.doc.html#40222">Section 4.8, "Constraints on Java Virtual Machine Code,"</a> verification throws a <code>VerifyError</code>.</ul><a name="76208"></a>A class or interface must be successfully verified before it is initialized. Any attempt to initialize a class or interface that has not been successfully verified must be preceded by verification. Repeated verification of a class or interface that the Java virtual machine has previously unsuccessfully attempted to verify always fails with the same error that was thrown as a result of the initial verification attempt.<p><a name="71421"></a><h3>5.4.2 Preparation</h3><a name="73485"></a><i>Preparation</i> involves creating the static fields for the class or interface and initializingthose fields to their standard default values <a href="Concepts.doc.html#15858">(§2.5.1)</a>. Preparation should not be confused with the execution of static initializers <a href="Concepts.doc.html#32316">(§2.11)</a>; unlike execution of static initializers, preparation does not require the execution of any Java virtual machine code. <p><a name="79142"></a>During preparation of a class or interface C, the Java virtual machine also imposes loading constraints (<a href="ConstantPool.doc.html#78621">§5.3.4</a>). Let L<sub>1</sub> be the defining loader of C. For each method <i>m</i> declared in C that overrides a method declared in a superclass or superinterface <D, L2  \>, the Java virtual machine imposes the following loading constraints: Let T<sub>0</sub> be the name of the type returned by <i>m</i>, and let T<sub>1</sub>, ..., T<sub>n</sub> be the names of the argument types of <i>m</i>. Then T<sub>i</sub><sup>L1</sup>=T<sub>i</sub><sup>L2</sup> for <i>i = 0</i> to<i> n</i> <a href="ConstantPool.doc.html#78621">(§5.3.4)</a>.<p><a name="73540"></a>Preparation may occur at any time following creation but must be completed prior to initialization.<p><a name="73492"></a><h3>5.4.3 Resolution</h3><a name="74024"></a>The process of dynamically determining concrete values from symbolic references in the runtime constant pool is known as <i>resolution</i>. <p><a name="74943"></a>Resolution can be attempted on a symbolic reference that has already been resolved. An attempt to resolve a symbolic reference that has already successfully been resolved always succeeds trivially and always results in the same entity produced by the initial resolution of that reference.<p><a name="75906"></a>Subsequent attempts to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt.<p><a name="74944"></a>Certain Java virtual machine instructions require specific linking checks when resolving symbolic references. For instance, in order for a <i>getfield</i> instruction to successfully resolve the symbolic reference to the field on which it operates it must complete the field resolution steps given in <a href="ConstantPool.doc.html#71685">Section 5.4.3.2</a>. In addition, it must also check that the field is not <code>static</code>. If it is a <code>static</code> field, a linking exception must be thrown. <p><a name="73906"></a>Linking exceptions generated by checks that are specific to the execution of a particular Java virtual machine instruction are given in the description of that instruction and are not covered in this general discussion of resolution. Note that such exceptions, although described as part of the execution of Java virtual machine instructions rather than resolution, are still properly considered failure of resolution.<p><a name="73526"></a>The Java virtual machine instructions <i>anewarray</i>, <i>checkcast</i>, <i>getfield</i>, <i>getstatic</i>, <i>instanceof</i>, <i>invokeinterface</i>, <i>invokespecial</i>, <i>invokestatic</i>, <i>invokevirtual</i>, <i>multianewarray</i>, <i>new</i>, <i>putfield</i>, and <i>putstatic</i> make symbolic references to the runtime constant pool. Execution of any of these instructions requires resolution of its symbolic reference. <p><a name="74202"></a>The following sections describe the process of resolving a symbolic reference in the runtime constant pool <a href="ConstantPool.doc.html#73272">(§5.1)</a> of a class or interface D. Details of resolution differ with the kind of symbolic reference to be resolved. <p><a name="71636"></a><h4>5.4.3.1 Class and Interface Resolution</h4><a name="71647"></a>To resolve an unresolved symbolic reference from D to a class or interface C denoted by N, the following steps are performed:<p><ol><a name="71648"></a><li>The defining class loader of D is used to create a class or interface denoted by N. This class or interface is C. Any exception that can be thrown as a result of failure of class or interface creation can thus be thrown as a result of failure of class and interface resolution. The details of the process are given in <a href="ConstantPool.doc.html#72007">Section 5.3</a>. <p><a name="71665"></a><li>If C is an array class and its element type is a reference type, then the symbolic reference to the class or interface representing the element type is resolved by invoking the algorithm in <a href="ConstantPool.doc.html#71636">Section 5.4.3.1</a> recursively.<p><a name="72502"></a><li>Finally, access permissions to C are checked:<p><ul><li>If C is not accessible <a href="ConstantPool.doc.html#75929">(§5.4.4)</a> to D, class or interface resolution throws an <code>IllegalAccessError</code>. </ul><a name="77677"></a>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -