中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

jd-gui 反編譯出現access$分析和函數說明什么

發布時間:2021-10-14 09:59:34 來源:億速云 閱讀:807 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關jd-gui 反編譯出現access$分析和函數說明什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

1)static Type access$iii(Outer); 是JAVA編譯器自動生成的十分重要的方法(該方法的個數由你的內部類要訪問的外部類的變量個數相關),目的是:用于內部類訪問外部類的數據成員時使用.

2)因此:JAVA編譯器在生成內部類的訪問外部類的數據成員時,會自動生成代碼來調用這個方法.
以你的代碼為例:內部類Inner中的方法
public int getDate() { 
return xx; 

生成的代碼如下:(經javap 處理后)
Java code

?

1 2 3 4 5 6 7 8 9 10 11 12public int getDate();  LineNumberTable:   line 120       Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   getfield        #1//Field this$0:LOuter;   4:   invokestatic    #3//Method Outer.access$000:(LOuter;)I   7:   ireturn


看代碼第4行:通過Outer.access$000(Outer o)來獲取外部類對象o中的private型的數據成員(請注意:這可是從另外一個類中訪問其它類的private型數據成員--不是通過反射技術)

3)進一步:
若外部類定義了兩個private 數據成員如下:
private int xx=12;
private float yy=12.4f;
這兩個數據成員在內部類中都要訪問,則編譯器會自動生成兩個access方法:
static int access$000(Outer);  用于內部類訪問private int xx;
static float access$100(Outer);  用于內部類訪問private float yy;

4)這種內部類訪問外部類中private數據成員的技術(不是通過反射!) 給安全留下了可能的小隱患(因為有些private數據成員是不提供外界訪問它的所謂的getter()的).為此,編譯器對自己自動生成的這些access$000()方法,在編譯時進行檢查,是不允許程序員直接來調用的.

但是:我們可以利用JAVA編譯器對類的編譯特性來繞過這個檢查:目的是,達到在自己的其它類中直接來調用這些access$000()方法.
這樣,我們可采用這個技術(即:在自己的類中--注意不是內部類,而是外部類中直接來調用這個access$000(Outer);)來訪問其它類的private的數據成員了.

具體技術演示如下:
第一步:定義如下的類:
class Outer { 
private final int xx = 123;  
//由于是final,故不再自動生成access$000(Outer);

public Inner getInner() { 
return new Inner(); 

public class Inner { 
public int getDate() { 
return xx; 

} //class Inner

 static int access$000(Outer)//這個是自已定義的!
 {
  return  1;
 } 


第二步:定義你的其它類,來直接調用這個access$000()方法
public class Test1
{
 public static void main(String[] args)
 {

  System.out.println(Outer.access$000(new Outer()));  //這個調用是沒有問題的,因為是自己定義的!
 }

}

將上述兩個JAVA文件編譯成class,成其是第二步的 Test1.class

第三步:這是變戲法的一步:
將第一步的類Outer改為如下:
class Outer { 
private  int xx = 123;  
//由于不是final,故自動生成access$000(Outer);

public Inner getInner() { 
return new Inner(); 

public class Inner { 
public int getDate() { 
return xx; 

} //class Inner
/*將這個第一步中自己定義的access$000去掉,因為編譯器會自動生成它!
 static int access$000(Outer {
  return  1;
 } */

重新編譯第三步中的這個類,而第二步中的類Test.class不動它. 此時,我們達到了這樣一個目的:在類Test1中調用了Outer類中編譯器自動生成的這個access$000(...)了.

----上篇借鑒別人的--

使用jd-gui反編譯后去掉注釋 /\*
*\d* *\*/

此處略作修改:\/\* *\d* *\*\/

去掉最后一行自動生成的注釋 /\* Location:[\S\s]+?(?=\*/)\*/$

.access$ 反編譯偶內部類調用外部類成員問題
很簡單的一個測試類源碼: 
public class testOuter {
private int a;
private int b;

private void fun() {
a += 1;
}

class testInner {
int x = 0;
testInner() {
b = 1;
a = 0;
fun();
}
}
編譯生成的Class文件:
class testOuter$testInner {
int x = 0;
testOuter$testInner(testOuter paramtestOuter) {
testOuter.access$002(paramtestOuter, 1);
testOuter.access$102(paramtestOuter, 0);
testOuter.access$200(paramtestOuter);
}
}
可以看出,為了使內部類訪問外部類的私有成員,編譯器生成了形似 “外部類.access$XYZ”的函數。XYZ為數字。X是按照私有成員在內部類出現的順序遞增的。8是 service , YZ為02的話,標明是基本變量成員;YZ為00的話標明是對象成員或者函數,YZ為08的話標明是對象成員或者函數。

這些參數可以得出一張表對應表,等待整理 

.....sionManager.access$102(..nManager.this, null);

關于jd-gui 反編譯出現access$分析和函數說明什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梅河口市| 定日县| 富蕴县| 天镇县| 余姚市| 南城县| 平潭县| 赤城县| 贡觉县| 乐陵市| 福安市| 石屏县| 遂平县| 大洼县| 东丽区| 寿光市| 广宗县| 黎川县| 华宁县| 阿勒泰市| 长海县| 双峰县| 河北区| 扶余县| 商水县| 资源县| 仲巴县| 彭山县| 宣威市| 东莞市| 隆安县| 邳州市| 扎赉特旗| 山阳县| 灵宝市| 丰台区| 德格县| 扶余县| 万山特区| 保靖县| 肥乡县|