当前位置: 首页 > 工具软件 > jd2xx > 使用案例 >

java access$ jd gui_jd-gui 反编译出现access$分析和函数说明

邓声
2023-12-01

1)static

Type

access$

iii

(Outer); 是JAVA编译器自动生成的十分重要的方法(该方法的个数由你的内部类要访问的外部类的变量个数相关),目的是:

用于内部类访问外部类的数据成员时使用

.

2)因此:JAVA编译器在生成内部类的访问外部类的数据成员时,会

自动生成代码来调用这个方法

.

以你的代码为例:内部类Inner中的方法

public int getDate() {

return xx;

}

生成的代码如下:(经javap 处理后)

Java code

代码第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);

 类似资料: