世界是沙粒还是宇宙_看到一个沙粒世界:再一次你好世界

世界是沙粒还是宇宙

“看到一个沙粒中的世界”,我们很可能会看到最简单的“ Hello World”中的世界,所以我们开始吧,再一次向世界问好。

我猜所有的Java课程,教程都是从这个著名的Hello World程序开始的,这是我可以在没有IDE的帮助下编写的非常罕见的程序之一:)

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

1.您知道这些javac选项吗?

编写完第一个程序后,您将首先执行以下命令进行编译,否则将无法运行。

javac HelloWorld.java

您可能会发现不必将文件命名为“ HelloWorld.java”,“ Hello.java”也可以使用。 public class HelloWorld也可以降级为class HelloWorld

如果您好奇地按下javac --help ,将会看到很多有关Java编译器的选项,例如,我们要打印中文版“ Hello World”,并希望它完全适用于JDK8语言级别,元数据为包含的参数名称,它看起来像这样:

javac -encoding UTF-8 -source 8 -target 8 -parameters Hello.java

您已经安装了JDK11,但是使用上面的命令仅使用1.8功能发布了类文件。 如果您编写了一些仅可从JDK9获得的内容,则会发现它无法按预期进行编译。

2.类文件的基础

关于Java虚拟机规范中的类文件格式的整章内容,您是否需要对其进行一些探讨?

沙粒

您会看到字节码(与JDK11一起编译)以一个神奇的,神秘的“ cafe babe”开头,然后以55开头,很多东西会伤害您的大脑。 其中,“ cafe babe”是魔术,指向次要版本的55点映射到JDK11。 与读取超赞的类文件格式相比,您还可以使用javap检索该类文件的信息:

# You would use javap -h to see how many options you have
javap -p -l -c -s -constants HelloWorld

您将获得如下信息:

class HelloWorld {HelloWorld();                                                                                        descriptor: ()V                                                                                    Code:                                                                                              0: aload_0                                                                                      1: invokespecial #1                  // Method java/lang/Object."<init>":()V                    4: return                                                                                       LineNumberTable:                                                                                   line 1: 0                                                                                        public static void main(java.lang.String[]);                                                         descriptor: ([Ljava/lang/String;)V                                                                 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;)V8: return                                                                                       LineNumberTable:                                                                                   line 4: 0                                                                                        line 5: 8                                                                                        
}

您会发现这里的指令与源代码有些相似,带有源代码的行号和指令号的映射,您可能想知道,我可以从这些东西中恢复源代码吗?

3.反编译器

是的你可以。 反编译器有很多,但是其中一些反编译器已经过时,例如JD-GUI ,JAD等,它们在使用最新JDK编译的类文件上不能很好地工作。 您仍然可以使用它们,但是CFR更合适。

# java -jar cfr-0.139.jar HelloWorld.class
/*                                               * Decompiled with CFR 0.139.*/                                              
import java.io.PrintStream;                      class HelloWorld {                               HelloWorld() {                               }                                            public static void main(String[] arrstring) {System.out.println("Hello World");       }                                            
}

您可能已经发现源代码和反编译的代码(添加了构造方法)略有不同,实际上,您可能会惊讶地发现有时似乎对源代码进行了修改,从而使您感到惊讶。 但是,其中许多是通过JVM进行的优化,通常可以提高性能,比较它们之间的差异实际上很有趣,并且可以为您提供很多见识。

4.如何再次初始化具有空值的最终变量?

System.out.println("Hello World") ,System是一个类,out是具有final修饰符的静态属性之一:

public final static PrintStream out = null;

然后问题来了,为什么hack System.out.println("Hello World")不会抛出著名的NullPointerException ,根据语言规范,似乎最终的静态变量out不可能分配给有效值再次吧?

是的,在大多数情况下,如果您不使用肮脏的反射技巧并且不引入native好友,那是正确的。

如果您只是想玩转,可以这样做:

Field f = clazz.getDeclaredField("out");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);

但是,这对于System无效,实际的秘密隐藏在System.java以下代码行中:

private static native void registerNatives();
static {registerNatives();
}

按照方法上方写的注释,“ VM将调用initializeSystemClass方法来完成此类的初始化”,转到initializeSystemClass方法,您将看到以下行:

FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));

而且你还可以看到这3种本地方法设置inout

private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);

因此,您现在可能会问,JVM会在OS级别上做这些事情并“绕过” final限制,您可能会问,JVM将适应的OS级别代码在哪里被破解?

因此这里是System.c (JDK11版本) 。

