📄 chap15.html
字号:
<!-- All material contained herein is copyright (c) McGraw-Hill Professional Books
All Rights Reserved. No use of this material may be made without express written
permission of the copyright holder. HTML conversions by Mega Space [barry@megaspace.com] -->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<TITLE>Understanding Digital Signatures: Inside the Java Virtual Machine
by Bill Venners - Beta Version</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<TABLE BORDER="0" WIDTH="100%">
<TR><TD><A HREF="http://www.pbg.mcgraw-hill.com/betabooks/stores.html" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/stores.html" target="bottom"><IMG SRC="hotkey.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/hotkey.gif" ALIGN="LEFT" BORDER="0" WIDTH="40" HEIGHT="40" ALT="Orders"></A>
<IMG SRC="order_text.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/order_text.gif" WIDTH="103" HEIGHT="41" ALT="Orders"></TD>
<TD ALIGN="RIGHT"><A HREF="chap14.html" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/venners/chap14.html"><IMG SRC="backward.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/backward.gif" BORDER="0" ALT="Backward" WIDTH="32" HEIGHT="32"></A> <A HREF="chap16.html" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/venners/chap16.html"><IMG SRC="forward.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/forward.gif" BORDER="0" ALT="Forward" WIDTH="32" HEIGHT="32"></A></TD></TR>
<TR><TD COLSPAN="2"><A HREF="mailto:computing@mcgraw-hill.com"><IMG SRC="hotkey.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/hotkey.gif" ALIGN="LEFT" BORDER="0" WIDTH="40" HEIGHT="40" ALT="Comments"></A>
<IMG SRC="comment_text.gif" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/images/comment_text.gif" WIDTH="73" HEIGHT="39" ALT="Comments"></TD></TR>
<TR><TD COLSPAN="2"><FONT FACE="ARIEL,HELVETICA" SIZE="-1"><I>© 1997 The McGraw-Hill Companies, Inc. All rights reserved. <BR>Any use of this Beta Book is subject to the rules stated in the <A HREF="http://www.mcgraw-hill.com/corporate/news_info/copyrttm.htm" tppabs="http://www.mcgraw-hill.com/corporate/news_info/copyrttm.htm" target="_top">Terms of Use</A>.</I></FONT><br>
<script language="javascript">
document.write("<a href='http://banners.linkbuddies.com/click.php?id=237296'><img src='http://banners.linkbuddies.com/image.php?id=237296&ref=" + document.referrer + "' width=468 height=60 alt='Click Here' border=0></a>");
</script></TD></TR>
</TABLE>
<HR>
<P><H1>Chapter Fifteen</H1></P>
<P><H2>Objects and Arrays</H2></P>
<P>This chapter describes the instructions that create and manipulate objects and arrays inside the Java Virtual Machine. All of these instructions involve the heap. Most of them refer to entries in the constant pool.</P>
<P>Accompanying this chapter on the CD-ROM is an applet that interactively illustrates the material presented in the chapter. The applet, named <I>Three-Dimensional Array</I>, simulates the Java Virtual Machine executing a method that allocates and initializes a three dimensional array. At the end of this chapter, you will find a description of this applet and the bytecodes it executes.</P>
<H3><EM><P>A Refresher on Objects and Arrays</P>
</EM></H3><P>As mentioned in earlier chapters, in the Java Virtual Machine, memory is allocated on the garbage-collected heap only as objects. There is no way to allocate memory for a primitive type on the heap, except as part of an object. If you want to use a primitive type where an <CODE>Object</CODE> reference is needed, you can allocate a wrapper object for the type from the <CODE>java.lang</CODE> package. For example, there is an <CODE>Integer</CODE> class that wraps an <CODE>int</CODE> type with an object. Only object references and primitive types can reside on the Java stack as local variables. Objects can never reside on the Java stack. </P>
<P>The architectural separation of objects and primitive types in the Java Virtual Machine is reflected in the Java programming language, in which objects cannot be declared as local variables--only object references and primitive types. Upon declaration, an object reference refers to nothing. Only after the reference has been explicitly initialized--either with a reference to an existing object or with a call to <CODE>new</CODE>--does the reference refer to an actual object. </P>
<P>In the Java Virtual Machine instruction set, all objects are instantiated and accessed with the same set of opcodes, except for arrays. As mentioned in earlier chapters, arrays in Java are full-fledged objects. Like any other Java object, arrays are created dynamically. Array references can be used anywhere a reference to type <CODE>Object</CODE> is called for, and any method of <CODE>Object</CODE> can be invoked on an array. Still, in the Java Virtual Machine, array operations are handled by special bytecodes. </P>
<P>As with any other object, arrays cannot be declared as local variables; only array references can. Array objects themselves always contain either an array of primitive types or an array of object references. If you declare an array of objects, you get an array of object references. The objects themselves must be explicitly created with <CODE>new</CODE> and assigned to the elements of the array. </P>
<H3><EM><P>Opcodes for Objects</P>
</EM></H3><P>Instantiation of new objects is accomplished via the <CODE>new</CODE> opcode, shown in Table 15-1. Two one-byte operands follow the <CODE>new</CODE> opcode. These two bytes are combined to form an unsigned 16-bit index into the constant pool. The constant pool entry at the specified offset gives information about the class of the new object. If it hasn韙 already, the virtual machine resolves the constant pool entry. It creates a new instance of the object on the heap, initializes the object韘 instance variables to default initial values, and pushes the reference to the new object onto the stack. </P>
<P>Table 15-1. Object creation</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">new</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">creates a new object on the heap, pushes reference</TD></TR>
</TABLE>
<P>Table 15-2 shows the opcodes that put and get object fields. These opcodes, <FONT FACE="Courier New">putfield</FONT> and <FONT FACE="Courier New">getfield</FONT>, operate only on fields that are instance variables. Static variables are accessed by <FONT FACE="Courier New">putstatic</FONT> and <FONT FACE="Courier New">getstatic</FONT>, which are described later. The <FONT FACE="Courier New">putfield</FONT> and <FONT FACE="Courier New">getfield</FONT> instructions each take two one-byte operands, which are combined to form an unsigned 16-bit index into the constant pool. The constant pool entry at that index contains information about the type, size, and offset of the field. If it hasn韙 already, the virtual machine resolves the constant pool entry. The object reference is taken from the stack in both the <FONT FACE="Courier New">putfield</FONT> and <FONT FACE="Courier New">getfield</FONT> instructions. The <FONT FACE="Courier New">putfield</FONT> instruction takes the instance variable value from the stack, and the <FONT FACE="Courier New">getfield</FONT> instruction pushes the retrieved instance variable value onto the stack. </P>
<P>Table 15-2. Accessing instance variables</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">putfield</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">set field, indicated by index, of object to value (both taken from stack)</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">getfield</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes field, indicated by index, of object (taken from stack)</TD></TR>
</TABLE>
<P>Class variables are accessed via the <FONT FACE="Courier New">getstatic</FONT> and <FONT FACE="Courier New">putstatic</FONT> opcodes, as shown in Table 15-3. Both <FONT FACE="Courier New">getstatic</FONT> and <FONT FACE="Courier New">putstatic</FONT> take two one-byte operands, which are combined by the Java Virtual Machine to form a 16-bit unsigned offset into the constant pool. The constant pool item at that location gives information about one static field of a class. If it hasn韙 already, the virtual machine resolves the constant pool entry. Because there is no particular object associated with a static field, there is no object reference used by either <FONT FACE="Courier New">getstatic</FONT> or <FONT FACE="Courier New">putstatic</FONT>. The <FONT FACE="Courier New">putstatic</FONT> instruction takes the value to assign from the stack. The <FONT FACE="Courier New">getstatic</FONT> instruction pushes the retrieved value onto the stack.</P>
<P>Table 15-3. Accessing class variables</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">putstatic</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">set field, indicated by index, of object to value (both taken from stack)</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">getstatic</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes field, indicated by index, of object (taken from stack)</TD></TR>
</TABLE>
<P>The following opcodes check to see whether the object reference on the top of the stack refers to an instance of the class or interface indexed by the operands following the opcode. In both cases, the virtual machine forms an unsigned 16-bit index into the constant pool from the two bytes that follow the opcode. If it hasn韙 already, the virtual machine resolves the constant pool entry.</P>
<P>The <FONT FACE="Courier New">checkcast</FONT> instruction throws <CODE>CheckCastException</CODE> if the object is not an instance of the specified class or interface. Otherwise, <FONT FACE="Courier New">checkcast</FONT> does nothing. The object reference remains on the stack and execution is continued at the next instruction. This instruction ensures that casts are safe at run time and forms part of the Java Virtual Machine's security blanket. </P>
<P>The <FONT FACE="Courier New">instanceof</FONT> instruction, shown in Table 15-4, pops the object reference from the top of the stack and pushes true or false. If the object is indeed an instance of the specified class or interface, then true is pushed onto the stack, otherwise, false is pushed onto the stack. The <FONT FACE="Courier New">instanceof</FONT> instruction is used to implement the <CODE>instanceof</CODE> keyword of the Java language , which allows you to test whether an object is an instance of a particular class or interface. </P>
<P>Table 15-4. Type checking</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">checkcast</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">Throws <FONT FACE="Courier New">ClassCastException</FONT> if objectref on stack cannot be cast to class at index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">instanceof</FONT></TD><TD VALIGN="TOP">indexbyte1, indexbyte2</TD><TD VALIGN="TOP">Pushes <FONT FACE="Courier New">true</FONT> if objectref on stack is an instance of class at index, else pushes <FONT FACE="Courier New">false</FONT></TD></TR>
</TABLE>
<H3><EM><P>Opcodes for Arrays</P>
</EM></H3><P>Instantiation of new arrays is accomplished via the <FONT FACE="Courier New">newarray</FONT>, <FONT FACE="Courier New">anewarray</FONT>, and <FONT FACE="Courier New">multianewarray</FONT> opcodes, shown in Table 15-6. The <FONT FACE="Courier New">newarray</FONT> opcode is used to create arrays of primitive types other than object references. The particular primitive type is specified by a single one-byte operand, the "atype," following the <FONT FACE="Courier New">newarray</FONT> opcode. The <FONT FACE="Courier New">newarray</FONT> instruction can create arrays for <FONT FACE="Courier New">byte</FONT>, <FONT FACE="Courier New">short</FONT>, <FONT FACE="Courier New">char</FONT>, <FONT FACE="Courier New">int</FONT>, <FONT FACE="Courier New">long</FONT>, <FONT FACE="Courier New">float</FONT>, <FONT FACE="Courier New">double</FONT>, or <FONT FACE="Courier New">boolean</FONT>. Table 15-5 shows the legal values for atype and the corresponding array types.</P>
<P>Table 15-5. Values for atype</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Array Type</STRONG></TD><TD VALIGN="TOP"><STRONG>atype</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_BOOLEAN</FONT></TD><TD VALIGN="TOP">4</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_CHAR</FONT></TD><TD VALIGN="TOP">5</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_FLOAT</FONT></TD><TD VALIGN="TOP">6</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_DOUBLE</FONT></TD><TD VALIGN="TOP">7</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_BYTE</FONT></TD><TD VALIGN="TOP">8</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_SHORT</FONT></TD><TD VALIGN="TOP">9</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_INT</FONT></TD><TD VALIGN="TOP">10</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">T_LONG</FONT></TD><TD VALIGN="TOP">11</TD></TR>
</TABLE>
<P>Note that the instructions that create arrays is one place in the Java Virtual Machine where <FONT FACE="Courier New">boolean</FONT> values are referred to explicitly. This enables implementations, especially those that must operate under constrained memory requirements, to compress arrays of <FONT FACE="Courier New">boolean</FONT> values into bit maps. In such a representation, each <FONT FACE="Courier New">boolean</FONT> element of an array would be represented by one bit. On implementations that have more memory available, <FONT FACE="Courier New">boolean</FONT> arrays may instead be implemented as arrays of <FONT FACE="Courier New">byte</FONT>s. This representation would likely yield better performance than a bit map approach, though it would consume more memory. No matter what internal implementation a particular virtual machine uses for <FONT FACE="Courier New">boolean</FONT> arrays, the elements of a <FONT FACE="Courier New">boolean</FONT> array are accessed with the same opcodes used to access <FONT FACE="Courier New">byte</FONT> arrays. These opcodes are described later in this chapter.</P>
<P>The <FONT FACE="Courier New">anewarray</FONT> instruction creates an array of object references. Two one-byte operands follow the <FONT FACE="Courier New">anewarray</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 constant pool entry. This instruction allocates space for the array of object references and initializes the references to null. </P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -