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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

classpath*: 和classpath:有什么区别_我们可以从Java“HelloWorld”中学到什么?

發布時間:2023/12/19 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 classpath*: 和classpath:有什么区别_我们可以从Java“HelloWorld”中学到什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是每個Java程序員都知道的程序。它很簡單,但是簡單的開始可以導致對更復雜概念的深入理解。在這篇文章中,我將探討從這個簡單的程序中學到什么。

公共 類 HelloWorld {

/ **

* @參數參數

* /

public static void main (String [ ] args ) {

// TODO自動生成的方法存根

System。出來。println (“ Hello World” );

} }

1.為什么一切都從一堂課開始?

Java程序是從類構建的,每個方法和字段都必須在一個類中。這是由于它具有面向對象的功能:一切都是一個對象,它是一個類的實例。相對于功能性編程語言,面向對象的編程語言具有很多優勢,例如更好的模塊化,可擴展性等。

2.為什么總是有“主要”方法?

“ main”方法是程序入口,它是靜態的。“靜態”表示該方法是其類的一部分,而不是對象的一部分。

這是為什么?我們為什么不將非靜態方法作為程序入口?

如果方法不是靜態的,則需要先創建一個對象才能使用該方法。因為必須在對象上調用該方法。為了進入目的,這是不現實的。沒有雞肉,我們就無法獲得雞蛋。因此,程序進入方法是靜態的。

參數“ String [] args”指示可以將字符串數組發送到程序以幫助程序初始化。

3. HelloWorld的字節碼

為了執行該程序,首先將Java文件編譯為存儲在.class文件中的Java字節碼。字節碼是什么樣的?字節碼本身不可讀。如果我們使用十六進制編輯器,則如下所示:

我們可以在上面的字節碼中看到很多操作碼(例如CA,4C等),每個操作碼都有一個對應的助記碼(例如,在下面的示例中為aload_0)。操作碼不可讀,但是我們可以使用javap來查看.class文件的助記符形式。

“ javap -c”打印出該類中每個方法的反匯編代碼。反匯編代碼表示組成Java字節碼的指令。

javap -classpath。-c HelloWorld

從“ HelloWorld.java”編譯而成的公共 類 HelloWorld 擴展了 Java。郎。對象{ public HelloWorld ();

代碼:

0 : aload_0

1 : 調用特殊#1 ; //方法java / lang / Object。“ <init>” :()V

4 : 返回

公共 靜態 無效主( java中。郎。字符串[ ] );

代碼:

0 : 靜態#2 ; //字段java / lang / System.out:Ljava / io / PrintStream;

3 : ldc#3 ; // String Hello World

5 : invokevirtual#4 ; //方法java / io / PrintStream.println:(Ljava / lang / String;)V

8 : return }

上面的代碼包含兩種方法:一種是默認的構造函數,由編譯器推斷出來;另一種是默認的構造函數。另一種是主要方法。

在每種方法之下,都有一系列指令,例如aload_0,invokespecial#1等。可以在Java字節碼指令列表中查找每個指令的作用。例如,aload_0將局部變量0的引用加載到堆棧上,getstatic獲取類的靜態字段值。請注意,在getstatic指令指向運行時常量池之后,將顯示“#2”。常量池是JVM運行時數據區域之一。這使我們看一下常量池,可以使用“ javap -verbose”命令來完成。

此外,每個指令都以數字開頭,例如0、1、4等。在.class文件中,每個方法都有一個對應的字節碼數組。這些數字對應于存儲每個操作碼及其參數的數組的索引。每個操作碼的長度為1個字節,指令可以具有0個或多個參數。這就是為什么這些數字不連續的原因。

現在,我們可以使用“ javap -verbose”進一步看一看該類。

javap -classpath。詳細的HelloWorld

從“ HelloWorld.java”編譯而成的公共 類 HelloWorld 擴展了 Java。郎。對象

SourceFile : “ HelloWorld.java”

次要版本: 0

主要版本: 50