JNIEXPORT void JNICALL
Java_java_lang_System_registerNatives(JNIEnv *env, jclass cls)
{(*env)->RegisterNatives(env, cls,methods, sizeof(methods)/sizeof(methods[0]));
}
/** The following three functions implement setter methods for* java.lang.System.{in, out, err}. They are natively implemented* because they violate the semantics of the language (i.e. set final* variable).*/
JNIEXPORT void JNICALL
Java_java_lang_System_setIn0(JNIEnv *env, jclass cla, jobject stream)
{jfieldID fid =(*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");if (fid == 0)return;(*env)->SetStaticObjectField(env,cla,fid,stream);
}

在这里,您可以在注释中找到后门, “它们是本机实现的,因为它们违反了语言的语义(即,设置最终变量)”

然后,您会发现这是一条漫长的道路。 旅程将永远不会停止。

结束:停一会儿

“用沙粒看世界
还有野花中的天堂
将Infinity握在手中 一小时的永恒”

如果最简单的HelloWorld只是一片沙粒,那么里面肯定有一个世界,也许您曾多次对它说“ Hello”,但这并不意味着您已经探索了一点世界,也许现在时间和探索世界,虽然沙子会弄脏您的手,但花朵却不会。

翻译自: https://www.javacodegeeks.com/2019/02/world-grain-sand-world.html

世界是沙粒还是宇宙

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑word在哪_到底哪个PDF转Word最好用?

今天的内容很简单&#xff0c;就聊一个很基本的问题&#xff1a;PDF格式转换。而PDF转换中最具有代表性以及最常用的&#xff0c;莫过于PDF转Word了。那咱们今天就从PDF转Word着手&#xff0c;找出最好用的PDF转Word神器。特别提醒&#xff0c;这是一篇将近2000字长文。不想看过…

linux视音频解码教程,音视频编解码:NVIDIA Jetson Linux Multimedia API(总结)

音视频编解码&#xff1a;NVIDIA Jetson Linux Multimedia API(总结)2020年12月02日| 萬仟网IT编程| 我要评论一、官网链接官网链接&#xff1a;https://docs.nvidia.com/jetson/l4t-multimedia/index.html二、环境我这边用的是jetson nano&#xff0c;刷机是JetPack4.4版本。j…

IntelliJ IDEA for Mac下载、安装、使用TunnelliJ插件(一种TCP/IP Monitor)

文章目录下载和安装 TunnelliJ使用 TunnelliJIntelliJ IDEA 要使用类似于 Eclipse 的 TCP/IP Monitor&#xff0c;需要下载第三方插件&#xff0c;推荐使用 TunnelliJ 插件。下载和安装 TunnelliJ 或者按快捷键 ⇧ ⌘ A&#xff0c;搜索 plugins 也能打开插件管理界面&#…

干支纪年法简便算法_民间玄学:那些年我理解的何谓“天干”,“地支”,“干支”...

文/天泽子在我很小的时候&#xff0c;大概6岁左右&#xff0c;父亲带着我跟这一方面的知识开始接触&#xff0c;那个时候的我不明白天干&#xff0c;地支是什么&#xff1f;父亲的小学文化程度&#xff0c;只对我说“天干分别为&#xff1a;甲(jiǎ)、乙(yǐ)、丙(bǐng)、丁(d…

corda_吞吐量-Corda的故事

corda我最近启动了一个针对特定用例的Corda性能的项目。 该项目的结果使我们在170多个节点的网络上一天之内处理了1.15亿个请求。 此外&#xff0c;Corda每秒能够处理6300个请求&#xff0c;确认满足了网络的最高要求。 迄今为止&#xff0c;这是迄今为止已部署的最大的Corda网…

linux webapi测试,Webapi管理和性能测试工具WebBenchmark

WebBenchmark是一款基于开源通讯组件Beetlex扩展的Webapi管理和性能测试工具&#xff0c;在传统工具中一般管理工具缺乏性能压测能力或有性能测试的缺少管理功能&#xff1b;WebBenchmark的设计目标是就管理和性能压测能力同时具备。接下来介绍一下工具的功能和使用&#xff1a…

小程序影藏溢出的gif_ScreenToGif:一款小巧实用动图gif制作神器

ScreenToGif是一个小型的便携式的gif录屏程序,它能使您记录您的屏幕上的任何内容并将其保存为GIF动画。您可以自由地移动捕获帧录制视频上的 web 页或屏幕活动在您的桌面上。捕获可以暂停和恢复&#xff0c;一旦你完成录制&#xff0c;程序带来了一种简单的编辑器&#xff0c;允…

Servlet的重定向和转发特点

重定向 重定向的特点&#xff1a; 1.地址栏发生变化 2.重定向可以访问其他站点(服务器)的资源 3.重定向是两次请求&#xff0c;不可以使用Request对象共享数据 重定向的示例代码&#xff1a; package priv.lwx.javaex.servlet_demo.web.servlet.response;import javax.servl…

java 动画_Java安全动画

java 动画总览 自从JDK 1.2中引入安全沙箱模型以及JDK提供的安全API的发展以来&#xff0c;Java安全就一直是一个复杂的话题。 并发实用程序也观察到类似的问题&#xff0c;并且开发了一种名为Java Concurrent Animated的工具&#xff0c;目的是通过有趣而有趣的方式降低进入这…

u盘插在linux电脑上没有反应,U盘插在自己电脑上没有反应,别人电脑有反应的解决方法...

近期&#xff0c;将U盘插到自己电脑上无法读盘&#xff0c;虽然通知栏那里显示了设备已连接&#xff0c;但是在电脑里看不到盘符&#xff0c;以为是U盘损坏了&#xff0c;但是插到别人电脑上却可以正常使用&#xff0c;这就证明了U盘肯定没有问题的。那么遇到这个问题我们要如何…

绝对路径/相对路径

文章目录1.相对路径2.绝对路径1.相对路径 通过相对路径不可以确定唯一资源。 如&#xff1a; ./index. html。 不以/开头&#xff0c;以.开头路径。 规则&#xff1a;找到当前资源和目标资源之间的相对位置关系。 ./&#xff1a;当前目录 ../&#xff1a;后退一级目录&…

局域网网管软件_网管软件有哪些?那些不同之处

企业管理一般用到的网管软件&#xff0c;就是局域网监控软件的一种&#xff0c;它不同于网吧管理用的管理软件&#xff0c;它是集网络监控&#xff0c;监管一体的软件。网管软件并不是单单的一种软件&#xff0c;它在市面上也是包含很多类的。行业内知名的超级眼局域网监控软件…

stripe pay_J2Pay –完整示例

stripe pay介绍 在本节中&#xff0c;我们将详细探讨如何使用网关并成功调用所有四种方法&#xff0c;即购买&#xff0c;退款&#xff0c;作废和重新计费。 对于此示例&#xff0c;我们将使用授权网关。 让我们开始。 首先&#xff0c;我们将获得授权网关对象。 Gateway ga…

Linux主机通过直连线直连,【IT基础】网线的直连线与交叉线之间的区别

小续嵌入式开发的运行环境是目标板&#xff0c;而开发环境是宿主机。因此需要把宿主机中经过编译之后的可执行文件下载到目标板上去。需要注意的是&#xff0c;这里所讲的下载是下载到目标机中的SDRAM常见的下载方式有网络下载(如TFTP、FTP等方式)、串口下载、USB下载等当用TFT…

字符集和字符编码的学习

文章目录标准 ASCII扩展 ASCIIGB2312 编码GBK 编码GB18030 编码Unicode 编码UCS-2 字符集UCS-4 字符集UTF-8 编码先有字符集&#xff0c;然后对每个字符进行编码&#xff0c;这叫字符编码&#xff0c;不同的编码规则就产生了不同的编码方案。 标准 ASCII 标准 ASCII 码也叫基…

移动端怎么让底部固定_移动端排名应该怎么做?两种匹配移动端实战排名干货分享...

关于移动端优化的问题、最近一些兄弟一直在问我应该怎么做&#xff1f;毕竟现在是手机的时代、绝大部分情况下、PC显得有点鸡肋&#xff01;在讲移动端排名之前、逆冬先来讲两个容易被大家搞错的问题&#xff08;移动端&#xff09;。1、逆冬老师你好、我观察现在的移动端都是独…

stripe pay_J2Pay –入门

stripe pay入门将指导您如何通过非常简单的步骤快速开始使用J2pay。 下载 J2Pay在Maven上可用。 <dependency><groupId>com.tranxactive</groupId><artifactId>j2pay</artifactId><version>2.4.0</version></dependency>您…

基于linux设计的贪吃蛇论文,毕业设计(论文)LINUX平台下基于C的贪食蛇游戏设计与实现.doc...

毕业设计(论文)LINUX平台下基于C的贪食蛇游戏设计与实现正在输入(豆丁网laoshutou)为您倾心整理(下载后双击删除)如有需求请发豆丁站内信(下载后双击删除)目 录TOC \h \z \t "样式1,1,样式4,1,样式5,2,样式6,3" HYPERLINK \l "_Toc" 摘 要 PAGEREF _Toc \h…

缓存和缓冲的区别

参考&#xff1a; https://www.cnblogs.com/mlgjb/p/7991903.html https://www.cnblogs.com/xiangxiaolin/p/11840278.html

java环境变量的配置_Java的下载及环境变量的配置

讲讲java的安装,java的官方下载地址为https://www.oracle.com/technetwork/java/javase/downloads/index.html目前oracle官网提供了java的很多版本&#xff0c;但大多数开发者使用的还是java8&#xff0c;博主也是java8&#xff0c;java8目前最稳定&#xff0c;java分为javase,…