这是什么引用?

4
假设我有这个类:
public class class1 extends Applet implements Runnable
{
    private String s;
    private URL u;
    ...
}

还有第二个类:

class TS extends Thread
{
    private final class1 _$97913;
    public TS(class1 paramclass1)
    {
        this._$97913 = paramclass1;
    }
    ...
    public void PostData()
    {
        ...
        class1.access$16(this._$97913, new Socket(class1.access$17(this._$97913), 80);
        ...
    }
    ...
}

有人能解释一下 class1.access$16(this._$97913, new Socket(class1.access$17(this._$97913), 80); 如何引用 class1 中的 private URL u; 吗? access$16 是从哪里来的?这个被称为什么,我在哪里可以了解更多关于它的信息?
好的,由于这是反编译代码的结果,有没有一种方法将数字(如 access$16access$17 等)与原始变量或类相关联呢?据我所见,唯一的方法可能是手动进行(即查看引用的位置并猜测 'this' 类接收到了一个 URL,那么 'this' 必须与 'that' 变量相关联)。
2个回答

5

这是反编译Java代码的结果吗?

看起来像是一个合成方法,用于允许外部类和内部类互相访问私有字段或方法。

当封闭类访问具有私有修饰符的嵌套类的属性时,Java编译器必须在嵌套类上创建合成方法。下面的代码示例说明了这种情况。

...

如上面的屏幕截图所示,合成方法access$100已经在嵌套类NestedClass上创建,以将其私有字符串提供给封闭类。请注意,仅为封闭类访问的NestedClass的单个私有属性添加了合成方法。


它看起来像是一个合成方法。它看起来很可怕。FTFY。 - Finbarr
是的,这是反编译代码。感谢您的快速回答。这回答了我对此的大部分疑问。 - Josh C.
说真的,这绝对看起来像是一个合成方法。+1 - Finbarr
@Josh:如果这个回答没有解决你所有的问题,可以在你的问题下面添加剩余的问题(有一个编辑按钮)。当你所有的问题都得到了解答,就可以将最佳答案标记为“已接受”。 - Paŭlo Ebermann
据我所知,cfr反编译器可以很好地处理这些。 - Tamas Rev

4
好的,这是反编译代码的结果,有没有一种方法可以将数字(access$16access$17等)与原始变量或类关联起来?从我所看到的情况来看,唯一的方法就是手动关联(即查看被引用的内容在哪里,并猜测由于'this'类接收了一个URL,因此'this'必须与'that'变量关联)。 access$x方法是在从嵌套类中访问私有方法或变量(或者反过来,或者从一个嵌套类到另一个嵌套类)时创建的。它们是由编译器创建的,因为虚拟机不允许直接访问私有变量。
如果反编译器让这些方法调用留在使用类的重新创建源代码中,它应该也让合成方法定义留在使用的类的重新创建源代码中。如果是这样,请查看接收该方法的类(class1在您的情况下),应该有这样的方法(access$17)。在该方法的代码中,您可以看到在此处访问了哪个真实方法(或变量)。
如果反编译器删除了合成方法,则可能是一个错误,或者它可能是可配置的。也可能是您必须一次传递所有类,然后它可以在所有地方放入正确的方法/字段-请查看其文档。
如果您有一个方法调用的点之前的类(以及它们的超类,如果有的话),那么您应该有这些方法。
从您发布的片段中,class1应该有一个access$16access$17方法(或者在这里class1是一个局部变量吗?)。
如果没有,也许你的反编译器试图比它应该更聪明。您可以查看javap class1的输出,看看方法是否存在,以及javap -c class1的整个字节码。或者使用另一个反编译器。

class1创建一个新的TS实例this.var = new xplug.SI(this);(var是private class1.TS var)不幸的是,没有可用的文档可以查看。在class1中没有access$17方法,我怀疑这不是一个错误。虽然可能性较小,但我认为也有可能是我缺少包含这些方法的文件。 - Josh C.
无论如何,非常感谢您的帮助。我会从这里开始尝试解决问题。 - Josh C.
我刚刚看到了你的最新编辑,它非常有用。从我的观察来看,似乎我可能缺少一个类文件或者它被配置为这种编译方式。以下是让我这么想的原因:起初,我反编译了class1.class文件,发现有很多access$x方法被调用,但是找不到它们的位置。之后,我得到了class1$TS.class文件。再次反编译后,一些access$x引用被正确的方法/变量替换了。所以看起来我可能缺少了一个额外的类文件。再次感谢你的帮助。 - Josh C.
我应该能够通过现有的字节码重新创建缺失的方法,无论这样做是否繁琐。 - Josh C.
@Josh:不要重新创建缺失的access$*方法,而是让你的类再次嵌套在彼此之中,并直接使用所访问的字段/方法。(或将这些更改为默认访问而不是私有访问,但这可能会干扰继承。)这样做不会更加繁琐,而且生成的代码将更接近原始代码。 - Paŭlo Ebermann
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接