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

📄 compiling.doc.html

📁 java虚拟机规范
💻 HTML
📖 第 1 页 / 共 5 页
字号:
</code><code>    Thread threads[];</code><code>    int count = 10;</code><code>    threads = new Thread[count];</code><code>    threads[0] = new Thread();</code><code>}</code></pre></blockquote>becomes<p><blockquote><pre>Method <code>void createThreadArray()</code>   0 	bipush 10			// Push <code>int</code> constant <code>10</code>   2 	istore_2			// Initialize <code>count</code> to that   3 	iload_2				// Push <code>count</code>, used by anewarray   4 	anewarray class #1 		// Create new array of class <code>Thread</code>   7 	astore_1			// Store new array in <code>threads</code>   8 	aload_1				// Push value of <code>threads</code>   9 	iconst_0			// Push <code>int</code> constant <code>0</code>  10 	new #1 				// Create instance of class <code>Thread</code>  13 	dup				// Make duplicate reference...  14 	invokespecial #5 		// ...to pass to instance initialization method					// Method <code>java.lang.Thread.&lt;init&gt;()V</code>  17 	aastore				// Store new <code>Thread</code> in array at <code>0</code>  18 	return</pre></blockquote><a name="5674"></a>The anewarray instruction can also be used to create the first dimension of a multidimensional array. Alternatively, the multianewarray instruction can be used to create several dimensions at once. For example, the three-dimensional array:<p><blockquote><pre><code>int[][][] create3DArray() {</code><code>    int grid[][][];</code><code>    grid = new int[10][5][];</code><code>    return grid;</code><code>}</code></pre></blockquote>is created by<p><blockquote><pre>Method <code>int</code> <code>create3DArray()[][][]</code>   0 	bipush 10			// Push <code>int</code> <code>10</code> (dimension one)   2 	iconst_5			// Push <code>int</code> <code>5</code> (dimension two)   3 	multianewarray #1 dim #2 	// Class <code>[[[I</code>, a three					// dimensional <code>int</code> array;					// only create first two 					// dimensions   7 	astore_1			// Store new array...   8 	aload_1				// ...then prepare to return it   9 	areturn</pre></blockquote>The first operand of the multianewarray instruction is the runtime constant pool index to the array class type to be created. The second is the number of dimensions of that array type to actually create. The multianewarray instruction can be used to create all the dimensions of the type, as the code for <code>create3DArray</code> shows. Note that the multidimensionalarray is just an object and so is loaded and returned by an aload_1 and areturn instruction, respectively. For information about array class names, see <a href="ClassFile.doc.html#1221">Section 4.4.1</a>.<p><a name="14939"></a>All arrays have associated lengths, which are accessed via the arraylength instruction.<p><a name="14942"></a><hr><h2>7.10    Compiling Switches</h2>Compilation of <code>switch</code> statements uses the tableswitch and lookupswitch instructions.The tableswitch instruction is used when the cases of the <code>switch</code> can be efficientlyrepresented as indices into a table of target offsets. The <code>default</code> target of the <code>switch</code> is used if the value of the expression of the <code>switch</code> falls outside the range of valid indices. For instance,<p><blockquote><pre><code>int chooseNear(int i) {</code><code>    switch (i) {</code><code>        case 0:  return 0;</code><code>        case 1:  return 1;</code><code>        case 2:  return 2;</code><code>        default: return -1;</code><code>    }</code><code>}</code></pre></blockquote>compiles to<p><blockquote><pre>Method <code>int</code> <code>chooseNear(int)</code>   0	iload_1				// Push local variable 1 (argument <code>i</code>)   1 	tableswitch 0 to 2: 		// Valid indices are 0 through 2		0: 28			// If <code>i</code> is <code>0</code>, continue at 28	 	1: 30			// If <code>i</code> is <code>1</code>, continue at 30	 	2: 32			// If <code>i</code> is <code>2</code>, continue at 32		default:34		// Otherwise, continue at 34  28 	iconst_0			// <code>i</code> was <code>0</code>; push <code>int</code> constant <code>0</code>...  29 	ireturn				// ...and return it  30 	iconst_1			// <code>i</code> was <code>1</code>; push <code>int</code> constant <code>1</code>...  31 	ireturn				// ...and return it  32 	iconst_2			// <code>i</code> was <code>2</code>; push <code>int</code> constant <code>2</code>...  33 	ireturn				// ...and return it  34 	iconst_m1			// otherwise push <code>int</code> constant -<code>1</code>...  35 	ireturn				// ...and return it</pre></blockquote><a name="7459"></a>The Java virtual machine's tableswitch and lookupswitch instructions operate only on <code>int</code> data. Because operations on <code>byte</code>, <code>char</code>, or <code>short</code> values are internally promoted to <code>int</code>, a <code>switch</code> whose expression evaluates to one of those types is compiled as though it evaluated to type <code>int</code>. If the <code>chooseNear</code> method had been written using type <code>short</code>, the same Java virtual machine instructions would have been generated as when using type <code>int</code>. Other numeric types must be narrowed to type <code>int</code> for use in a <code>switch</code>.<p><a name="7490"></a>Where the cases of the <code>switch</code> are sparse, the table representation of the tableswitch instruction becomes inefficient in terms of space. The lookupswitch instruction may be used instead. The lookupswitch instruction pairs <code>int</code> keys (the values of the <code>case</code> labels) with target offsets in a table. When a lookupswitch instruction is executed, the value of the expression of the <code>switch</code> is compared against the keys in the table. If one of the keys matches the value of the expression, execution continues at the associated target offset. If no key matches, execution continues at the <code>default</code> target. For instance, the compiled code for<p><blockquote><pre><code>int chooseFar(int i) {</code><code>    switch (i) {</code><code>        case -100: return -1;</code><code>        case 0:	   return 0;</code><code>        case 100:  return 1;</code><code>        default:   return -1;</code><code>    }</code><code>}</code></pre></blockquote>looks just like the code for <code>chooseNear</code>, except for the use of the lookupswitch instruction:<p><blockquote><pre>Method <code>int</code> <code>chooseFar(int)</code>   0 	iload_1   1 	lookupswitch 3: 	 	-100: 36	 	0: 38	 	100: 40	 	default:42  36 	iconst_m1  37 	ireturn  38 	iconst_0  39 	ireturn  40 	iconst_1  41	ireturn  42 	iconst_m1  43 	ireturn</pre></blockquote><a name="14885"></a>The Java virtual machine specifies that the table of the lookupswitch instruction must be sorted by key so that implementations may use searches more efficient than a linear scan. Even so, the lookupswitch instruction must search its keys for a match rather than simply perform a bounds check and index into a table like tableswitch. Thus, a tableswitch instruction is probably more efficient than a lookupswitch where space considerations permit a choice. <p><a name="14892"></a><hr><h2>7.11    Operations on the Operand Stack</h2>The Java virtual machine has a large complement of instructions that manipulate the contents of the operand stack as untyped values. These are useful because of the Java virtual machine's reliance on deft manipulation of its operand stack. For instance,<p><blockquote><pre><code>public long nextIndex() { </code><code>    return index++;</code><code>}</code><code>private long index = 0;</code></pre></blockquote>is compiled to<p><blockquote><pre>Method <code>long nextIndex()</code>   0 	aload_0			// Push <code>this</code>   1 	dup			// Make a copy of it   2 	getfield #4 		// One of the copies of <code>this</code> is consumed				// pushing <code>long</code> field <code>index</code>,				// above the original <code>this</code>   5 	dup2_x1			// The <code>long</code> on top of the operand stack is 				// inserted into the operand stack below the 				// original <code>this</code>   6 	lconst_1		// Push <code>long</code> constant 1    7 	ladd			// The index value is incremented...   8 	putfield #4 		// ...and the result stored back in the field  11 	lreturn			// The original value of <code>index</code> is left on				// top of the operand stack, ready to be returned</pre></blockquote>Note that the Java virtual machine never allows its operand stack manipulation instructions to modify or break up individual values on the operand stack.<p><a name="9934"></a><hr><h2>7.12    Throwing and Handling Exceptions</h2>Exceptions&#32;are thrown from programs using the <code>throw</code> keyword. Its compilation is simple:<p><blockquote><pre><code>void cantBeZero(int i) throws TestExc {</code><code>    if (i == 0) {</code><code>        throw new TestExc();</code><code>    }</code><code>}</code></pre></blockquote>becomes<p><blockquote><pre>Method <code>void</code> <code>cantBeZero(int)</code>   0 	iload_1				// Push argument 1 (<code>i</code>)   1	ifne 12				// If <code>i==0</code>, allocate instance and throw   4	new #1 				// Create instance of <code>TestExc</code>   7 	dup				// One reference goes to the constructor   8 	invokespecial #7 		// Method <code>TestExc.&lt;init&gt;()V</code>  11 	athrow				// Second reference is thrown  12 	return				// Never get here if we threw <code>TestExc</code></pre></blockquote><a name="7996"></a>Compilation of <code>try</code>-<code>catch</code> constructs is straightforward. For example,<p><blockquote><pre><code>void catchOne() {</code><code>    try {</code><code>        tryItOut();</code><code>    } catch (TestExc e) {</code><code>        handleExc(e);</code><code>    }</code><code>}</code></pre></blockquote>is compiled as<p><blockquote><pre>Method <code>void</code> <code>catchOne()</code>   0 	aload_0				// Beginning of <code>try</code> block   1 	invokevirtual #6 		// Method <code>Example.tryItOut()V</code>   4 	return				// End of <code>try</code> block; normal return   5 	astore_1			// Store thrown value in local variable 1   6 	aload_0				// Push <code>this</code>   7 	aload_1				// Push thrown value   8 	invokevirtual #5 		// Invoke handler method: 					// <code>Example.handleExc(LTestExc;)V</code>  11 	return				// Return after handling <code>TestExc</code>Exception table:   	From 	To 	Target 		Type     	0     	4     	5 		Class <code>TestExc</code></pre></blockquote>Looking more closely, the <code>try</code> block is compiled just as it would be if the <code>try</code> were not present:<p><blockquote><pre>Method <code>void</code> <code>catchOne()</code>   0	aload_0				// Beginning of <code>try</code> block   1 	invokevirtual #4 		// Method <code>Example.tryItOut()V</code>   4 	return				// End of <code>try</code> block; normal return</pre></blockquote>If no exception is thrown during the execution of the <code>try</code> block, it behaves as though the <code>try</code> were not there: <code>tryItOut</code> is invoked and <code>catchOne</code> returns. <p><a name="8894"></a>Following the <code>try</code> block is the Java virtual machine code that implements the single <code>catch</code> clause:<p><blockquote><pre>   5 	astore_1			// Store thrown value in local variable 1   6 	aload_0				// Push <code>this</code>    7 	aload_1				// Push thrown value   8 	invokevirtual #5 		// Invoke handler method: 

⌨️ 快捷键说明

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