1.java程序的编译

    ①编译器将源文件(*.java)编译成字节码文件( *.class)。

 

    java编译器会根据classpath路径找到对应的java文件(不存在,则报错),如果该类不依赖其他类,则直接将该类编译成.class文件,如若依赖其他类,

    依赖的类已编译,则直接引用,否则先编译被依赖的类,再编译本类 。

 

    编译后的字节码文件主要包括字节:常量池和方法字节码;

    常量池:存放 代码出现过的所有token(包名,类名,成员变量名等等)以及符号引用(方法引用,成员变量引用等等)。

    方法字节码: 存放类中各个方法的字节码。

 

  2.java程序的运行

    ②JVM虚拟机解释运行字节码文件

    (注意:JVM虚拟机只有在类第一次被使用的时候才会主动加载该类,而且只加载一次)

    例子:(运行A.java)

    

//B.java
public class B {
    private String name;
    B(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void say(){
           System.out.println("My name is "+name);
    }
}




//A.java
public class A {
    public static void main(String[] args){
        B b = new B();
     b.say();
    }
}

  

  a.JVM找到A.class后,把A的类信息加载到运行时数据区的方法区(A类的加载);

  b.JVM找到A类的main函数入口,开始执行main函数;

  c.new B()要创建一个B对象,但是这个时候方法区没有B类的信息,所以JVM类马上加载B类,把B的类信息放到方法区;

  d.JVM在堆区为B实例分配空间,B实例持有指向方法区B的类信息的引用;

  e.调用say()方法时,JVM根据b的引用找到B实例对象,再根据B实例的引用定位到方法区B类信息的方法表,获得say()的字节码地址;

  g.执行say()方法;

 

  参考资料: http://www.360doc.com/content/14/0218/23/9440338_353675002.shtml