日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 世界是沙粒还是宇宙_看到一个沙粒世界:再一次你好世界 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

世界是沙粒還是宇宙

“看到一個(gè)沙粒中的世界”,我們很可能會(huì)看到最簡(jiǎn)單的“ Hello World”中的世界,所以我們開始吧,再一次向世界問好。

我猜所有的Java課程,教程都是從這個(gè)著名的Hello World程序開始的,這是我可以在沒有IDE的幫助下編寫的非常罕見的程序之一:)

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

1.您知道這些javac選項(xiàng)嗎?

編寫完第一個(gè)程序后,您將首先執(zhí)行以下命令進(jìn)行編譯,否則將無法運(yùn)行。

javac HelloWorld.java

您可能會(huì)發(fā)現(xiàn)不必將文件命名為“ HelloWorld.java”,“ Hello.java”也可以使用。 public class HelloWorld也可以降級(jí)為class HelloWorld 。

如果您好奇地按下javac --help ,將會(huì)看到很多有關(guān)Java編譯器的選項(xiàng),例如,我們要打印中文版“ Hello World”,并希望它完全適用于JDK8語言級(jí)別,元數(shù)據(jù)為包含的參數(shù)名稱,它看起來像這樣:

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

您已經(jīng)安裝了JDK11,但是使用上面的命令僅使用1.8功能發(fā)布了類文件。 如果您編寫了一些僅可從JDK9獲得的內(nèi)容,則會(huì)發(fā)現(xiàn)它無法按預(yù)期進(jìn)行編譯。

2.類文件的基礎(chǔ)

關(guān)于Java虛擬機(jī)規(guī)范中的類文件格式的整章內(nèi)容,您是否需要對(duì)其進(jìn)行一些探討?

您會(huì)看到字節(jié)碼(與JDK11一起編譯)以一個(gè)神奇的,神秘的“ cafe babe”開頭,然后以55開頭,很多東西會(huì)傷害您的大腦。 其中,“ cafe babe”是魔術(shù),指向次要版本的55點(diǎn)映射到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 }

您會(huì)發(fā)現(xiàn)這里的指令與源代碼有些相似,帶有源代碼的行號(hào)和指令號(hào)的映射,您可能想知道,我可以從這些東西中恢復(fù)源代碼嗎?

3.反編譯器

是的你可以。 反編譯器有很多,但是其中一些反編譯器已經(jīng)過時(shí),例如JD-GUI ,JAD等,它們?cè)谑褂米钚翵DK編譯的類文件上不能很好地工作。 您仍然可以使用它們,但是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"); } }

您可能已經(jīng)發(fā)現(xiàn)源代碼和反編譯的代碼(添加了構(gòu)造方法)略有不同,實(shí)際上,您可能會(huì)驚訝地發(fā)現(xiàn)有時(shí)似乎對(duì)源代碼進(jìn)行了修改,從而使您感到驚訝。 但是,其中許多是通過JVM進(jìn)行的優(yōu)化,通常可以提高性能,比較它們之間的差異實(shí)際上很有趣,并且可以為您提供很多見識(shí)。

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

System.out.println("Hello World") ,System是一個(gè)類,out是具有final修飾符的靜態(tài)屬性之一:

public final static PrintStream out = null;

然后問題來了,為什么hack System.out.println("Hello World")不會(huì)拋出著名的NullPointerException ,根據(jù)語言規(guī)范,似乎最終的靜態(tài)變量out不可能分配給有效值再次吧?

是的,在大多數(shù)情況下,如果您不使用骯臟的反射技巧并且不引入native好友,那是正確的。

如果您只是想玩轉(zhuǎn),可以這樣做:

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

但是,這對(duì)于System無效,實(shí)際的秘密隱藏在System.java以下代碼行中:

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

按照方法上方寫的注釋,“ VM將調(diào)用initializeSystemClass方法來完成此類的初始化”,轉(zhuǎn)到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種本地方法設(shè)置in與out :

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

因此,您現(xiàn)在可能會(huì)問,JVM會(huì)在OS級(jí)別上做這些事情并“繞過” final限制,您可能會(huì)問,JVM將適應(yīng)的OS級(jí)別代碼在哪里被破解?

因此這里是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); }

在這里,您可以在注釋中找到后門, “它們是本機(jī)實(shí)現(xiàn)的,因?yàn)樗鼈冞`反了語言的語義(即,設(shè)置最終變量)” 。

然后,您會(huì)發(fā)現(xiàn)這是一條漫長(zhǎng)的道路。 旅程將永遠(yuǎn)不會(huì)停止。

結(jié)束:停一會(huì)兒

“用沙粒看世界
還有野花中的天堂
將Infinity握在手中 一小時(shí)的永恒”

如果最簡(jiǎn)單的HelloWorld只是一片沙粒,那么里面肯定有一個(gè)世界,也許您曾多次對(duì)它說“ Hello”,但這并不意味著您已經(jīng)探索了一點(diǎn)世界,也許現(xiàn)在時(shí)間和探索世界,雖然沙子會(huì)弄臟您的手,但花朵卻不會(huì)。

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

世界是沙粒還是宇宙

總結(jié)

以上是生活随笔為你收集整理的世界是沙粒还是宇宙_看到一个沙粒世界:再一次你好世界的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。