美文网首页请叫我程序员程序员Java 杂谈
当你写java helloworld时候,背后到底发生什么?

当你写java helloworld时候,背后到底发生什么?

作者: 三个米连 | 来源:发表于2017-09-13 11:14 被阅读94次

    每一个主要学过写代码的人,都知道helloworld是做什么的。而不同的程序与眼中的Helloworld深度和层次是不一样的,这篇文章让我们更加深度的解读一下java的helloworld背后的故事。

    为什么java的所有代码都是在类中?

    java的设计逻辑就是基于类来开发,所以所有的方法和类函数都是基于类来弹的。这和c++这门是有本质的区别的。一定程度上,这样的设计让JAVA面向对象的底蕴更加浓厚,所有的事务逻辑都应该是以类的某一个实例来出现。

    而面向对象相对于函数式的编程好处,可以说有很多,其中最为重要的则是模块化和拓展性。

    为什么main函数永远有一个static修饰符?

    main函数是程序运行的入口,static修饰符告诉我们,这个函数是属于类本身的一部分,而不是属于某一实例。

    那为什么我们一定要用static来作为一个程序入口呢? 可以不用吗?

    如果一个方法不是static的,那这个方法或者这个对象必须是先被创建才能被使用。而作为程序的入口,自然这是不合理的。就如同生鸡生蛋的问题,你什么都没有,没人可以做创建。所以static就是要让main方法是无需创建而直接可以调用的。

    String[] args是做什么用的?

    这些就是在命令行调用时候传入的参数,就如同ls -l -t后面的-l -t这些参数。都是为了初始化时候,将参数输入程序。

    HelloWorld的字节码长啥样?

    helloworld在执行前,会被编译成Java的字节码存储在.class文件中。字节码本身不可读,但是我们可以通过hex editor这样的工具来简单看到一些内容。

    在bytecode前几个字节码里,我们看到CA字符这样的opcode。这些叫做记忆码(不知道怎么翻译,mnemonic code)。这些记忆码是不可读的,但是我们可以通过javap命令里看看.class文件里的记忆码。

    javap -classpath . -c HelloWorld

    javap -c可以打印出程序的汇编代码,汇编代码也就是字节码的前一个阶段。

    这段汇编包含两个方法,一个是默认的构造器,这部分编译器自己做好的,另一个则是main函数。

    在每个方法下面则是一串执行的命令码,aload_o,invoke这样的命令。需要知道每个命令的含义,可以看java bytecode list在java的官网上有。

    简单介绍下,aload_o就是从本地变量o加载一个引用到栈上,getstatic则是拿到一个类的static的方法。

    那这些汇编左边的数字是什么呢?这些命令是存在一个数组中,每个命令占用的字节空间不一样,所以数字就不是连续的。

    这个.class文件是如何执行的呢?

    在main函数执行之前,JVM需要执行load, link, initialize这些工作。

    load: 就是要把class/interface的二进制码加载到JVM

    link: 将这些二进制数据放到JVM的run-time state

    initialize: 将变量初始化

    所有的工作做完之后,main函数就会被push到JVM栈中,程序计数器会设定到对应位置,开始执行程序。当所有程序执行完,JVM会将Helloworld pop出来,程序结束。

    相关文章

      网友评论

      本文标题:当你写java helloworld时候,背后到底发生什么?

      本文链接:https://www.haomeiwen.com/subject/zwyksxtx.html