⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12.doc.html

📁 java语言规范
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<a name="44615"></a>		System.out.println(J.i);
<a name="44616"></a>		System.out.println(K.j);
<a name="44617"></a>	}
<a name="44618"></a>
	static int out(String s, int i) {
<a name="44619"></a>		System.out.println(s + "=" + i);
<a name="44620"></a>		return i;
<a name="44621"></a>	}
<a name="44622"></a>}
</pre><a name="44623"></a>
produces the output:
<p><pre><a name="44624"></a>
1
<a name="44625"></a>j=3
<a name="44626"></a>jj=4
<a name="44627"></a>3
</pre><a name="44628"></a>
The reference to <code>J.i</code> is to a field that is a compile-time constant; therefore, it does 
not cause <code>I</code> to be initialized. The reference to <code>K.j</code> is a reference to a field actually 
declared in interface <code>J</code> that is not a compile-time constant; this causes initialization
of the fields of interface <code>J</code>, but not those of its superinterface <code>I</code>, nor those of 
interface <code>K</code>. Despite the fact that the name <code>K</code> is used to refer to field <code>j</code> of interface 
<code>J</code>, interface <code>K</code> is not actively used.
<p><a name="44630"></a>
<h3>12.4.2    Detailed Initialization Procedure</h3>
<a name="44631"></a>
Because Java is multithreaded, initialization of a class or interface requires careful 
synchronization, since some other thread may be trying to initialize the same class 
or interface at the same time. There is also the possibility that initialization of a 
class or interface may be requested recursively as part of the initialization of that 
class or interface; for example, a variable initializer in class <i>A</i> might invoke a 
method of an unrelated class <i>B</i>, which might in turn invoke a method of class <i>A</i>. 
The implementation of the Java Virtual Machine is responsible for taking care of 
synchronization and recursive initialization by using the following procedure. It 
assumes that the <code>Class</code> object has already been verified and prepared, and that the 
<code>Class</code> object contains state that indicates one of four situations:
<p><ul><a name="44632"></a>
<li>This <code>Class</code> object is verified and prepared but not initialized.
<a name="44633"></a>
<li>This <code>Class</code> object is being initialized by some particular thread <i>T</i>.
<a name="44634"></a>
<li>This <code>Class</code> object is fully initialized and ready for use.
<a name="44635"></a>
<li>This <code>Class</code> object is in an erroneous state, perhaps because the verification or preparation step failed, or because initialization was attempted and failed.
</ul><a name="44636"></a>
The procedure for initializing a class or interface is then as follows:
<p><ol>
<a name="44640"></a>
<li>Synchronize <a href="14.doc.html#79287">(&#167;14.17)</a> on the <code>Class</code> object that represents the class or interface to be initialized. This involves waiting until the current thread can obtain the lock for that object <a href="17.doc.html#28460">(&#167;17.13)</a>.
<a name="44644"></a>
<li>If initialization is in progress for the class or interface by some other thread, then <code>wait</code> <a href="javalang.doc1.html#33394">(&#167;20.1.6)</a> on this <code>Class</code> object (which temporarily releases the lock). When the current thread awakens from the <code>wait</code>, repeat this step.
<a name="44648"></a>
<li>If initialization is in progress for the class or interface by the current thread, then this must be a recursive request for initialization. Release the lock on the <code>Class</code> object and complete normally.
<a name="44649"></a>
<li>If the class or interface has already been initialized, then no further action is required. Release the lock on the <code>Class</code> object and complete normally.
<a name="44650"></a>
<li>If the <code>Class</code> object is in an erroneous state, then initialization is not possible. Release the lock on the <code>Class</code> object and throw a <code>NoClassDefFoundError</code>.
<a name="44651"></a>
<li>Otherwise, record the fact that initialization of the <code>Class</code> object is now in progress by the current thread and release the lock on the <code>Class</code> object.
<a name="44652"></a>
<li>Next, if the <code>Class</code> object represents a class rather than an interface, and the superclass of this class has not yet been initialized, then recursively perform this entire procedure for the superclass. If necessary, verify and prepare the superclass first. If the initialization of the superclass completes abruptly because of a thrown exception, then lock this <code>Class</code> object, label it erroneous, notify all waiting threads <a href="javalang.doc1.html#13790">(&#167;20.1.10)</a>, release the lock, and complete abruptly, throwing the same exception that resulted from initializing the superclass.
<a name="44656"></a>
<li>Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block, except that <code>final</code> class variables and fields of interfaces whose values are compile-time constants are initialized first (<a href="8.doc.html#38010">&#167;8.3.2.1</a>, <a href="9.doc.html#40720">&#167;9.3.1</a>, <a href="13.doc.html#45139">&#167;13.4.8</a>).
<a name="44657"></a>
<li>If the execution of the initializers completes normally, then lock this <code>Class</code> object, &#32;label it fully initialized, notify all waiting threads <a href="javalang.doc1.html#13790">(&#167;20.1.10)</a>, release the lock, and complete this procedure normally.
<a name="44661"></a>
<li>Otherwise, the initializers must have completed abruptly by throwing some exception &#32;<i>E</i>. If the class of <i>E</i> is not <code>Error</code> or one of its subclasses, then create a new instance of the class <code>ExceptionInInitializerError</code>, with <i>E</i> as the argument, and use this object in place of <i>E</i> in the following step. But if a new instance of <code>ExceptionInInitializerError</code> cannot be created because an <code>OutOfMemoryError</code> occurs, then instead use an <code>OutOfMemoryError</code> object in place of <i>E</i> in the following step.
<a name="44665"></a>
<li>Lock the <code>Class</code> object, label it erroneous, notify all waiting threads <a href="javalang.doc1.html#13790">(&#167;20.1.10)</a>, release the lock, and complete this procedure abruptly with reason <i>E</i> or its replacement as determined in the previous step.
</ol>
<a name="44666"></a>
(Due to a flaw in some early implementations of Java, a exception during class initialization
was ignored, rather than causing an <code>ExceptionInInitializerError</code> 
as described here.) 
<p><a name="44667"></a>
<h3>12.4.3    Initialization: Implications for Code Generation</h3>
<a name="44668"></a>
Code generators need to preserve the points of possible initialization of a class or 
interface, inserting an invocation of the initialization procedure just described. If 
this initialization procedure completes normally and the <code>Class</code> object is fully initialized
and ready for use, then the invocation of the initialization procedure is no 
longer necessary and it may be eliminated from the code-for example, by patching
it out or otherwise regenerating the code.
<p><a name="46847"></a>
Compile-time analysis may, in some cases, be able to eliminate many of the checks that a type has been initialized from the generated code, if an initialization order for a group of related types can be determined. Such analysis must, however, fully account for the fact that Java is concurrent and that initialization code is unrestricted.<p>
<a name="44670"></a>
<h2>12.5    Creation of New Class Instances</h2>
<a name="44671"></a>
A new class instance is explicitly created when one of the following situations 
occurs:
<p><ul><a name="44675"></a>
<li>Evaluation of a class instance creation expression <a href="15.doc.html#41147">(&#167;15.8)</a> creates a new instance of the class whose name appears in the expression.
<a name="44679"></a>
<li>Invocation of the <code>newInstance</code> method <a href="javalang.doc2.html#15088">(&#167;20.3.6)</a> of class <code>Class</code> creates a new instance of the class represented by the <code>Class</code> object for which the method was invoked.
</ul><a name="44680"></a>
A new class instance may be implicitly created in the following situations:
<p><ul><a name="44684"></a>
<li>Loading of a class or interface that contains a <code>String</code> literal <a href="3.doc.html#101083">(&#167;3.10.5)</a> may create a new <code>String</code> object <a href="javalang.doc11.html#14460">(&#167;20.12)</a> to represent that literal. (This might not occur if the same <code>String</code> has previously been interned <a href="3.doc.html#101083">(&#167;3.10.5)</a>.)
<a name="44691"></a>
<li>Execution of a string concatenation operator <a href="15.doc.html#39990">(&#167;15.17.1)</a> that is not part of a constant expression sometimes creates a new <code>String</code> object to represent the result. String concatenation operators may also create temporary wrapper objects for a value of a primitive type.
</ul><a name="44692"></a>
Each of these situations identifies a particular constructor to be called with specified
arguments (possibly none) as part of the class instance creation process.
<p><a name="44693"></a>
Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden. If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an <code>OutOfMemoryError</code>. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values <a href="4.doc.html#10931">(&#167;4.5.4)</a>. Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:<p>
<ol>
<a name="44697"></a>
<li>Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
<a name="44698"></a>
<li>If this constructor begins with an explicit constructor invocation of another constructor in the same class (using <code>this</code>), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
<a name="44699"></a>
<li>This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using <code>this</code>). If this constructor is for a class other than <code>Object</code>, then this constructor will begin with a explicit or implicit invocation of a superclass constructor (using <code>super</code>). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
<a name="44700"></a>
<li>Execute the instance variable initializers for this class, assigning their values to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5. (In some early Java implementations, the compiler incorrectly omitted the code to initialize a field if the field initializer expression was a constant expression whose value was equal to the default initialization value for its type.)
<a name="44701"></a>
<li>Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
</ol>
<a name="44702"></a>
In the example:
<p><pre><a name="44703"></a>
class Point {
<a name="44704"></a>	int x, y;
<a name="44705"></a>	Point() { x = 1; y = 1; }
<a name="44706"></a>}
<a name="44707"></a>
class ColoredPoint extends Point {
<a name="44708"></a>	int color = 0xFF00FF;
<a name="44709"></a>}
<a name="44710"></a>
class Test {
<a name="44711"></a>	public static void main(String[] args) {
<a name="44712"></a>		ColoredPoint cp = new ColoredPoint();
<a name="44713"></a>		System.out.println(cp.color);
<a name="44714"></a>	}
<a name="44715"></a>}
</pre><a name="44716"></a>
a new instance of <code>ColoredPoint</code> is created. First, space is allocated for the new 
<code>ColoredPoint</code>, to hold the fields <code>x</code>, <code>y</code>, and <code>color</code>. All these fields are then initialized
to their default values (in this case, <code>0</code> for each field). Next, the <code>ColoredPoint</code> 
constructor with no arguments is first invoked. Since <code>ColoredPoint</code> declares no 
constructors, a default constructor of the form:
<p><pre><a name="44717"></a>ColoredPoint() { super(); }
</pre><a name="44718"></a>
is provided for it automatically by the Java compiler.
<p><a name="44719"></a>
This constructor then invokes the <code>Point</code> constructor with no arguments. The <code>Point</code> constructor does not begin with an invocation of a constructor, so the compiler provides an implicit invocation of its superclass constructor of no arguments, as though it had been written:<p>
<pre><a name="44720"></a>Point() { super(); x = 1; y = 1; }
</pre><a name="44721"></a>
Therefore, the constructor for <code>Object</code> which takes no arguments is invoked.
<p><a name="46262"></a>
The class <code>Object</code> has no superclass, so the recursion terminates here. Next, any instance variable initializers and static initializers of <code>Object</code> are invoked. Next, the body of the constructor of <code>Object</code> that takes no arguments is executed. No such constructor is declared in <code>Object</code>, so the compiler supplies a default one, which in this special case is:<p>
<pre><a name="44722"></a>Object() { }
</pre><a name="44723"></a>
This constructor executes without effect and returns.
<p><a name="44724"></a>
Next, all initializers for the instance variables of class <code>Point</code> are executed. As it happens, the declarations of <code>x</code> and <code>y</code> do not provide any initialization expressions, so no action is required for this step of the example. Then the body of the <code>Point</code> constructor is executed, setting <code>x</code> to <code>1</code> and <code>y</code> to <code>1</code>.<p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -