📄 chap15.html
字号:
<P>The <FONT FACE="Courier New">multianewarray</FONT> instruction is used to allocate multidimensional arrays, which are simply arrays of arrays. A multidimensional array could alternatively be allocated with repeated use of the <FONT FACE="Courier New">anewarray</FONT> and <FONT FACE="Courier New">newarray</FONT> instructions. The <FONT FACE="Courier New">multianewarray</FONT> instruction simply compresses the bytecodes needed to create multidimensional arrays into one instruction. Two one-byte operands follow the <FONT FACE="Courier New">multianewarray</FONT> opcode and are combined to form an unsigned 16-bit index into the constant pool. A description of the class of object for which the array is to be created is found in the constant pool at the specified index. If it hasn韙 already, the virtual machine resolves the symbolic reference. Immediately following the two one-byte operands that form the constant pool index is an unsigned one-byte operand that specifies the number of dimensions in this multidimensional array. The sizes for each dimension are popped off the stack. This instruction allocates space for all arrays that are needed to implement the multidimensional arrays.</P>
<P>The constant pool entry referred to by a <FONT FACE="Courier New">multianewarray</FONT> instruction contains a <FONT FACE="Courier New">Constant_CLASS</FONT> entry with an array class name. For example, the constant pool entry for a four-dimensional array of float would have the name <FONT FACE="Courier New">"[[[[F"</FONT>. The class name in the constant pool entry may have more (but not less) left-brackets than indicated by the dimensions byte. The virtual machine always creates the number of dimensions specified by the dimensions byte.</P>
<P>Table 15-6. Creating new arrays</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">newarray</FONT></TD><TD VALIGN="TOP">atype</TD><TD VALIGN="TOP">pops length, allocates new array of primitive types of type indicated by atype, pushes objectref of new array</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">anewarray</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops length, allocates a new array of objects of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">multianewarray</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2, dimensions</TD><TD VALIGN="TOP">pops dimensions number of array lengths, allocates a new multidimensional array of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array</TD></TR>
</TABLE>
<P>Table 15-7 shows the <FONT FACE="Courier New">arraylength</FONT> instruction, which pops an array reference off the top of the stack and pushes the length of that array. </P>
<P>Table 15-7. Getting an array length</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">arraylength</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops objectref of an array, pushes length of that array</TD></TR>
</TABLE>
<P>The opcodes shown in Table 15-8 retrieve an element from an array. The array index and array reference are popped from the stack, and the value at the specified index of the specified array is pushed back onto the stack. The <FONT FACE="Courier New">baload</FONT> opcode converts the <FONT FACE="Courier New">byte</FONT> or <FONT FACE="Courier New">boolean</FONT> value to <FONT FACE="Courier New">int</FONT> by sign extending, then pushes the <FONT FACE="Courier New">int</FONT>. Likewise, the <FONT FACE="Courier New">saload</FONT> opcode converts the short value to <FONT FACE="Courier New">int</FONT> by sign extending, then pushes the <FONT FACE="Courier New">int</FONT>. The <FONT FACE="Courier New">caload</FONT> instruction converts the <FONT FACE="Courier New">char</FONT> to an <FONT FACE="Courier New">int</FONT> by zero-extending, then pushes the <FONT FACE="Courier New">int</FONT>.</P>
<P>Table 15-8. Retrieving an array element</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">baload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">byte</FONT>s or <FONT FACE="Courier New">boolean</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">caload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">char</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">saload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">short</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">iaload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">int</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">laload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">long</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">faload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">float</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">daload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of <FONT FACE="Courier New">double</FONT>s, pushes arrayref[index]</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">aaload</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops index and arrayref of an array of objectrefs, pushes arrayref[index]</TD></TR>
</TABLE>
<P>Table 15-9 shows the opcodes that store a value into an array element. The value, index, and array reference are popped from the top of the stack. The <FONT FACE="Courier New">bastore</FONT> instruction just stores the lower eight bits of the popped <FONT FACE="Courier New">int</FONT> value. The <FONT FACE="Courier New">sastore</FONT> and <FONT FACE="Courier New">castore</FONT> instructions just store the lower 16 bits of the popped <FONT FACE="Courier New">int</FONT> value.</P>
<P>Table 15-9. Storing to an array element</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">bastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">byte</FONT>s or <FONT FACE="Courier New">boolean</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">castore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">char</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">sastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">short</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">iastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">int</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">long</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">float</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of <FONT FACE="Courier New">double</FONT>s, assigns arrayref[index] = value</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">aastore</FONT></TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops value, index, and arrayref of an array of objectrefs, assigns arrayref[index] = value</TD></TR>
</TABLE>
<H3><EM><P>Three-Dimensional Array: A Simulation</P>
</EM></H3><P>The <I>Three-Dimensional Array</I> applet, shown in Figure 15-1, demonstrates a Java Virtual Machine executing a sequence of bytecodes. This applet is embedded in a web page on the CD-ROM in file <FONT FACE="Courier New">applets/ThreeDArray.html</FONT>.</P>
<P> The bytecode sequence in the simulation was generated by <CODE>javac</CODE> for the <CODE>initAnArray()</CODE> method of the class shown below: </P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file opcodes/ex1/ThreeDTree.java
<P>class ThreeDTree {</P>
<P> </P>
<P> static void initAnArray() {</P>
<P> </P>
<P> int[][][] threeD = new int[5][4][3];</P>
<P> </P>
<P> for (int i = 0; i < 5; ++i) {</P>
<P> for (int j = 0; j < 4; ++j) {</P>
<P> for (int k = 0; k < 3; ++k) {</P>
<P> threeD[i][j][k] = i + j + k;</P>
<P> }</P>
<P> }</P>
<P> }</P>
<P> }</P>
<P>}</P>
</FONT><FONT SIZE="2"><P> </P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>The bytecodes generated by <CODE>javac</CODE> for <CODE>initAnArray()</CODE> are shown below: </P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New"> 0 iconst_5 // Push constant int 5.
<P> 1 iconst_4 // Push constant int 4.</P>
<P> 2 iconst_3 // Push constant int 3.</P>
<P> 3 multianewarray #2 dim #3 <Class [[[I</FONT></P>
<P> // Create a new multi-dimensional array using</P>
<P> // constant pool entry #2 as the class (which</P>
<P> // is [[[I, an 3D array of ints) with a</P>
<P> // dimension of 3.</P>
<P> 7 astore_0 // Pop object ref into local variable 0:</P>
<P> // int threeD[][][] = new int[5][4][3];</P>
<P> 8 iconst_0 // Push constant int 0.</P>
<P> 9 istore_1 // Pop int into local variable 1: int i = 0;</P>
<P>10 goto 54 // Go to section of code that tests outer loop.</P>
<P>13 iconst_0 // Push constant int 0.</P>
<P>14 istore_2 // Pop int into local variable 2: int j = 0;</P>
<P>15 goto 46 // Go to section of code that tests middle loop.</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -