首页 > 编程语言 >Java程序启动“Hello, World!”详细分析

Java程序启动“Hello, World!”详细分析

时间:2024-10-23 19:51:19浏览次数:10  
标签:Java 字节 HelloWorld JVM World main Hello

在这里插入图片描述
在Java编程世界中,“Hello, World!”程序是学习旅程的起点。这个程序虽然简单,但它展示了Java程序的基本结构和从编写到运行的全过程。下面,我们将详细分析如何启动一个Java程序并输出“Hello, World!”。

一. 编写Java源代码

首先,我们需要编写一个包含main方法的Java类。main方法是Java程序的入口点,程序从这里开始执行。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

在这个例子中,我们定义了一个名为HelloWorld的公共类,并在其中定义了一个main方法。main方法接受一个字符串数组作为参数,这是Java程序的标准入口格式。在方法体内,我们使用System.out.println方法输出字符串“Hello, World!”。

二. 编译Java源代码

在编写完源代码后,我们需要使用Java编译器(javac)将其编译成字节码。字节码是Java虚拟机(JVM)可以执行的中间代码。

在命令行中,导航到保存HelloWorld.java文件的目录,并运行以下命令:

javac HelloWorld.java

如果编译成功,编译器将生成一个名为HelloWorld.class的文件,其中包含Java虚拟机可以执行的字节码。
为了查看生成的字节码,我们可以使用javap工具,它是Java SDK提供的一个反汇编器,可以将字节码转换回一种更易于阅读的格式(称为“Java汇编语言”或“Java字节码”)。

运行以下命令来查看HelloWorld.class的字节码:

javap -c HelloWorld

输出可能类似于以下内容(具体输出可能会因Java版本和编译器优化而有所不同):

Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()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
}

这里是对输出的解释:

  • HelloWorld类有两个方法:一个是构造函数HelloWorld(),另一个是main方法。
  • 构造函数HelloWorld()调用了父类Object的构造函数。
  • main方法首先获取System.out的引用(一个PrintStream对象),然后加载字符串"Hello, World!",接着调用PrintStreamprintln方法打印该字符串,最后返回。

字节码指令如aload_0invokespecialgetstaticldcinvokevirtualreturn是JVM执行引擎能够理解的低级指令。这些指令告诉JVM如何操作栈、局部变量表、方法区等内存结构。

三. 运行Java程序

接下来,我们使用Java解释器(java)来运行编译后的字节码。注意,在运行时,我们不需要指定.class扩展名。

在命令行中,运行以下命令:

java HelloWorld

Java解释器将加载HelloWorld.class文件,启动JVM,并执行main方法。最终,你将在控制台中看到输出:

Hello, World!

接下来,我们使用Java解释器(实际上是一个启动JVM的命令)来运行编译后的字节码。

在这里插入图片描述

这个流程图简洁地表示了从编写Java源代码到运行程序并输出结果的整个过程,包括编译、加载类、链接、初始化、调用main方法、执行字节码指令和输出结果等关键步骤。做了以下几件事情:

  1. 启动JVMjava命令负责启动Java虚拟机。JVM是Java程序的运行环境,它提供了内存管理、垃圾回收、安全控制等核心功能。

  2. 加载类:JVM首先加载HelloWorld类。这涉及到从类路径中找到HelloWorld.class文件,并将其内容读入内存。然后,JVM会验证类文件的格式,确保它符合Java类文件的规范。

  3. 链接:加载类后,JVM会进行链接过程。这包括将类中的符号引用解析为直接引用(例如,将方法调用解析为具体的方法地址)。链接过程还包括准备类的静态变量,但此时不会执行静态初始化代码。

  4. 初始化:在链接之后,如果类还没有被初始化(即,这是第一次加载该类),JVM将执行类的初始化阶段。这包括执行静态代码块和静态变量的初始化。对于HelloWorld类来说,这个阶段没有特别的初始化代码要执行,因为所有的静态变量都是默认初始化的,并且没有静态代码块。

  5. 调用main方法:一旦类被加载、链接和初始化,JVM就会调用HelloWorld类的main方法。这是程序的入口点,所有Java程序都从这里开始执行。

  6. 执行字节码:在main方法内部,JVM一行一行地执行字节码指令。例如,getstatic指令将System.out的引用推入操作栈,ldc指令将字符串"Hello, World!"的引用推入操作栈,invokevirtual指令调用PrintStreamprintln方法,并将操作栈顶的两个引用作为参数。最后,return指令表示main方法执行完毕。

  7. 输出结果:在执行println方法时,JVM会调用底层操作系统的API来将字符串"Hello, World!"输出到控制台。

通过这个过程,Java程序从源代码编译成字节码,再由JVM执行字节码,最终输出结果。这个过程展示了Java语言的“一次编写,到处运行”的特性,以及JVM作为Java程序运行环境的重要性。

