下面的表格給出了字節碼表達式的幾個實例。
表二:Java字節碼表達式范例
Java Code | Java Bytecode Expression |
double d[ ][ ][ ]; | [[[D |
Object mymethod(int I, double d, Thread t) | (IDLjava/lang/Thread;)Ljava/lang/Object; |
想了解更多細節的話,參考《The java Virtual Machine Specification,第二版》中的“4.3 Descriptors"。想了解更多的Java字節碼的指令的話,參考《The Java Virtual Machined Instruction Set》的“6.The Java Virtual Machine Instruction Set"
Class文件格式
在講解Java class文件格式之前,我們先看看一個在Java Web應用中經常出現的問題。
現象
當我們編寫完jsp代碼,并且在Tomcat運行時,Jsp代碼沒有正常運行,而是出現了下面的錯誤。
1
2
|
Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException: Unable to compile class for JSP Generated servlet error: The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit" |
原因
在不同的Web服務器上,上面的錯誤信息可能會有點不同,不過有有一點肯定是相同的,它出現的原因是65535字節的限制。這個65535字節的限制是JVM規范里的限制,它規定了一個方法的大小不能超過65535字節。
下面我會更加詳細地講解這個65535字節限制的意義以及它出現的原因。
Java字節碼里的分支和跳轉指令分別是”goto"和"jsr"。
1
2
|
goto [branchbyte1] [branchbyte2] jsr [branchbyte1] [branchbyte2] |
這兩個指令都接收一個2字節的有符號的分支跳轉偏移量做為操作數,因此偏移量最大只能達到65535。不過,為了支持更多的跳轉,Java字節碼提供了"goto_w"和"jsr_w"這兩個可以接收4字節分支偏移的指令。
1
2
|
goto_w [branchbyte1] [branchbyte2] [branchbyte3] [branchbyte4] jsr_w [branchbyte1] [branchbyte2] [branchbyte3] [branchbyte4] |
有了這兩個指令,索引超過65535的分支也是可用的。因此,Java方法的65535字節的限制就可以解除了。不過,由于Java class文件的更多的其他的限制,使得Java方法還是不能超過65535字節。
為了展示其他的限制,我會簡單講解一下class 文件的格式。
Java class文件的大致結構如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count- 1 ]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count];} |
原文轉自:http://www.anti-gravitydesign.com