Java字节码缺少局部变量表

Java字节码缺少局部变量表,java,jvm,bytecode,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); descrip

当我检查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 公共同步void add(java.lang.Class,T); 描述符:(Ljava/lang/Class;Ljava/util/EventListener;)V 标志:ACC_公共,ACC_已同步 代码: 堆栈=5,局部变量=5,参数大小=3 0:aload_2 1:ifnonnull 5 4:返回 5:aload_1 6:aload_2 7:invokevirtual#133//方法java/lang/Class.isInstance:(Ljava/lang/Object;)Z ... 116:aload_0 117:aload 4 119:putfield#128//字段监听器列表:[Ljava/lang/Object; 122:返回 StackMapTable:条目数=4 框架类型=5/*相同*/ 框架类型=43/*相同*/ 框架类型=28/*相同*/ 框架类型=43/*相同*/ LineNumberTable: 第179行:0 第183行:4 第185行:5 第186行:13 ... 第200行:109 第202行:116 第204行:122 签名:#85/(Ljava/lang/Class;TT;)V 我们可以看到这个方法有两个局部变量,但是JDK字节码没有显示局部变量表,我的问题是:

  • 为什么要验证没有显式局部变量表的字节码
  • 当运行这样的字节码时,JVM如何获得起始PC、名称和签名

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


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

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

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

    来自
    javac--help

    -g Generate all debugging info
    
    如果你有一个类,比如说
    Temp.java
    ,那么:

    • javac-g Temp.java
    • javap-v Temp
    将在输出中为您提供
    LocalVariableTable

    PS:不确定如何处理内置类,如
    javax.swing.event.EventListenerList
    来自
    javac--help

    -g Generate all debugging info
    
    如果你有一个类,比如说
    Temp.java
    ,那么:

    • javac-g Temp.java
    • javap-v Temp
    将在输出中为您提供
    LocalVariableTable


    PS:不确定如何处理内置类,如
    javax.swing.event.EventListenerList

    请注意默认设置(
    -g
    )包括行号和源文件的名称,但不包括局部变量表。这是JDK类的编译方式。指定
    -g:none
    甚至会跳过行号(至少一些JRE以这种方式编译的类附带)。请注意默认设置(
    -g
    )包括行号和源文件的名称,但不包括局部变量表。这就是JDK类的编译方式。指定
    -g:none
    甚至会跳过行号(至少有些JRE是以这种方式编译的类附带的)。