JAVA打印Hello World的底层实现

news/2025/3/5 6:00:51/

任何一个学过JAVA的人应该都对这段代码非常熟悉。空闲时间翻了下代码,看看它的底层是怎么实现的

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

首先点开out,发现它是System类中的一个public static final变量,类型为PrintStream。为了找到它是怎么初始化的,一直往前翻到System类的构造函数

System类的注释中发现,VM会调用initPhase1这个方法来初始化这个类。先不管VM,先看下initPhase1方法做了什么

发现它用FileDescriptor.out创建了FileOutputStream对象,再用这个对象创建了PrintStream对象,最后调用native的setOut0

在创建PrintStream对象时,先将FileOutputStream封装成BufferedOutputStream,然后把BufferedOutputStream封装成OutputStreamWriter。这一步中会根据传入的字符集创建OutputStreamWriter中的编码器StreamEncoder

这样OutputStreamWriter就创建好了,在print的时候会调用这个类的方法,最后根据调用栈发现调用了FileOutputStream中的writeBytes方法

发现这个方法是native的,也就是说不在JAVA中实现,打开openjdk,checkout到tag jdk18

找到在jdk中的实现,发现调用了IO_AppendIO_Write,而这两个是宏定义,指向了handleWrite方法

在不同的平台下,这个方法有不同的实现

在windows下调用了WriteFile这个Win32 API

在linux下调用了unistd.h中定义的write方法

打开glibc,在write_nocancel.c下看到提供的write方法实现,通过一堆的宏定义最终是一个系统调用,调用了linux的write方法

在linux内核源代码中,找到write的SYSCALL,其中调用了ksys_write方法

这个方法中会获取fd,然后再通过vfs_write写入,顺着调用链一路找到了下面这个write方法

后面的两个参数很好理解,第一个tty_struct是什么?

In many computing contexts, “TTY” has become the name for any text terminal, such as an external console device, a user dialing into the system on a modem on a serial port device, a printing or graphical computer terminal on a computer’s serial port or the RS-232 port on a USB-to-RS-232 converter attached to a computer’s USB port, or even a terminal emulator application in the window system using a pseudoterminal device.

简单来说,就是一个文本终端。它也是一个虚拟文件系统,模拟了终端设备

回头看ksys_write方法的第一行,打开了一个文件描述符,其中调用了__fget_light方法

从第一行就能看到,从current中找到了files_structcurrent是一个宏定义,获取当前正在运行的任务current_task,而current_task->files是这个当前正在运行的任务所打开的文件信息

也就是说,进程打开了一个由虚拟文件系统管理的虚拟文件,它是一个伪终端PTY,然后向其中写入数据

在linux中输入tty,就可以看到对应的伪终端设备文件路径。往里写入数据,就可以实现向另一个终端中打印东西


参考:

  1. https://github.com/openjdk/jdk
  2. https://sourceware.org/git/glibc.git
  3. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
  4. https://www.linusakesson.net/programming/tty/index.php
  5. https://en.wikipedia.org/wiki/Devpts
  6. https://man7.org/linux/man-pages/man7/pty.7.html
  7. https://github.com/GNOME/vte

http://www.ppmy.cn/news/212547.html

相关文章

2022版MyBatis入门教程笔记

1. MyBatis简介 MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objec…

摄影知识 - 入门学习

摄影知识 - 入门学习 个人博客:sulenn 自从去过 雨崩 和 稻城 等地之后,我就一直心心念,想着买一个单反。主要用于记录旅途中遇见的景、看见的人。苦于手头拮据,索性先了解一些相关知识,为之后购买、择机打好基础。此…

摄影入门-之一-什么是单反

单反 数码单镜反光相机(Digital Single Lens Reflex Camera,常简称为DSLR),简称数码单反相机。 相对于传统使用的单反相机,数码单反相机是以电荷耦合元件(Charge-coupled device,CCD&#xff…

单反相机参数之ISO/焦距篇

ISO/焦距是什么 要说什么是ISO还要从传统胶片相机说起,ISO称作为感光度,它是衡量传统相机所使用胶片感光速度的国际统一指标,其反映了胶片感光时的速度(其实是银元素与光线的光化学反应速率)。而对于现在并不使用胶片…

渗透hacker入门知识,小白级

社工:社会工程学 一种通过对受害者心理弱点、本能反应、好奇心、信任、贪婪等心理陷阱进行诸如欺骗、伤害等危害手段。 单反:社工术语 一个好友辅助申诉 裸奔:社工术语 不需要好友辅助申诉 肉鸡:肉鸡也称傀儡机,是指…

入门级CC(Smart3D)照片建模

一、准备和设置 1、准备 单反相机:(没有相机用手机拍照也可以测试) 软件:CC(ContextCapture),版本:CCCenter-partial-10.16.0.75.x64-en.msi 软件下载地址,也阔以自己在网上下载: …

单反入门二 转载

在上期文章( 相机参数之光圈/快门篇)中笔者给大家详细的介绍了 相机中光圈与快门这两个参数的作用和特点。然而在今天的文章中笔者依然会为大家详细的介绍 相机的另两个重要参数——ISO和焦距。相信大家在看完这篇文章后会对这两个参数有更多的了解。…