四. 详细分析
  • 类加载:当运行java HelloWorld命令时,JVM首先查找并加载名为HelloWorld的类。这涉及到从类路径中找到并读取HelloWorld.class文件。

  • 链接:加载类后,JVM会进行链接过程,这包括验证类文件的格式、准备类的静态变量、并将符号引用解析为直接引用。

  • 初始化:在链接之后,JVM将执行类的初始化阶段。这通常包括执行静态代码块和静态变量的初始化。对于HelloWorld类来说,这个阶段没有特别的初始化代码要执行。

  • 调用main方法:一旦类被加载、链接和初始化,JVM就会调用HelloWorld类的main方法。这是程序的入口点,所有Java程序都从这里开始执行。

  • 执行代码:在main方法内部,System.out.println("Hello, World!");语句被执行。这个语句使用标准输出流(通常是控制台)来打印字符串“Hello, World!”。

五. 总结

从编写源代码到编译成字节码,再到运行Java程序并输出结果,“Hello, World!”程序展示了Java编程的基本流程。这个过程涉及类加载、链接、初始化和方法调用等关键步骤。通过理解这些步骤,我们可以更好地掌握Java程序的运行原理,并为进一步学习Java编程打下坚实的基础。

标签:Java,字节,HelloWorld,JVM,World,main,Hello
From: https://blog.csdn.net/gzjimzhou/article/details/143192085

相关文章

  • vue3+java基于Spring Boot的爱老助老服务平台源码 lw 部署
    目录功能介绍具体实现截图技术介绍开发核心技术介绍:技术创新点vue3和vue2的区别:核心代码部分展示非功能需求分析系统开发流程软件测试源码获取功能介绍爱老助老服务平台的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使......
  • javascript对象介绍
    1.什么是对象?在JavaScript中,对象是一个无序的键值对集合,可以用来存储数据和功能。对象可以包含原始值、函数(方法)以及其他对象,是构建复杂数据结构和实现面向对象编程的基础。2.创建对象2.1字面量方式最常见的创建对象的方法是使用对象字面量:constperson={n......
  • java基础2024(5.集合)
    集合(Collection)是一组用于存储和操作对象的数据结构。Java集合框架(JavaCollectionsFramework,JCF)提供了一个统一的架构,用于表示和操作集合,它包含了一系列接口、实现类以及算法。Collection接口Collection接口是集合框架的根接口,它扩展了Iterable接口,定义了所有集合类型共......
  • javascript数组splice和slice介绍
    一splice1.概述splice是JavaScript数组对象的一个方法,用于改变原数组的内容。它可以添加、删除或替换数组中的元素。2.语法array.splice(start,deleteCount,item1,item2,...)start:需要改变的数组的起始索引。如果是负数,则表示从数组末尾开始计数。de......
  • 挑战中,Java面试题复习第5天,坚持就是胜利。
     ......
  • 【Azure Developer】使用JavaScript通过SDK进行monitor-query的client认证报错问题
    问题描述使用JavaScript通过SDK进行monitor-query的client初始化时候,需要进行认证时报错AADSTS90002。代码如下:constcredential=newDefaultAzureCredential();constlogsQueryClient=newLogsQueryClient(credential,{endpoint:"https://api.loganalytics.azur......
  • java操作word
    word基础docx和doc的区别doc是微软特有的一种文件格式,其本质是一个二进制的文件docx是基于XML的开放文档格式,是OfficeOpenXml的一部分。docx组成部分一个完整的docx文档由4部分构成。即_rels、docProps、word和[Content_Types].xmlword文件夹定义了文档的内容......
  • 0基础学java之Day13
    static理解:静态的作用:1.修饰属性类加载到方法区时,JVM会扫描该类的所有属性并把静态属性加载到静态区中,静态属性属于类属性,该类所有的对象都共享该属性静态属性直到项目结束时才会被回收2.修饰方法属于类方法,直接用类名调用应用场景:工具类3.修饰代码块静态代......
  • 如何使用Java设计一个RDB格式的Redis
    RDB的使用场景数据备份:RDB适合定期备份Redis中的数据,帮助在系统崩溃或意外情况下恢复数据。冷备份:在不需要频繁写入数据的场景(如数据分析、报告生成),RDB可以作为冷备份使用。启动时数据加载:在系统启动时,通过加载RDB文件快速恢复数据,提高启动速度。数据迁移:使用RD......
  • 如何使用Java设计一个AOF格式的Redis
    AOF的使用场景高数据安全性需求:适用于对数据一致性要求高的应用场景,如金融交易系统、订单处理系统等。频繁写入操作:AOF适合频繁进行写操作的场景,因为它记录每个写命令,可以有效恢复最新数据。实时数据恢复:当系统崩溃或发生故障时,AOF能快速恢复数据,适合需要高可用性......