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

📄 chap17.html

📁 Inside the java virtualMachine,深入研究java虚拟机
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- 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="chap16.html" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/venners/chap16.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>&nbsp;<A HREF="chap18.html" tppabs="http://www.pbg.mcgraw-hill.com/betabooks/venners/chap18.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>&copy; 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 Seventeen</H1></P>
<P><H2>Exceptions</H2></P>
<P>This chapter shows how exceptions are implemented in bytecodes. It describes the instruction for throwing an exception explicitly, explains exception tables, and shows how catch clauses work.</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>Play Ball!</I>, simulates the Java Virtual Machine executing a method that throws and catches exceptions. At the end of this chapter, you will find a description of this applet and the bytecodes it executes.</P>
<H3><EM><P>Throwing and Catching Exceptions</P>
</EM></H3><P>Exceptions allow you to smoothly handle unexpected conditions that occur as your programs run. To demonstrate the way the Java Virtual Machine handles exceptions, consider a class named <CODE>NitPickyMath</CODE> that provides methods that perform addition, subtraction, multiplication, division, and remainder on integers. <CODE>NitPickyMath</CODE> performs these mathematical operations the same as the normal operations offered by Java's <FONT FACE="Courier New">+</FONT>, <FONT FACE="Courier New">-</FONT>, <FONT FACE="Courier New">*</FONT>, <FONT FACE="Courier New">/</FONT>, and <FONT FACE="Courier New">%</FONT> operators, except the methods in <CODE>NitPickyMath</CODE> throw checked exceptions on overflow, underflow, and divide-by-zero conditions. The Java Virtual Machine will throw an <CODE>ArithmeticException</CODE> on an integer divide-by-zero, but will not throw any exceptions on overflow and underflow. The exceptions thrown by the methods of <CODE>NitPickyMath</CODE> are defined as follows: </P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file except/ex1/OverflowException.java
<P>class OverflowException extends Exception {</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></P>
<P></FONT><FONT FACE="Courier New">// On CD-ROM in file except/ex1/UnderflowException.java
<P>class UnderflowException extends Exception {</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></P>
<P></FONT><FONT FACE="Courier New">// On CD-ROM in file except/ex1/DivideByZeroException.java
<P>class DivideByZeroException extends Exception {</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>A simple method that catches and throws exceptions is the <CODE>remainder()</CODE> method of class <CODE>NitPickyMath</CODE>: </P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file except/ex1/NitpickyMath.java
<P>class NitpickyMath {</P>
<P>&nbsp;</P>
<P>    static int add(int a, int b)</P>
<P>        throws OverflowException, UnderflowException {</P>
<P>&nbsp;</P>
<P>        long longA = (long) a;</P>
<P>        long longB = (long) b;</P>
<P>        long result = a + b;</P>
<P>        if (result </FONT> Integer.MAX_VALUE) {</P>
<P>            throw new OverflowException();</P>
<P>        }</P>
<P>        if (result &lt; Integer.MIN_VALUE) {</P>
<P>            throw new UnderflowException();</P>
<P>        }</P>
<P>        return (int) result;</P>
<P>    }</P>
<P>&nbsp;</P>
<P>    static int subtract(int minuend, int subtrahend)</P>
<P>        throws OverflowException, UnderflowException {</P>
<P>&nbsp;</P>
<P>        long longMinuend = (long) minuend;</P>
<P>        long longSubtrahend = (long) subtrahend;</P>
<P>        long result = longMinuend - longSubtrahend;</P>
<P>        if (result </FONT> Integer.MAX_VALUE) {</P>
<P>            throw new OverflowException();</P>
<P>        }</P>
<P>        if (result &lt; Integer.MIN_VALUE) {</P>
<P>            throw new UnderflowException();</P>
<P>        }</P>
<P>        return (int) result;</P>
<P>    }</P>
<P>&nbsp;</P>
<P>    static int multiply(int a, int b)</P>
<P>        throws OverflowException, UnderflowException {</P>
<P>&nbsp;</P>
<P>        long longA = (long) a;</P>
<P>        long longB = (long) b;</P>
<P>        long result = a * b;</P>
<P>        if (result </FONT> Integer.MAX_VALUE) {</P>
<P>            throw new OverflowException();</P>
<P>        }</P>
<P>        if (result &lt; Integer.MIN_VALUE) {</P>
<P>            throw new UnderflowException();</P>
<P>        }</P>
<P>        return (int) result;</P>
<P>    }</P>
<P>&nbsp;</P>
<P>    static int divide(int dividend, int divisor)</P>
<P>        throws OverflowException, DivideByZeroException {</P>
<P>&nbsp;</P>
<P>        // Overflow can occur in division when dividing the</P>
<P>        // negative integer of the largest possible magnitude</P>
<P>        // (Integer.MIN_VALUE) by -1, because this would just flip</P>
<P>        // the sign, but there is no way to represent that number</P>
<P>        // in an int.</P>
<P>        if ((dividend == Integer.MIN_VALUE) &amp;&amp; (divisor == -1)) {</P>
<P>            throw new OverflowException();</P>
<P>        }</P>
<P>        try {</P>
<P>            return dividend / divisor;</P>
<P>        }</P>
<P>        catch (ArithmeticException e) {</P>
<P>            throw new DivideByZeroException();</P>
<P>        }</P>
<P>    }</P>
<P>&nbsp;</P>
<P>    static int remainder(int dividend, int divisor)</P>
<P>        throws OverflowException, DivideByZeroException {</P>
<P>&nbsp;</P>
<P>        // Overflow can occur in division when dividing the</P>
<P>        // negative integer of the largest possible magnitude</P>
<P>        // (Integer.MIN_VALUE) by -1, because this would just flip</P>
<P>        // the sign, but there is no way to represent that number</P>
<P>        // in an int.</P>
<P>        if ((dividend == Integer.MIN_VALUE) &amp;&amp; (divisor == -1)) {</P>
<P>            throw new OverflowException();</P>
<P>        }</P>
<P>        try {</P>
<P>            return dividend % divisor;</P>
<P>        }</P>
<P>        catch (ArithmeticException e) {</P>
<P>            throw new DivideByZeroException();</P>
<P>        }</P>
<P>    }</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>The <CODE>remainder()</CODE> method simply performs the remainder operation (<FONT FACE="Courier New">%</FONT>) upon the two <EM><FONT FACE="Courier New">ints</FONT></EM> passed as arguments. The remainder operation throws an <CODE>ArithmeticException</CODE> if the divisor of the remainder operation is a zero. This method catches this <CODE>ArithmeticException</CODE> and throws a <CODE>DivideByZeroException</CODE>. </P>
<P>The difference between these two exceptions is that <CODE>DivideByZeroException</CODE> is <EM>checked</EM> and <CODE>ArithmeticException</CODE> is <EM>unchecked</EM>. Because the <CODE>ArithmeticException</CODE> is unchecked, a method need not declare this exception in a <FONT FACE="Courier New">throws</FONT> clause even though it might throw it. Any exceptions that are subclasses of either <CODE>Error</CODE> or <CODE>RuntimeException</CODE> are unchecked. (<CODE>ArithmeticException</CODE> is a subclass of <CODE>RuntimeException</CODE>.) By catching <CODE>ArithmeticException</CODE> and then throwing <CODE>DivideByZeroException</CODE>, the <CODE>remainder()</CODE> method forces its clients to deal with the possibility of a divide-by-zero exception, either by catching it or declaring <CODE>DivideByZeroException</CODE> in their own <FONT FACE="Courier New">throws</FONT> clauses. </P>
<P><CODE>javac</CODE> generates the following bytecode sequence for the <CODE>remainder</CODE> method: </P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// The main bytecode sequence for remainder():
<P>&nbsp;</P>
<P> 0 iload_0  // Push local variable 0 (arg passed as dividend)</P>
<P>            // Push the minimum integer value</P>
<P> 1 ldc #1 &lt;Integer -2147483648</FONT></P>
<P>            // If the dividend isn't equal to the minimum integer,</P>
<P>            // jump to the remainder calculation</P>
<P> 3 if_icmpne 19</P>
<P>&nbsp;</P>
<P> 6 iload_1  // Push local variable 1 (arg passed as divisor)</P>
<P>            // Push -1</P>
<P> 7 iconst_m1</P>
<P>            // If the divisor isn't equal to -1, jump</P>
<P>            // to the remainder calculation</P>
<P> 8 if_icmpne 19</P>
<P>            // This is an overflow case, so throw an exception</P>
<P>            // Create a new OverflowException, push reference to</P>
<P>            // it onto the stack</P>
<P>11 new #4 &lt;Class OverflowException</FONT></P>
<P>14 dup      // Make a copy of the reference</P>
<P>            // Pop one copy of the reference and invoke the &lt;init</FONT></P>

⌨️ 快捷键说明

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