![]() |
|||
![]() ![]() |
![]() |
![]()
|
![]() |
Exceptions thrown by a method The .class file also tells you which checked exceptions a method can throw. A checked exception is one that you must catch or declare in a throws clause. The exceptions declared in the throws clause of a method are an attribute of the method. The ExceptionsAttribute class, Listing 4-34, holds an array of indices into the constant pool, each of which points to a ClassInfo structure. The ClassInfo structure represents the class of the exception thats thrown. Listing 4-34 The ExceptionsAttribute class import java.io.*; public class ExceptionsAttribute { int nameIndex; int[] exceptions; public ExceptionsAttribute(AttributeInfo ai) throws IOException { nameIndex = ai.nameIndex(); ByteArrayInputStream bis = new ByteArrayInputStream(ai.data); DataInputStream dis = new DataInputStream(bis); exceptions = new int[dis.readUnsignedShort()]; for (int i = 0; i < exceptions.length; i++) { exceptions[i] = dis.readUnsignedShort(); } } public int nameIndex() { return nameIndex; } public int howMany() { return exceptions.length; } public int getIndex(int i) { return exceptions[i]; } public String toString() { return String.valueOf(nameIndex); } }
Listing 4-35 The getExceptions() method public String getExceptions(Method mi) { ExceptionsAttribute theExceptions=null; String result = ; // find the exceptions attribute AttributeInfo[] mAttributes = mi.getAttributes(); for (int i = 0; i < mAttributes.length; i++) { String name = thePool.readUTF8(mAttributes[i].nameIndex()); if (name.equals(Exceptions)) { try { theExceptions = new ExceptionsAttribute(mAttributes[i]); } catch (IOException e) { } break; } } if (theExceptions != null) { for (int i = 0; i < theExceptions.howMany(); i++) { if (i == 0) result += throws ; else result += , ; ClassInfo ci = thePool.readClassInfo(theExceptions.getIndex(i)); result += thePool.readUTF8(ci.nameIndex()).replace(/, .); } } return result; } The method body The one piece left is the code inside the methods. This is the one piece of a Java .class file that you cant easily make to match the source code. Thats because the Java source language in which you write programs is compiled to the much lower level byte code. In this chapter, I only show you where the bytes of the byte code are stored so that you can output them in a disassembly. The next chapter, however, discusses what those byte codes mean, how you can read and understand them, and how you can work backward from the byte codes to Java source code. The byte codes for each method are stored in a Code attribute for the method. The Code attribute has many different fields, but most of them are used only when interpreting code. In this chapter, you see only the actual byte codes. The constructor has more information to parse than you need immediately. The toString() method converts the signed bytes in the code array to integers between zero and 255. Listing 4-36 shows this CodeaAttribute class.
|
![]() |
|