Java字节代码缺少局部变量表

时间:2018-01-07 06:28:48

标签: java jvm bytecode

当我检查JDK1.7的字节代码时,我发现rt.jar中某些Java类(例如javax.swing.event.EventListenerList)的字节代码不包含局部变量表。例如,我使用javap -v -p -l EventListenerList.class命令并获得add方法的字节代码,如:

public synchronized <T extends java.util.EventListener> void add(java.lang.Class<T>, T);
descriptor: (Ljava/lang/Class;Ljava/util/EventListener;)V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
  stack=5, locals=5, args_size=3
     0: aload_2
     1: ifnonnull     5
     4: return
     5: aload_1
     6: aload_2
     7: invokevirtual #133                // Method java/lang/Class.isInstance:(Ljava/lang/Object;)Z
    ...
   116: aload_0
   117: aload         4
   119: putfield      #128                // Field listenerList:[Ljava/lang/Object;
   122: return
  StackMapTable: number_of_entries = 4
    frame_type = 5 /* same */
    frame_type = 43 /* same */
    frame_type = 28 /* same */
    frame_type = 43 /* same */
  LineNumberTable:
    line 179: 0
    line 183: 4
    line 185: 5
    line 186: 13
    ...
    line 200: 109
    line 202: 116
    line 204: 122
Signature: #85                          // <T::Ljava/util/EventListener;>(Ljava/lang/Class<TT;>;TT;)V

我们可以看到该方法有两个局部变量,但JDK字节码不显示局部变量表。我的问题是:

  1. 为什么没有显式局部变量表的字节代码被验证?
  2. JVM如何在运行此类字节代码时获取启动PC,名称和签名?

2 个答案:

答案 0 :(得分:4)

局部变量表仅用于调试目的 - 它对字节码的执行没有任何直接影响。您可以通过传递-g:none告诉javac将它们遗漏。

至于第二个问题,它没有。 JVM并不关心您在源代码级别声明的变量 - 它看到的只是在字节码中传递的值。

答案 1 :(得分:0)

来自javac --help

-g Generate all debugging info

如果你有一个班级说Temp.java,那么:

  • javac -g Temp.java
  • javap -v Temp

会在输出中给你 LocalVariableTable

PS:不知道如何处理像 javax.swing.event.EventListenerList

这样的内置类