Java语言的Hello World程序详细分析.docx

上传人:牧羊曲112 文档编号:3159723 上传时间:2023-03-11 格式:DOCX 页数:6 大小:39.23KB
返回 下载 相关 举报
Java语言的Hello World程序详细分析.docx_第1页
第1页 / 共6页
Java语言的Hello World程序详细分析.docx_第2页
第2页 / 共6页
Java语言的Hello World程序详细分析.docx_第3页
第3页 / 共6页
Java语言的Hello World程序详细分析.docx_第4页
第4页 / 共6页
Java语言的Hello World程序详细分析.docx_第5页
第5页 / 共6页
亲,该文档总共6页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Java语言的Hello World程序详细分析.docx》由会员分享,可在线阅读,更多相关《Java语言的Hello World程序详细分析.docx(6页珍藏版)》请在三一办公上搜索。

1、Java语言的Hello World程序详细分析Java语言的Hello World程序详细分析 HelloWorld.java public class HelloWorld /* * param args */ public static void main(String args) / TODO Auto-generated method stub System.out.println(Hello World); 这是每个Java程序员都知道的。虽然简单,但是从一个简单的问题可以引入更深的思考。在这篇文章中,我们将讨论这个简单的程序。 HelloWorld.java public cla

2、ss HelloWorld /* * param args */ public static void main(String args) / TODO Auto-generated method stub System.out.println(Hello World); 1、为什么一切都开始于一个类? Java程序是由类组成,一个类包含方法和属性。这是由于它的面向对象的特征:一切皆对象,每个对象都是一个类的实例。面向对象编程有很多优势,比如更好的模块化,扩展性强等 2、为什么总有一个“main”方法? “main”方法是程序的入口,它是静态的。 “static”是指该方法是类的一部分,而不是

3、对象的一部分。 这是为什么?我们为什么不把一个非静态方法作为程序的入口? 如果方法不是静态的,那么需要创建一个对象后才能使用方法。因为必须用对象去调用方法。对于程序的入口,这是不现实的。所以,程序的入口方法是静态的。 参数“String args”表示一个字符串数组可以被传入到该程序,用来初始化程序。 3、HelloWorld的字节码 执行这个程序,Java文件首先编译为java字节码储存在.class文件里。 字节码是什么样子的呢? 首先,字节码本身是无法读取。如果我们用一个十六进制编辑器打开,它看起来像下面这样: 我们能看到很多操作码在字节码上,它们每个都有一个相应的助记码。操作码是不可读

4、的,但我们可以用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

5、 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,invoke

6、special #1,等 下面的每个方法,也有说明,如aload_0,invokespecial1,等指令可以在java指令清单里查到。例如,aload_0指令是加载一个从栈中引用的本地变量0,getstatic 指令获取一个类的静态字段值。注意“2” 指令在getstatic指令后指向运行常量池。常量池是一个JVM运行时数据区,查看 。我们可以用“javap -verbose”命令来查看常量池。 此外,每个指令开始于一个数字,如0,1,4等。在.class文件中,每个方法都有一个对应的字节码数组。这些数字对应的每一个操作码和它的参数都存储在数组中的索引中。每个操作码为1个字节,指令可以有0个

7、或多个参数。这就是为什么数字是不连续的。 现在,我们可以用“javap -verbose” 查看.class文件进一步研究。 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/Obj

8、ect.:V const #2 = Field #16.#17; / java/lang/System.out:Ljava/io/PrintStream; const #3 = String #18; / Hello World const #4 = Method #19.#20; / java/io/PrintStream.println:(Ljava/lang/String;)V const #5 = class #21; / HelloWorld const #6 = class #22; / java/lang/Object const #7 = Asciz ; const #8 =

9、Asciz V; const #9 = Asciz Code; const #10 = Asciz LineNumberTable; const #11 = Asciz main; const #12 = Asciz (Ljava/lang/String;)V; const #13 = Asciz SourceFile; const #14 = Asciz HelloWorld.java; const #15 = NameAndType #7:#8;/ :V const #16 = class #23; / java/lang/System const #17 = NameAndType #2

10、4:#25;/ out:Ljava/io/PrintStream; const #18 = Asciz Hello World; const #19 = class #26; / java/io/PrintStream const #20 = NameAndType #27:#28;/ println:(Ljava/lang/String;)V const #21 = Asciz HelloWorld; const #22 = Asciz java/lang/Object; const #23 = Asciz java/lang/System; const #24 = Asciz out; c

11、onst #25 = Asciz Ljava/io/PrintStream; const #26 = Asciz java/io/PrintStream; const #27 = Asciz println; const #28 = Asciz (Ljava/lang/String;)V; public HelloWorld; Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; /Method java/lang/Object.:V 4: return LineNumberTable: line 2: 0 p

12、ublic static void main(java.lang.String); Code: Stack=2, Locals=1, Args_size=1 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 LineNumberTable: line 9: 0 line 10

13、: 8 JVM定义:运行常量池提供一个类似于传统的编程语言的符号表函数,尽管它包含了比典型的符号表范围更广的数据 “invokespecial #1指令指向#1常量在常量池中.常量是”Method #6.#15;“从数字上看,我们就可以按递归方式来得到最终的常量。 LineNumberTable提供用来调试java源代码对应字节码的行数信息例如,在main方法里Java源代码第9行对应字节码0,第10行对应字节码8。 如果你想知道更多关于字节码,您可以创建和编译一个更复杂的类来看一看。HelloWorld确实是个很简单的例子。 4、它是如何在JVM中执行? 现在的问题是如何JVM加载类并调用m

14、ain方法? 在main方法执行之前,JVM需要分三步走加载、连接以及初始化该类。1)加载二进制的类和接口到jvm中。 2)连接合并二进制数据到正在运行状态的jvm。连接有三步构成,验证、准备、解析。验证确保了类/接口在结构上正确的;准备工作包括所需要的类/接口分 配内存;解析符号引用。最后3)初始化变量并初始化值 这个装载工作是由Java类加载器完成的。当JVM启动时,3个类加载器被使用: 1.引导类加载器:加载位于/ jre / lib目录的核心Java库。这是jvm核心的一部分,并且是原生的代码。 2.扩展类加载器:加载代码的扩展目录。 3.系统类加载器:在CLASSPATH中找到负载代码。 所以HelloWorld类是由系统类加载器加载。当执行的主要方法,它会触发加载,链接和其他相关的类的初始化 ,如果它们存在。 最后,main的帧被加载到jvm堆栈,程序计数器被相应地设置。程序计数器然后指示println帧的加载到JVM堆栈。当main方法完成后,它会从堆栈中弹出执行完成。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号