一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java class文件格式之訪問標志信息_動力節點Java學院整理

Java class文件格式之訪問標志信息_動力節點Java學院整理

2020-11-17 11:02zhangjg Java教程

access_flags 描述的是當前類(或者接口)的訪問修飾符, 如public, private等, 此外, 這里面還存在一個標志位, 標志當前的額這個class描述的是類, 還是接口

class文件中的訪問標志信息

位于常量池下面的2個字節是access_flags 。 access_flags 描述的是當前類(或者接口)的訪問修飾符, 如public, private等, 此外, 這里面還存在一個標志位, 標志當前的額這個class描述的是類, 還是接口。access_flags 的信息比較簡單, 下面列出access_flags 中的各個標志位的信息。本來寫這個系列博客參考的是《深入java虛擬機》, 但是這本書比較老了, 關于java 5以后的新特性沒有進行解釋,這本書中指列出了5個標志值, 而最新的jvm規范是針對java 7 的, 其中加入了額外的三個標志位。 分別是acc_synthetic, acc_annotation 和 acc_enum  。

 

標志名
標志值
標志含義
針對的對像
acc_public
0x0001
public類型
所有類型
acc_final
0x0010
final類型
acc_super
0x0020
使用新的invokespecial語義
類和接口
acc_interface
0x0200
接口類型
接口
acc_abstract
0x0400
抽象類型
類和接口
acc_synthetic
0x1000
該類不由用戶代碼生成
所有類型
acc_annotation 
0x2000
注解類型
注解
acc_enum  
0x4000
枚舉類型
枚舉

 

其他標志就不做介紹了, 這些標志都很簡單。 讀者感覺比較陌生的可能是acc_super這個標志。 讀者會想, 類型不能被super關鍵字修飾啊, 那這個acc_super是做什么的呢?表中可以看出, 它的含義是:使用新的invokespecial語義 。 invokespecial是一個字節碼指令, 用于調用一個方法, 一般情況下, 調用構造方法或者使用super關鍵字顯示調用父類的方法時, 會使用這條字節碼指令。 這正是acc_super這個名字的由來。 在java 1.2之前, invokespecial對方法的調用都是靜態綁定的, 而acc_super這個標志位在java 1.2的時候加入到class文件中, 它為invokespecial這條指令增加了動態綁定的功能。 這里可能有幾個概念讀者不是很明白, 如靜態綁定, 動態綁定等, 這些概念會在以后的博客中詳細介紹。

還有一點需要說明, 既然access_flags 出現在class文件中的類的層面上, 那么它只能描述類型的修飾符, 而不能描述字段或方法的修飾符, 希望讀者不要將這里的access_flags 和后面要介紹的方法表和字段表中的訪問修飾符相混淆。

此外, 在java 5 的中, 引入和注解和枚舉的新特性, 那么可以推測,  acc_annotation 和 acc_enum是在java 5版本中加入的。 class文件雖然總體上保持前后一致性, 但他也不是一成不變的, 也會跟著java版本的提升而有所改變, 但是總體來說, class文件格式還是相對穩定的, 變動的地方不是很多。 

class文件中的this_class

訪問標志access_flags 下面的兩個字節叫做this_class, 它是對當前類的描述。 它的兩個字節的數據是對常量池中的一個constant_class_info數據項的一個索引。 constant_class_info在上面的文章中已經介紹過了。 constant_class_info中有一個字段叫做name_index , 指向一個constant_utf8_info , 在這個constant_utf8_info 中存放著當前類的全限定名。 

如果當前類為person:

?
1
2
3
4
5
6
7
8
9
10
package combjpowernodetest;
 
public class person {
 
 int age;
 
 int getage(){
  return age;
 }
}

將person.class反編譯后, 可以在常量池中看到如下兩項:

?
1
2
3
4
5
6
constant pool:
 #1 = class    #2    // com/bjpowernode/test/person
 #2 = utf8    com/bjpowernode/test/person
  
.........
.........

這兩項就是當前類的信息。 其中索引為1的constant_class_info會被class文件中的this_class所引用。 下面給出示例圖(其中虛線范圍內表示常量池的區域):

 Java class文件格式之訪問標志信息_動力節點Java學院整理

class文件中的super_class

super_class緊跟在this_class之后。 它和this_class一樣是一個指向常量池數據項的索引。 它指向一個constant_class_info, 這個constant_class_info數據項描述的是當前類的超類的信息。constant_class_info中的name_index指向常量池中的一個constant_utf8_info ,constant_utf8_info 中存放的是當前類的超類的全限定名。 如果沒有顯式的繼承一個,也就是說如果當前類是直接繼承object的, 那么super_class值為0 。 我們在前面的文章中提到過, 如果一個索引值為0, 那么就說明這個索引不引用任何常量池中的數據項, 因為常量池中的數據項是從1開始的。 也就是說, 如果一個類的class文件中的super_class為0 , 那么就代表該類直接繼承object類。 

