国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
class文件內(nèi)容分析總結(jié)

使用Java開發(fā),我們不必關(guān)系編譯器對源碼做了什么,但是我們現(xiàn)在要探索java許多的幕后細(xì)節(jié)。

  
  

1          用二進(jìn)制表示的類

二進(jìn)制類的格式實(shí)際上是由jvm規(guī)范定義的,他們是編譯器從java源碼生成,并存儲(chǔ)在擴(kuò)展名為.class文件中,不重要的部分不是源碼以及如何存儲(chǔ)源碼,而是格式本身,一個(gè)類的格式可能是下面這樣:

public class HelloWorld{

       public static void main(){

              System.out.println("helloworld");

       }    

}

 

Class文件結(jié)構(gòu),通過tag+長度的形式來表示某種結(jié)構(gòu),最基本的組成是8位的無符號(hào)數(shù),分別是U1,U2,U4,U8,這些字節(jié)可以被解釋成有符號(hào)數(shù),UTF-8編碼的字符等。

 

1.1   有符號(hào)無符號(hào)

參考我的:java中的有符號(hào),無符號(hào)操作以及DataInputStream

數(shù)據(jù)底層讀取都是一個(gè)byte,那作為int的輸入,實(shí)際是0X000000byte,所以肯定是無符號(hào)類型,如果是想讀取有符號(hào)的,比如byte,或者short,那可以直接做轉(zhuǎn)換,因?yàn)?/span>java在寬類型轉(zhuǎn)為窄類型的時(shí)候,直接截取掉長的byte。下面給出一個(gè)讀取short型以及讀取int型的例子

 

int

(((a & 0xff) << 24) | ((b & 0xff) << 16) |
  ((c & 0xff) << 8) | (d & 0xff))

或者是

  int ch1 = in.read();

  int ch2 = in.read();

  int ch3 = in.read();

  int ch4 = in.read();

  if ((ch1 | ch2 | ch3 | ch4) < 0)

      throw new EOFException();

  return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

 

Short

 int ch1 = in.read();

 int ch2 = in.read();

 if ((ch1 | ch2) < 0)

     throw new EOFException();

 return (short)((ch1 << 8) + (ch2 << 0));

 

1.2   Utf-8

UTF-8變體結(jié)構(gòu)的規(guī)則如下:

1. 標(biāo)準(zhǔn)的ascii碼表只需要7位(不包括擴(kuò)展表),當(dāng)然還有一個(gè)NULL,在這里,除了Null以外的ASCII碼全部使用一個(gè)字節(jié)表示

All characters in the range '\u0001' to '\u007F' are represented by a single byte:

0

bits 6-0

 


2.NULL字符(0000)和在00800007FF范圍內(nèi)的使用雙字節(jié)表示:

 

The bytes represent the character with the value ((x & 0x1f) << 6) + (y & 0x3f).

 

3.0800FFFF的所有字符使用三個(gè)字節(jié)表示:

 

 

他和標(biāo)準(zhǔn)UTF8的區(qū)別在于:

1.標(biāo)準(zhǔn)UTF-8編碼,空字符null使用一個(gè)字節(jié)表示,在CONSTANT_Utf8_info表中,空字符,使用兩個(gè)字節(jié)表示,這樣字節(jié)數(shù)組就不會(huì)為0,(據(jù)說是為了排除編碼\0帶來的干擾)

2.Bytes項(xiàng)中只使用了標(biāo)準(zhǔn)UTF-8編碼中的單字節(jié)、雙字節(jié)和三字節(jié),而標(biāo)準(zhǔn)UTF-8編碼還包括未在CONSTANT_Utf8_info表中使用的較長的格式。

 

可以參考標(biāo)準(zhǔn)UTF-8編碼:UTF-8

 

 

1.3   類文件基本格式

Java class文件的精確定義使得所有Java虛擬機(jī)都能夠正確地讀取和解釋所有Java class文件。

 

 {

   0xCAFEBABE,小版本號(hào),大版本號(hào),常量池大小,常量池?cái)?shù)組,

   訪問控制標(biāo)記,當(dāng)前類信息,父類信息,實(shí)現(xiàn)的接口個(gè)數(shù),實(shí)現(xiàn)的接口信息數(shù)組,

域個(gè)數(shù),域信息數(shù)組,方法個(gè)數(shù),方法信息數(shù)組,屬性個(gè)數(shù),屬性信息數(shù)組

}

 

二進(jìn)制類表示中首先是“cafe babe”特征符,它標(biāo)識(shí) Java 二進(jìn)制類格式,這個(gè)特征符恰好是一種驗(yàn)證一個(gè)數(shù)據(jù)塊 確實(shí)聲明成 Java 類格式的一個(gè)實(shí)例的簡單方法。任何 Java 二進(jìn)制類(甚至是文件系統(tǒng)中沒有出現(xiàn)的類)都需要以這四個(gè)字節(jié)作為開始。 think in java中,說作者正在思念一個(gè)女人)。

2          class文件格式詳細(xì)

參考我的:class文件格式詳細(xì)

這里可以學(xué)習(xí)到得主要就是怎么設(shè)計(jì)一個(gè)緊湊的格式,里面有個(gè)讓我映像深刻的主要是:

 

1.UTF_8結(jié)構(gòu)的大量使用,幾乎所有其他結(jié)構(gòu)都指向了這種結(jié)構(gòu),比如字段名,字段類型,方法名,方法參數(shù)類型,類名等等。

 

