Что это за отсылка?

Предположим, у меня есть этот класс:

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); ссылается на private URL u; из class1?

Откуда access$16? Как это называется и где можно узнать об этом подробнее?

Хорошо, это результат декомпилированного кода, есть ли способ связать числа (access$16, access$17 и т. д.) с исходной переменной или классом? Из того, что я вижу, единственный способ - сделать это вручную (т. Е. Посмотреть, на что ссылаются, и предположить, что, поскольку «этот» класс получил URL-адрес, «это» должно быть связано с «той» переменной)?


person Josh C.    schedule 02.04.2011    source источник


Ответы (2)


Хорошо, это результат декомпилированного кода, есть ли способ связать числа (access$16, access$17 и т. д.) с исходной переменной или классом? Из того, что я вижу, единственный способ - сделать это вручную (т. Е. Посмотреть, на что ссылаются, и предположить, что, поскольку «этот» класс получил URL-адрес, «это» должно быть связано с «той» переменной)?

Методы access$x создаются, если вы обращаетесь к закрытым методам или переменным из вложенного класса (или наоборот, или из одного вложенного класса в другой). Они создаются компилятором, так как виртуальная машина не разрешает прямой доступ к приватным переменным.

Если декомпилятор позволяет вызовам этих методов оставаться в воссозданном исходном коде для используемого класса, он также должен оставить определения синтетических методов в воссозданном исходном коде для используемого класса. Если это так, посмотрите на класс, который является получателем рассматриваемого метода (class1 в вашем случае), такой метод должен быть (access$17). В коде этого метода вы можете видеть, к какому реальному методу (или переменной) здесь обращаются.

Если декомпилятор удалил синтетические методы, это либо ошибка, либо это можно настроить. Также может быть, что вам нужно передать ему все классы сразу, и тогда он сможет везде вставить правильные методы/поля - посмотрите его документацию.


Если у вас есть классы перед точкой вызова метода (и их суперклассы, если таковые имеются), вы должны иметь методы.

Из фрагмента, который вы разместили, в class1 должны быть методы access$16 и access$17 (или class1 здесь локальная переменная?).

Если это не так, возможно, ваш декомпилятор пытался быть умнее, чем должен. Вы можете посмотреть вывод javap class1, чтобы увидеть, есть ли там методы, и javap -c class1 для всего байт-кода. Или используйте другой декомпилятор.

person Paŭlo Ebermann    schedule 02.04.2011
comment
class1 создает новый экземпляр TS this.var = new xplug.SI(this); (var равен private class1.TS var) К сожалению, документации для просмотра нет. В class1 нет метода access$17, и я сомневаюсь, что это ошибка. Я думаю, что также может быть, хотя и менее вероятно, что мне не хватает файла, содержащего эти методы. - person Josh C.; 02.04.2011
comment
(ошибка в декомпиляторе, я имел в виду.) - person Paŭlo Ebermann; 02.04.2011
comment
В любом случае, большое спасибо за вашу помощь. Я посмотрю, что я могу сделать с этим отсюда. - person Josh C.; 02.04.2011
comment
См. мое последнее редактирование для более подробной информации об этом. (Меня прервали, когда я начал печатать, поэтому только сейчас.) - person Paŭlo Ebermann; 02.04.2011
comment
Я только что видел ваше последнее редактирование, и оно оказалось очень полезным. Из того, что я могу сказать, кажется, что мне либо не хватает файла класса, либо он был настроен для компиляции таким образом. Вот что заставляет меня так думать: сначала я декомпилировал файл class1.class, и в нем было вызвано много access$x методов, которых нигде не было. После этого я получил файл class1$TS.class. После того, как я снова декомпилировал его, некоторые из ссылок access$x были заменены правильным методом/переменной. Так что кажется, что мне может не хватать дополнительного файла класса. Еще раз спасибо за вашу помощь. - person Josh C.; 03.04.2011
comment
Я должен быть в состоянии воссоздать отсутствующие методы благодаря доступному байт-коду, как бы утомительно это ни было. - person Josh C.; 03.04.2011
comment
@Josh: Вместо того, чтобы воссоздавать отсутствующие методы access$*, позвольте вашим классам снова вкладываться друг в друга и напрямую использовать поля/методы, к которым осуществляется доступ. (Или измените их на доступ по умолчанию вместо частного, но это может помешать наследованию.) Это будет не более утомительно, а результирующий код будет ближе к оригиналу. - person Paŭlo Ebermann; 03.04.2011

Это результат декомпиляции java?

Это похоже на синтетический метод, созданный для того, чтобы внешние и внутренние классы доступ к закрытым полям или методам друг друга.

Компилятор Java должен создавать синтетические методы во вложенных классах, когда к их атрибутам, указанным с помощью модификатора private, обращается охватывающий класс. Следующий пример кода указывает на эту ситуацию.

...

Как показано на приведенном выше снимке экрана, синтетический метод с именем access$100 был создан для вложенного класса NestedClass, чтобы предоставить его частную строку String включающему классу. Обратите внимание, что синтетический метод добавляется только для одного закрытого атрибута NestedClass, к которому обращается объемлющий класс.

person Mike Samuel    schedule 02.04.2011
comment
It looks like a synthetic method Выглядит ужасно. FTFY - person Finbarr; 02.04.2011
comment
Да, это из декомпилированного кода. И спасибо за быстрый ответ. Это отвечает на большинство моих вопросов, которые у меня были по этому поводу. - person Josh C.; 02.04.2011
comment
А если серьезно, то определенно похоже на синтетический метод. +1 - person Finbarr; 02.04.2011
comment
@Josh: Если он не отвечает на все вопросы, добавьте оставшиеся вопросы к своему вопросу (есть кнопка редактирования). Когда на все ваши вопросы будут даны ответы, отметьте лучший ответ как принятый. - person Paŭlo Ebermann; 02.04.2011
comment
Насколько я мог убедиться, декомпилятор cfr вполне справляется с этим. - person Tamas Rev; 05.07.2017