System.out.print实现原理猜解
我们往往在main中直接调用System.out.print方法来打印,但是其实就这简单的一步里面有很多的玄机,因为main是static的,所以只能调用static的函数,那么print是static的吗?我一直有这个疑问,今天专门查阅了下源码,说下我的理解:(源码只贴出来部分对理解有用的)
源码里面:public final class System 直接在lang包里面。所以可以直接不通过包名就直接调用system类。里面还有:
public final static PrintStream out = nullPrintStream();
............
............
private static PrintStream nullPrintStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
return null;
}
throw new NullPointerException();
}
可以看出out是system的静态成员,所以可以通过system.out直接访问到,但是这时候又有问题了,因为 nullPrintStream()这个函数返回值是null的,怎么可以调用printstream的方法呢。看out的注释:
/**
* The following two methods exist because in, out, and err must be
* initialized to null. The compiler, however, cannot be permitted to
* inline access to them, since they are later set to more sensible values
* by initializeSystemClass().
*/
大概翻译后知道刚开始的时候确实是都是null的,那么什么时候能把out指向标准输出的呢?注释说看initializeSystemClass()这个函数。
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
sun.misc.Version.init();
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
.................
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
...............
...............
接着找到FileDescriptor这个类中的静态成员 out:(用自身定义自身)
public static final FileDescriptor out = standardStream(1);
以及standardStream()方法:
private static FileDescriptor standardStream(int fd) {
FileDescriptor desc = new FileDescriptor();
desc.handle = set(fd);
return desc;
}
这时候返回了 handle为1的FileDescriptor; 在传统的unix的系统中,文件描述符为0,1,2分别表示为标准输入,标准输出和错误输出。
最后调用了setout0方法:
private static native void setOut0(PrintStream out);
到这里,setout0是native方法,所以再也追踪不到以后的细节了,而到这时候,out的出路似乎还没有找到。但是。在system类中有setout方法即:
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
调用了setout0()方法,而我们知道setout方法是重置输出流的对象的,因此虽然我们看不到setout0的细节,但是因为setout调用了setout0,我们可以大致猜到setout0是通过调用底层的代码实现对out的流的重定位的,而initializeSystemClass()这个函数也调用了setout0将fd为1的文件封装成文件流,再封装成缓冲流,再封装成打印流,最后通过setout0将out与这个流绑定。这样一切就都说通了。
原文链接:http://www.cnblogs.com/zr-714/archive/2012/03/22/2411926.html
System.out.print实现原理猜解的更多相关文章
- JVM源码分析之System.currentTimeMillis及nanoTime原理详解
JDK7和JDK8下的System.nanoTime()输出完全不一样,而且差距还非常大,是不是两个版本里的实现不一样,之前我也没注意过这个细节,觉得非常奇怪,于是自己也在本地mac机器上马上测试了一 ...
- python辅助sql手工注入猜解数据库案例分析
发现存在sql注入漏洞 简单一点可以直接用sqlmap工具暴库 但是如果想深入理解sql注入的原理,可以尝试手工注入,配合python脚本实现手工猜解数据库 首先hachbar开启 获取cms登录后的 ...
- WebLogic口令猜解工具【Python脚本】
WebLogic 默认端口7001 可以通过如下链接访问控制台 http://10.9.1.1:7001/console/login/LoginForm.jsp 写了一个简单的猜解脚本,半成品,做个记 ...
- FTP弱口令猜解【python脚本】
ftp弱口令猜解 python脚本: #! /usr/bin/env python # _*_ coding:utf-8 _*_ import ftplib,time username_list=[' ...
- Telnet弱口令猜解【Python脚本】
telnet 弱口令猜解脚本 测试环境:window2003.centos7 #! /usr/bin/env python # _*_ coding:utf-8 _*_ import telnetli ...
- PHPMyAdmin弱口令猜解【Python脚本】
PHPMyAdmin弱口令猜解 测试截图: 代码片段 #! /usr/bin/env python # _*_ coding:utf-8 _*_ import requests import time ...
- 节点地址的函数list_entry()原理详解
本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...
- WebActivator的实现原理详解
WebActivator的实现原理详解 文章内容 上篇文章,我们分析如何动态注册HttpModule的实现,本篇我们来分析一下通过上篇代码原理实现的WebActivator类库,WebActivato ...
- IIS系统短文件名漏洞猜解过程
今天看教程的时候,老师关于后台管理说到了短文件名漏洞,我就随便找了个网站猜解,可能是运气太好了,有了这次实践的过程,因为这个漏洞是13年的时候比较火,现在差不多都修复了,抓到一条漏网之鱼, 短文件名漏 ...
随机推荐
- iOS动画相关(持续更新)
1.When my application is entering background, because the user push the home button, the animations ...
- 关于Themleaf学习总结
此篇记录学习Themleaf测试的相关用例: study01 Thymeleaf 的HelloWorld级别的例子 简单介绍Thymeleaf的工作流程 study02 使用spring.thymel ...
- python2 和 python3兼容写法
一:使用ImportError,Python3中将一些Python2的模块名称做了修改,需要我们做一些处理来保证代码在不同Python版本中能够正常运行 # -*- coding: utf- -*- ...
- Snail—Hibernate反向生成实体类及配置文件
今天学习了Hibernate的反向生成类文件 第一步.打开myeclipse中的database视图,找到对应的表,选中后右键单击. watermark/2/text/aHR0cDovL2Jsb2cu ...
- find-k-pairs-with-smallest-sums
// https://discuss.leetcode.com/topic/50527/java-10ms-solution-no-priority-queue class Solution { pu ...
- hdu3117之矩阵快速幂
Fibonacci Numbers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- C#中的集合(HashTable与Array类)
一.Array类 1.Array类的属性 序号 属性 & 描述 1 IsFixedSize 获取一个值,该值指示数组是否带有固定大小. 2 IsReadOnly 获取一个值,该值指示数组是否只 ...
- 还原JavaScript的真实历史~
问题 ============ JavaScript真的继承自Cmm吗? JavaScript与Java有多少关系? JavaScirpt最初的设计是怎样的?在许多资料,JavaScript的语源被追 ...
- 时间插件WdatePicker使用方法
只需要引入js文件即可: <script src="WdatePicker/WdatePicker.js"></script> 自己试了个小实例: < ...
- 手写一个自己的LocalCache - 基于LinkedHashMap实现LRU
功能目标 实现一个全局范围的LocalCache,各个业务点使用自己的Namespace对LocalCache进行逻辑分区.所以在LocalCache中进行读写採用的key为(namespa ...