常量池:const#1 = Method #6。#15 ; // java / lang / Object。“ <init>” :()V const#2 = 字段 #16。#17 ; // java / lang / System.out:Ljava / io / PrintStream;const#3 = 字符串 #18 ; // Hello World const#4 = Method #19。#20 ; // java / io / PrintStream.println:(Ljava / lang / String;)V const#5 = class #21 ; // HelloWorld const#6 = class #22 ; // java / lang / Object const#7 = Asciz < init >; const#8 = Asciz () V ; const#9 = ASCII碼; const#10 = Asciz LineNumberTable ; const#11 = Asciz主函數;const#12 = Asciz ([ Ljava / lang / String ; ) V ; const#13 = Asciz SourceFile ; const#14 = Asciz HelloWorld。java ; const#15 = NameAndType#7 :#8 ; //“ <init>” :()V const#16 = class #23 ; // java / lang / System const#17 = NameAndType#24 :#25 ; // out:Ljava / io / PrintStream; const#18 = Asciz你好世界; const#19 = 類別 #26 ; // java / io / PrintStreamconst#20 = NameAndType#27 :#28 ; // println:(Ljava / lang / String;)V const#21 = Asciz HelloWorld ; const#22 = Asciz java / lang / Object ; const#23 = Asciz java / lang / System ; const#24 = ASCII輸出; const#25 = Asciz Ljava / io/ PrintStream ;; const#26 = Asciz java / io / PrintStream ; const#27 = Asciz println ; const#28 = Asciz ( Ljava / lang / String ; ) V ;

{ 公共 HelloWorld ();

代碼:

堆棧= 1,Locals = 1,Args_size = 1

0 : aload_0

1 : invokespecial#1 ; //方法java / lang / Object。“ <init>” :()V

4 : 返回

LineNumberTable :

第2行: 0

公共 靜態 無效主( java中。郎。字符串[ ] );

代碼:

堆棧= 2,Locals = 1,Args_size = 1

0 : getstatic#2 ; //字段java / lang / System.out:Ljava / io / PrintStream;

3 : ldc#3 ; // String Hello World

5 : invokevirtual#4 ; //方法java / io / PrintStream.println:(Ljava / lang / String;)V

8 : 返回

LineNumberTable :

行9 : 0

行10 : 8 }

從JVM規范開始:運行時常量池的功能類似于常規編程語言的符號表,盡管它包含的數據范圍比典型的符號表還大。

“ invokespecial#1”指令中的“#1”指向常量池中的#1常量。該常量為“方法#6.#15;”。從數字中,我們可以遞歸獲得最終常數。

LineNumberTable向調試器提供信息,以指示Java源代碼的哪一行對應于哪個字節代碼指令。例如,Java源代碼中的第9行對應于main方法中的字節代碼0,而行10對應于字節代碼8。

如果您想了解更多有關字節碼的信息,可以創建并編譯一個更復雜的類以進行查看。HelloWorld確實是這樣做的起點。

4.如何在JVM中執行?

現在的問題是,JVM如何加載類并調用main方法?

在執行main方法之前,JVM需要1)加載,2)鏈接和3)初始化類。1)加載將類/接口的二進制形式帶入JVM。2)鏈接將二進制類型的數據合并到JVM的運行時狀態中。鏈接包括3個步驟:驗證,準備和可選的解決方案。驗證可確保類/接口在結構上正確;準備工作涉及分配類/接口所需的內存;分辨率解析符號引用。最后3)初始化為類變量分配了適當的初始值。

此加載作業由Java類加載器完成。啟動JVM時,將使用三個類加載器:

1. Bootstrap類加載器:加載位于以下位置的核心Java庫: / jre / lib目錄。它是核心JVM的一部分,并用本機代碼編寫。

2. 擴展類加載器:將代碼加載到擴展目錄中(例如, / jar / lib / ext)。

3. 系統類加載器:加載在CLASSPATH上找到的代碼。

因此,HelloWorld類由系統類加載器加載。當main方法執行時,它將觸發其他依賴類的加載,鏈接和初始化(如果存在)。

最后,將main()框架壓入JVM堆棧,并相應地設置程序計數器(PC)。PC然后指示將println()幀推送到JVM堆棧。當main()方法完成時,它將從堆棧中彈出并執行完畢。

最后,開發這么多年我也總結了一套學習Java的資料與面試題,如果你在技術上面想提升自己的話,可以關注我,私信發送領取資料或者在評論區留下自己的聯系方式,有時間記得幫我點下轉發讓跟多的人看到哦。

總結

以上是生活随笔為你收集整理的classpath*: 和classpath:有什么区别_我们可以从Java“HelloWorld”中学到什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。