一段java代碼是如何執行的

      網友投稿 641 2025-03-31

      1. 編譯成class

      眾所周知,java代碼是不能直接在jvm上執行的,執行的是class文件,將java代碼編程class文件,需要編譯

      常用的編譯方法是:javac xxx.java

      但目前常見的java編輯工具,如eclipse和ideal都自帶自動編譯動能

      2. jvm的構成

      讓我們回憶一下jvm的構成:

      主題上分為五個部分:

      方法區,本地方法棧,java堆,java棧,程序計數器

      其中,java棧,本地方法棧,程序計數器為線程私有,其余為線程共享

      那么,方法在哪個地方執行呢?

      java棧。

      棧的遵循的方式是先進后出,java棧中方法的執行也遵循此規律,方法執行的步驟又稱為棧幀。

      3. 方法的順序執行和棧幀

      上代碼:

      -Java 代碼

      public class Main { public static void a(){ b(); } public static void b(){ c(); } public static void c(){ System.out.println("Hello world!"); } public static void main(String[] args) { a(); } }

      上面是一段很簡單的代碼,主體上就是:

      (1)一個Main類

      (2)上面定義了一個main方法

      (3)該main方法調用了靜態方法a

      (4)方法a調用方法b

      (5)方法b調用方法c

      (6)方法c打印了“Hello world!”

      前文說過,java定義的非本地方法都是在java棧內執行的,一方法一棧幀

      所以假設

      mian方法對應棧幀m

      a方法對應棧幀a

      b方法對應棧幀b

      c方法對應棧幀c

      根據方法的調用,入棧順序為:m,a,b,c

      所以,棧幀出棧(即方法執行)順序為:c,b,a,m

      4. class文件反編譯過后的樣子

      上一節,方法或棧幀在java棧的執行順序

      但在方法體內的內容是怎么執行的呢。

      前文提到,jvm執行的是class文件,而class文件內是什么?

      一段java代碼是如何執行的

      class文件內是一組指令集

      如何證明呢,還是再看一段代碼。

      -Java 代碼

      public class Calculator{ public int add(){ int n = 10; int m = 20; int r = n + m; return r; } public static void main(String[] args) { Calculator calculator = new Calculator(); int a = calculator.add(); System.out.println(a); } }

      如上代碼,實現的功能是:

      (1)定義兩個變量,相加

      (2)main方法new對象,調用方法

      但,class文件是不可以直接查看的。

      我們可以采用反編譯的方法,反編譯命令:、

      javap -c xxx.class

      上述文件反編譯后的樣子如下:

      每個方法下面的Code,都是一組指令集

      5. 指令集詳解

      在討論指令集之前,首先要講一個概念,那就是對棧幀進一步拆分。

      棧幀一共分為四個部分:局部變量表、操作數棧、動態鏈接、方法返回地址

      其中,局部變量表和操作數棧是最重要的兩個部分

      局部變量表存放在方法中定義的局部變量

      操作數棧相當于jvm的一個緩存

      所有的操作都必須在此處進行

      所有的變量都必須加載到操作數棧才能被使用

      所以,所謂指令,就是在局部變量表和操作數棧來回倒騰的過程。

      下面對指令進行分類講解:

      (1)入棧指令

      整型入棧指令:

      取值-1~5采用iconst指令;

      取值-128~127采用bipush指令;

      取值-32768~32767采用sipush指令;

      取值-2147483648~2147483647采用ldc指令。

      非整型入棧指令:

      float,String類型也使用ldc指令

      double和long類型使用ldc_2w

      boolean類型視作0和1

      null的入棧指令為:aconst_null

      (2)存儲指令

      將操作數棧中的常量保存在局部變量表中的某個位置

      如:

      istore_1:將上面入棧的整型常量保存在局部變量表中的第1個位置

      fstore_2:將上面入棧的浮點常量保存在局部變量表中的第2個位置

      dstore_10:將上面入棧的雙浮點常量保存在局部變量表中的第10個位置

      lstore_20:將上面入棧的長整常量保存在局部變量表中的第20個位置

      astore_100:將上面入棧的引用常量保存在局部變量表中的第100個位置

      (3)變量入棧指令

      iload_1:局部變量表中的第1個位置的整型變量入棧

      fload_2:局部變量表中的第1個位置的浮點型變量入棧

      dload_10:局部變量表中的第1個位置的雙浮點型變量入棧

      lload_20:局部變量表中的第1個位置的長整型變量入棧

      aload_100:局部變量表中的第100個位置的引用型變量入棧

      (4)計算指令

      加:iadd、ladd、fadd、dadd

      減:isub、lsub、fsub、dsub

      乘:imul、lmul、fmul、dmul

      除:idiv、ldiv、fdiv、ddiv

      注意:棧頂計算,一次只能計算一個表達式

      Java JVM

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:apaas梯子怎么設置(蘋果怎么設置梯子)
      下一篇:人生苦短,我學 Python】進階篇——類與繼承(Day14)
      相關文章
      亚洲女人被黑人巨大进入| 亚洲码和欧洲码一码二码三码| 亚洲av片在线观看| 国产成人亚洲综合一区| 国内精品久久久久影院亚洲| 亚洲人成网站日本片| 亚洲国产精品综合福利专区| 亚洲一级免费毛片| 亚洲中文无码a∨在线观看| 亚洲精品美女在线观看| 亚洲视频精品在线观看| 亚洲日韩乱码久久久久久| 亚洲精品视频久久| 亚洲人成电影在线观看网| 亚洲一卡2卡4卡5卡6卡残暴在线| 亚洲日韩乱码中文无码蜜桃| 亚洲一线产区二线产区精华| 亚洲一区二区三区在线| 亚洲中文字幕一二三四区| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 亚洲xxxx视频| 亚洲人片在线观看天堂无码| 亚洲第一成年免费网站| 毛片亚洲AV无码精品国产午夜| 亚洲AV无码一区二三区| 国产精品亚洲mnbav网站 | 亚洲av乱码一区二区三区香蕉| 中文字幕在线观看亚洲视频| 亚洲另类无码专区首页| 国产精品成人亚洲| 国产亚洲精品无码专区| 亚洲av无码无在线观看红杏| 91亚洲国产成人精品下载| 亚洲免费视频网址| 国产亚洲中文日本不卡二区| 日韩精品成人亚洲专区| 亚洲日韩av无码| 亚洲Aⅴ无码专区在线观看q| 亚洲日本乱码一区二区在线二产线| 7777久久亚洲中文字幕| 亚洲.国产.欧美一区二区三区|