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

📄 compiling.doc.html

📁 一本关于java方面的书籍 英文html形式 关于Java虚拟机
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<a name="5962"></a>
Finally, <code>addTwo</code> is invoked. When it returns, its <code>int</code> return value is pushed onto the operand stack of the frame of the invoker, the <code>add12and13</code> method. The return value is thus put in place to be immediately returned to the invoker of <code>add12and13</code>. <p>
<a name="10439"></a>
The return from <code>add12and13</code> is handled by the <i>ireturn</i> instruction of <code>add12and13</code>. The <i>ireturn</i> instruction takes the <code>int</code> value returned by <code>addTwo</code>, on the operand stack of the current frame, and pushes it onto the operand stack of the frame of the invoker. It then returns control to the invoker, making the invoker's frame current. The Java Virtual Machine provides distinct return instructions for many of its numeric and <code>reference</code> data types, as well as a <i>return</i> instruction for methods with no return value. The same set of return instructions is used for all varieties of method invocations.<p>
<a name="10497"></a>
The operand of the <i>invokevirtual </i>instruction (in the example, the constant pool index <i>#4</i>) is not the offset of the method in the class instance. The Java compiler does not know the internal layout of a class instance. Instead, it generates symbolic references to the methods of an instance, which are stored in the constant pool. Those constant pool items are resolved at run time to determine the actual method location. The same is true for all other Java Virtual Machine instructions that access class instances.<p>
<a name="6012"></a>
Invoking <code>addTwoStatic</code>, a class (<code>static</code>) variant of <code>addTwo</code>, is similar:<p>
<pre><br><a name="8844"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>int add12and13() {
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>	return addTwoStatic(12, 13);
</code><a name="8846"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="8842"></a>
although a different Java Virtual Machine method invocation instruction is used:
<p><a name="8786"></a>
 <i>Method </i><code>int add12and13()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>bipush 12
</i><br><td>

<tr><td>          <i>   2 
</i><br><td>          <i>bipush 13
</i><br><td>

<tr><td>          <i>   4 
</i><br><td>          <i>invokestatic #3 
</i><br><td><i>// Method </i><code>Example.addTwoStatic(II)I
</code>
<tr><td>          <i>   7 
</i><br><td>          <i>ireturn
</i><br><td>

</Table><br><br></code><p>
<a name="8784"></a>
Compiling an invocation of a class (<code>static</code>) method is very much like compiling an 
invocation of an instance method, except <code>this</code> is not passed by the invoker. The 
method arguments will thus be received beginning with local variable <i>0</i> (see <a href="Compiling.doc.html#8556">Section 
7.6, "Receiving Arguments"</a>). The <i>invokestatic</i> instruction is always used to invoke 
class methods.
<p><a name="9398"></a>
The <i>invokespecial</i> instruction must be used to invoke instance initialization (<code>&lt;init&gt;</code>) methods (see <a href="Compiling.doc.html#4089">Section 7.8, "Working with Class Instances"</a>). It is also used when invoking methods in the superclass (<code>super</code>) and when invoking <code>private</code> methods. For instance, given classes <code>Near</code> and <code>Far</code> declared as<p>
<pre><br><a name="9433"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>class Near {
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>    	int it;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	public int getItNear() {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>		return getIt();
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	}
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>    	private int getIt() {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>		return it;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>    	}
</code><br><a name="9423"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br><a name="12879"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>class Far extends Near {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>    	int getItFar() {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>		return super.getItNear();
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>    	}
</code><a name="9427"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="9477"></a>
the method <code>Near.getItNear</code> (which invokes a <code>private</code> method) becomes
<p><a name="9478"></a>
 <i>Method </i><code>int</code> <code>getItNear()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>aload_0
</i><br><td>          
<br>
<tr><td>          <i>   1 
</i><br><td>          <i>invokespecial 
#5 
</i><br><td><i>// Method </i><code>Near.getIt()I
</code>
<tr><td>          <i>   4 
</i><br><td>          <i>ireturn
</i><br><td>          
<br>
</Table><br><br></code><p>
<a name="9407"></a>
The method <code>Far.getItFar</code> (which invokes a superclass method) becomes
<p><a name="9438"></a>
 <i>Method </i><code>int</code> <code>getItFar()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>aload_0
</i><br><td>

<tr><td>          <i>   1 
</i><br><td>          <i>invokespecial 
#4
</i><br><td><i>// Method </i><code>Near.getItNear()I
</code>
<tr><td>          <i>   4
</i><br><td>          <i>ireturn
</i><br><td>

</Table><br><br></code><p>
<pre><a name="25556"></a>&nbsp;&nbsp;&nbsp;&nbsp;<i>
</i><br></pre><a name="10459"></a>
Note that methods called using the <i>invokespecial</i> instruction always pass <code>this</code> to the 
invoked method as its first argument. As usual, it is received in local variable <i>0</i>.
<p><a name="4089"></a>
<hr><h2>7.8	 Working with Class Instances</h2>
<a name="4438"></a>
Java Virtual Machine class instances are created using the Java Virtual Machine's 
<i>new</i> instruction. Once the class instance has been created and its instance variables, 
including those of the class and all of its superclasses, have been initialized to their 
default values, an instance initialization method of the new class instance (<code>&lt;init&gt;</code>) is 
invoked. [Recall that at the level of the Java Virtual Machine, a constructor appears 
as a method with the special compiler-supplied name <code>&lt;init&gt;</code>. This special method is 
known as the instance initialization method <a href="Overview.doc.html#12174">(&#167;3.8)</a>. Multiple instance initialization 
methods, corresponding to multiple constructors, may exist for a given class.] For 
example:
<p><pre><br><a name="4445"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>Object create() {
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>	return new Object();
</code><a name="4448"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="4442"></a>
compiles to
<p><a name="7013"></a>
 <i>Method </i><code>java.lang.Object</code> <code>create()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>new #1 
</i><br><td><i>// Class java.lang.Object
</i>
<tr><td>          <i>   3 
</i><br><td>          <i>dup
</i><br><td><i>
</i>
<tr><td>          <i>   4 
</i><br><td>          <i>invokespecial 
#4 
</i><br><td><i>// Method java.lang.Object.&lt;init&gt;()V
</i>
<tr><td>          <i>   7 
</i><br><td>          <i>areturn
</i><br><td><i>
</i>
</Table><br><br></code><p>
<a name="4630"></a>
Class instances are passed and returned (as <code>reference</code> types) very much like numeric values, although type <code>reference</code> has its own complement of instructions:<p>
<pre><br><a name="7661"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>int i;					// An instance variable
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>MyObj example() {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	MyObj o = new MyObj();
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	return silly(o);
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>MyObj silly(MyObj o) {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	if (o != null) {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	    return o;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	} else {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	    return o;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	}
</code><a name="16770"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="16771"></a>
becomes
<p><a name="16899"></a>
 <i>Method </i><code>MyObj</code> <code>example()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>new #2 
</i><br><td><i>// Class MyObj
</i>
<tr><td>          <i>   3 
</i><br><td>          <i>dup
</i><br><td><i>
</i>
<tr><td>          <i>   4 
</i><br><td>          <i>invokespecial 
#5 
</i><br><td><i>// Method MyObj.&lt;init&gt;()V
</i>
<tr><td>          <i>   7 
</i><br><td>          <i>astore_1
</i><br><td><i>
</i>
<tr><td>          <i>   8 
</i><br><td>          <i>aload_0
</i><br><td><i>
</i>
<tr><td>          <i>   9 
</i><br><td>          <i>aload_1
</i><br><td><i>
</i>
<tr><td>          <i>  10 
</i><br><td>          <i>invokevirtual 
#4 
</i><br><td><i>
</i>
<tr><td>          <i>
</i><br><td>          <i>
</i><br><td><i>// Method Example.silly(LMyObj;)LMyObj;
</i>
<tr><td>          <i>  13 
</i><br><td>          <i>areturn
</i><br><td><i>
</i>
</Table><br><br></code><p>
<a name="7653"></a>
 <i>Method </i><code>MyObj</code> <code>silly(MyObj)<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>aload_1
</i><br>
<tr><td>          <i>   1 
</i><br><td>          <i>ifnull 6
</i><br>
<tr><td>          <i>   4
</i><br><td>          <i>aload_1
</i><br>
<tr><td>          <i>   5 
</i><br><td>          <i>areturn
</i><br>
<tr><td>          <i>   6 
</i><br><td>          <i>aload_1</i>
<br>
<tr><td>          <i>   7 
</i><br><td><a name="25574"></a>
<i>areturn</i><p>

</Table><br><br></code><p>
<a name="4716"></a>
The fields of a class instance (instance variables) are accessed using the <i>getfield</i> and <i>putfield</i> instructions. If <code>i</code> is an instance variable of type <code>int</code>, the methods <code>setIt</code> and <code>getIt,</code> defined as<p>
<pre><br><a name="4760"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>void setIt(int value) {
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>	i = value;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>int getIt() {
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	return i;
</code><a name="13220"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="13221"></a>
become
<p><a name="13222"></a>
 <i>Method </i><code>void</code> <code>setIt(int)<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>aload_0
</i><br><td><i>
</i>
<tr><td>          <i>   1 
</i><br><td>          <i>iload_1
</i><br><td><i>
</i>
<tr><td>          <i>   2 
</i><br><td>          <i>putfield #4 
</i><br><td><i>// Field Example.i I
</i>
<tr><td>          <i>   5
</i><br><td>          <i>return
</i><br><td><i>
</i>
</Table><br><br></code><p>
<pre><br><a name="4753"></a>&nbsp;&nbsp;&nbsp;&nbsp;<i>Method </i><code>int</code> <code>getIt()<p><Table Border="0">
<tr><td>          <i>   0 
</i><br><td>          <i>aload_0
</i><br><td><i>
</i>
<tr><td>          <i>   1 
</i><br><td>          <i>getfield #4 
</i><br><td><i>// Field Example.i I
</i>
<tr><td>          <i>   4
</i><br><td>          <i>ireturn
</i><br><td><i>
</i>
</Table><br><br>
</code></pre><a name="4719"></a>
As with the operands of method invocation instructions, the operands of the <i>putfield</i> 
and <i>getfield</i> instructions (the constant pool index <i>#4</i>) are not the offsets of the fields 
in the class instance. The Java compiler generates symbolic references to the fields 
of an instance, which are stored in the constant pool. Those constant pool items are 
resolved at run time to determine the actual field offset.
<p><a name="4091"></a>
<hr><h2>7.9	 Arrays</h2>
<a name="4816"></a>
Java Virtual Machine arrays are also objects. Arrays are created and manipulated 
using a distinct set of instructions. The <i>newarray</i> instruction is used to create an 
array of a numeric type. The &#32;code
<p><pre><br><a name="4872"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>void createBuffer() {
</code></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;<code>	int buffer[];
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	int bufsz = 100;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	int value = 12;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	buffer = new int[bufsz];
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	buffer[10] = value;
</code>&nbsp;&nbsp;&nbsp;&nbsp;<code>	value = buffer[11];
</code><a name="4879"></a>&nbsp;&nbsp;&nbsp;&nbsp;<code>}
</code><br></pre><a name="8889"></a>

⌨️ 快捷键说明

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