下面以代碼來說明:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package combjpowernodetest;
 
public class programer extends person{
 
 computer computer;
  
 public programer(computer computer){
  thiscomputer = computer;
 }
  
 public void dowork(){
  computercalculate();
 }
}

上面的programer類繼承自person類。 那么反編譯programer .class , 它的常量池中會存在如下信息:

?
1
2
3
4
5
6
7
constant pool:
 
.........
.........
 
 #3 = class    #4    // com/bjpowernode/test/person
 #4 = utf8    com/bjpowernode/test/person

這兩項就是當前類的父類的信息。 其中索引為3的constant_class_info會被class文件中的super_class引用。 下面給出示例圖(其中虛線范圍內表示常量池的區域):

Java class文件格式之訪問標志信息_動力節點Java學院整理

class文件中的interfaces_count和interfaces

緊接著super_class的是interfaces_count, 表示當前類所實現的接口的數量或者當前接口所繼承的超接口的數量。 注意, 只有當前類直接實現的接口才會被統計, 如果當前類繼承了另一個類, 而另一個類又實現了一個接口, 那么這個接口不會統計在當前類的interfaces_count中。 在interfaces_count后面是interfaces, 他可以看做是一個數組, 其中的每個數組項是一個索引, 指向常量池中的一個constant_class_info, 這個constant_class_info又會引用常量池中的一個constant_utf8_info , 這個constant_utf8_info 中存放著有當前類型直接實現或繼承的接口的全限定名。 當前類型實現或繼承了幾個接口, 在interfaces數組中就會有幾個數項與之相對應。 

下面看代碼示例:

?
1
2
3
4
5
6
7
8
9
package combjpowernodetest;
 
public class plane implements iflyable, cloneable{
 
 @override
 public void fly() {
   
 }
}

plane類實現了一個自定義的iflyable接口, 還實現了一個jdk中的cloneable接口, 那么它的常量池中會有如下信息:

?
1
2
3
4
5
6
7
8
9
10
11
12
constant pool:
 
.........
.........
 
 #5 = class    #6    // com/bjpowernode/test/iflyable
 #6 = utf8    com/bjpowernode/test/iflyable
 #7 = class    #8    // java/lang/cloneable
 #8 = utf8    java/lang/cloneable
  
.........
.........

這四項數據就是當前的plane類所實現的接口的信息。 第五項和第六項描述了plane所實現的iflyable接口, 第七項和第八項描述了plane所實現的接口cloneable接口。 下面是示意圖(其中虛線范圍內表示常量池的區域):

Java class文件格式之訪問標志信息_動力節點Java學院整理

總結

主要講解了三個部分, 分別是this_class , super_class , interfaces_count和interfaces 。 這三個數據項分別描述了當前類(就是當前class文件所在的類), 當前類所繼承的超類, 和當前類所實現的接口(如果當前class文件代表的是一個接口, 那么 interfaces_count和interfaces描述的是當前接口所繼承的超接口)。

這幾個數據項都持有指向常量池的索引。 真實的信息都是存放在常量池中的, 只不過常量池中的這些信息會被this_class , super_class , interfaces_count和interfaces 引用。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美人与禽杂交大片 | 国产精品美女福利视频免费专区 | 亚洲成人精品久久 | 99热在线这里只有精品 | 国产精品天天看特色大片不卡 | 好女孩韩剧免费观看 | 国产丰满美女做爰 | 51精品| 国产视频在线一区 | 动漫美女被褥吸奶漫画漫画 | 极品 女神校花 露脸91 | 男人的j放进女人的p全黄 | 精品欧美一区二区三区久久久 | 香蕉免费看一区二区三区 | 好湿好紧太硬了我太爽了网站 | 国产一区二区三区久久精品小说 | pregnant欧美孕交xxx | 污书屋 | 亚洲精品视频久久 | 国产成人福利美女观看视频 | 熟睡中的麻麻大白屁股小说 | 99热精品久久 | 欧美日韩成人在线视频 | 精品日韩二区三区精品视频 | 日本护士撒尿 | 摄像头东北对白清晰 | 九九365资源稳定资源站 | 丝袜足控免费网站xx动漫漫画 | 日韩精品视频在线观看免费 | 国产精品视频一区二区三区经 | 色综合久久中文字幕综合网 | 国产欧美综合一区二区 | 欧美精品成人a多人在线观看 | 手机在线免费观看高清 | 性妲己 | 天天爽天天 | 亚洲精品www久久久久久久软件 | 国产麻豆流白浆在线观看 | 办公室大战秘书呻吟 | 久久综合中文字幕佐佐木希 | 日本一区二区三区视频在线观看 |