2.類構(gòu)造器方法<clint>,以及實(shí)例構(gòu)造器方法<init>

 

3.指令描述Code屬性,方法的指令不是在方法體中的,而是引用了一個(gè)Code屬性

 

4.局部變量表,LocalVariableTable以及LineNumberTable(字節(jié)碼和sourcecode行數(shù)的對應(yīng)關(guān)系),用于提供調(diào)試時(shí)候的信息,包括變量的作用域范圍等

3          指令符

Java字節(jié)碼有259個(gè)操作符(類似Ascii),用一個(gè)byte8位)就可以表示了。

0x00 - 0xca, 0xfe, and 0xff 被指定為不同的值. 0xba 因?yàn)橐恍v史原因沒有被使用。 0xca 被作為一個(gè)debug的斷點(diǎn),在程序中沒有被使用. 同樣, 0xfe 0xff 也沒有被語言使用,而是被保留為jvm內(nèi)部使用。

 

指令可以被寬泛的分為幾個(gè)組:

1.LoadStore(例如aload_0istore

2.運(yùn)算和邏輯(例如ladd,fcmpl

3.類型轉(zhuǎn)換(例如i2bd2i

4.對象的創(chuàng)建和操作(例如new putfiled

5.操作數(shù)棧管理(例如swap、Dup2

6.流程控制(例如ifeq、goto

7方法的執(zhí)行和返回(例如invokespecialareturn

 

另外,還有幾個(gè)特殊的指令,比如異常、同步等。

 

3.1   類型前綴和后綴

很多指令的前綴和/或后綴表明了他們操作的類型:

例如,iadd將會(huì)將兩個(gè)integer數(shù)相加,dadd將兩個(gè)double類型的數(shù)相加?!?/span>const”、“load”、“store”指令帶一個(gè)后綴“_n”,對于loadstore來說,n是一個(gè)1-3的數(shù);對于const,對大的類型要根據(jù)類型而定。

 

const”指令將一個(gè)指定類型的數(shù)壓入棧頂,例如,“iconst_5”將一個(gè)integer型的5壓入棧,“dconst_1”將一個(gè)double型的1入棧。還有一個(gè)特殊的iconst_null,會(huì)將null入棧。

 

對于loadstore來說,n表示變量表中的位置來載入或者存入。“aload_0”指令將變量[0]壓入棧頂(通常是“this”)。“istore_1”將棧頂?shù)臄?shù)存入變量[1];對于更大的n,就不能使用后綴,而需要使用操作數(shù)。

 

3.2   基于棧的指令結(jié)構(gòu)

Java字節(jié)碼是“面向棧的編程語言”,類似的有X86的處理器,比如:

 

add eax, edx

mov ecx, eax


上面的指令將兩個(gè)數(shù)相加,并且將結(jié)果移到另一個(gè)地方,相似的字節(jié)碼類似下面:

 

0 iload_1

1 iload_2

2 iadd

3 istore_3


上面的代碼中,通過iadd指令,先將兩個(gè)數(shù)壓入棧,并且相加,將結(jié)果重新壓入棧。Istrore指令將棧頂?shù)闹狄迫刖植孔兞繀^(qū)。每個(gè)指令前面的數(shù),僅僅代表每個(gè)指令相對于方法開始的偏移量。一個(gè)“getName”方法,類似下面這樣:

 

Method java.lang.String getName()

0 aload_0       // The "this" object is stored in location 0 of the variable table

1 getfield #5       <Field java.lang.String name>

                // This instructon pops an object from the top of the stack, retrieves the specified

                // field from it, and pushes the field onto the stack.

                // In this example, the "name" field is the fifth field of the class.

4 areturn       // Returns the object on top of the stack from the method.

下面是另一個(gè)例子: 

outer

  for (int i = 2; i < 1000; i++) {

      for (int j = 2; j < i; j++) {

          if (i % j == 0)

              continue outer;

      }

      System.out.println (i);

  }

 

 0:   iconst_2

  1:   istore_1

  2:   iload_1

  3:   sipush  1000

  6:   if_icmpge       44

  9:   iconst_2

  10:  istore_2

  11:  iload_2

  12:  iload_1

  13:  if_icmpge       31

  16:  iload_1

  17:  iload_2

  18:  irem

  19:  ifne    25

  22:  goto    38

  25:  iinc    2, 1

  28:  goto    11

  31:  getstatic       #84; //Field java/lang/System.out:Ljava/io/PrintStream;

  34:  iload_1

  35:  invokevirtual   #85; //Method java/io/PrintStream.println:(I)V

  38:  iinc    1, 1

  41:  goto    2

  44:  return

 

4          參考

4.1   指令參考

1.本地下載的指令集合:“Instructions2.doc.html”,以及java虛擬機(jī)的書。

2.wiki  http://en.wikipedia.org/wiki/Java_bytecode

3.http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings 簡單指令集合

 

4.2   基于棧的程序體系

Stack-oriented programming language

http://en.wikipedia.org/wiki/Stack-oriented_programming_language

  

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JVM指令詳解(上)( 轉(zhuǎn))
Java對象和數(shù)組操作(二)
JVM字節(jié)碼指令集簡介
try-catch-finally中的return
關(guān)于Java虛擬機(jī)中的字節(jié)碼指令
JVM 字節(jié)碼指令
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服