专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  监控系统选型,一篇全搞定! ·  12 小时前  
芋道源码  ·  新来个阿里 P7,仅花 2 ... ·  12 小时前  
芋道源码  ·  Hutool中的这些工具类,太实用了! ·  昨天  
Java编程精选  ·  看个文章隐私就被窃取了?3·15晚会曝光获客 ... ·  4 天前  
51好读  ›  专栏  ›  ImportNew

深入理解 Java HelloWorld

ImportNew  · 公众号  · Java  · 2017-04-03 11:49

正文

(点击 上方蓝字 ,快速关注我们)


作者:ImportNew - 黄飞飞

如有好文章投稿,请点击 → 这里了解详情


HelloWorld是每个Java程序员都知道的程序。它很简单,但是简单的开始可以引导你去深入了解更复杂的东西。这篇文章将探究从这个HelloWorld这个简单程序中可以学到的东西。如果你对HelloWorld有独到的理解,欢迎留下你的评论。


HelloWorld.java


public class HelloWorld {

/**

*

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.out.println("Hello World");

}

}


1、为什么一切都是从类开始?


Java程序是从类开始构建的, 每个方法和字段都必须在类里面。这是由于Java面向对象的特性: 一切都是对象,它是类的一个实例。面向对象编程语言相比函数式编程语言有许多的优势,比如更好的模块化、可扩展性等等。


2、为什么总有一个“main方法”?


main方法是程序的入口,并且是静态方法。static关键字意味着这个方法是类的一部分,而不是实例对象的一部分。为什么会这样呢? 为什么我们不用一个非静态的方法作为程序的入口呢?


如果一个方法不是静态的,那么对象需要先被创建好以后才能使用这个方法。因为这个方法必须要在一个对象上调用。对于一个入口来说,这是不现实的。因此,程序的入口方法是静态的。


参数 “String[] args”表明可以将一个字符串数组传递给程序来帮助程序初始化。


3、HelloWorld程序的字节码


为了执行这个程序,Java文件首先被编译成Java字节码存储到.class文件中。那么字节码看起来是什么样的呢?字节码本身是不可读的,如果我们使用一个二进制编辑器打开,它看起来就像下面那样:



在上面的字节码中,我们可以看到很多的操作码(比如CA、4C等等),它们中的每一个都有一个对应的助记码(比如下面例子中的aload_0)。操作码是不可读的,但是可以使用javap来查看.class文件的助记形式。


对于类中的每个方法执行“javap -c”可以输出反汇编代码。反汇编代码即组成Java字节码的指令。


javap -classpath .  -c HelloWorld


Compiled from "HelloWorld.java"

public class HelloWorld extends java.lang.Object{

public HelloWorld();

Code:

0:   aload_0

1:   invokespecial   #1; //Method java/lang/Object." ":()V

4:   return

public static void main(java.lang.String[]);

Code:

0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;

3:   ldc #3; //String Hello World

5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

8:   return

}


上面的代码包含两个方法: 一个是编译器推断出来的默认的构造器;另外一个是main方法。


接下来,每个方法都有一系列的指令。比如aload_0、invokespecial #1等等。可以在Java字节码指令集中查到每个指令的功能,例如aload_0用来从局部变量0中加载一个引用到堆栈,getstatic用来获取类的一个静态字段值。可以注意到,getstatic指令之后的“#2″指向的是运行期常量池。常量池是JVM运行时数据区之一。我们可以通过“javap -verbose”命令来查看常量池。


另外, 每个指令从一个数字开始,比如0、1、4等等。在.class文件中,每个方法都有一个对应的字节码数组。这些数字对应于存储每个操作码及其参数的数组的下标。每个操作码都是1个字节长度,并且指令可以有0个或多个参数。这就是为什么这些数字不是连续的原因。


现在,我们使用“javap -verbose”这个命令来进一步观察这个类。


javap -classpath . -verbose HelloWorld


Compiled from "HelloWorld.java"

public class HelloWorld extends java.lang.Object

SourceFile: "HelloWorld.java"

minor version: 0

major version: 50

Constant pool:

const #1 = Method   #6.#15; //  java/lang/Object." ":()V

const #2 = Field    #16.#17;    //  java/lang/System.out:Ljava/io/PrintStream;







请到「今天看啥」查看全文