依赖项存储在已编译的Java类中的哪个位置?

时间:2013-11-07 12:11:02

标签: java compilation dependencies .class-file

其中section of a compiled class是对存储的其他类(导入)的依赖关系,是否可以查看(使用编辑器或其他非编程方式)?

谢谢,

1 个答案:

答案 0 :(得分:2)

它存储在类的“常量池”中(以及其他所有内容,类和方法名称等)。

您可以使用javap以可读格式查看字节码。

请参阅Anton Arhipov's excellent blog on bytecode fundamentals

从课堂上取的一个例子:

public class Foo {
    private String bar;

    public String getBar(){ 
      return bar; 
    }
    ...

...产生字节码:

public java.lang.String getBar();
  Code:
   0:   aload_0
   1:   getfield        #2; //Field bar:Ljava/lang/String;
   4:   areturn

并且有持续的游泳池:

Compiled from "Foo.java"
public class Foo extends java.lang.Object
  SourceFile: "Foo.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #4.#17; //  java/lang/Object."<init>":()V
const #2 = Field        #3.#18; //  Foo.bar:Ljava/lang/String;
const #3 = class        #19;    //  Foo
const #4 = class        #20;    //  java/lang/Object
const #5 = Asciz        bar;
const #6 = Asciz        Ljava/lang/String;;
const #7 = Asciz        <init>
const #8 = Asciz        ()V;
const #9 = Asciz        Code;
const #10 = Asciz       LineNumberTable;
const #11 = Asciz       getBar;
const #12 = Asciz       ()Ljava/lang/String;;
const #13 = Asciz       setBar;
const #14 = Asciz       (Ljava/lang/String;)V;
const #15 = Asciz       SourceFile;
const #16 = Asciz       Foo.java;
const #17 = NameAndType #7:#8;//  "<init>":()V
const #18 = NameAndType #5:#6;//  bar:Ljava/lang/String;
const #19 = Asciz       Foo;
const #20 = Asciz       java/lang/Object;

您可以通过常量池跟踪StringFoo#getBar的引用:

  • getfield#2
  • 其中#2是Field,引用#3。#18
    • 其中#3引用了#19类
      • 是班级Foo
    • 和#18是引用#5和#6的NameAndType
      • 和#5是bar(field)
      • 和#6是对java.lang.String
      • 的引用

我强烈建议阅读Anton的博客。它真的做得很好!

我还阅读了James D. Bloom's JVM Internals article,因为它涵盖了很多JVM内部架构。当事情发生变化时,请注意引用的日期和版本(例如在java 8和String内联中使用java堆。