您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關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 12 | public int getDate(); LineNumberTable: line 12 : 0
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$分析和函數說明什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。