Что это за ссылка? - PullRequest
       0

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

4 голосов
/ 02 апреля 2011

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

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; из класса 1?

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

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

Ответы [ 2 ]

5 голосов
/ 02 апреля 2011

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

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

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

...

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

4 голосов
/ 02 апреля 2011

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

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

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

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


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

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

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

...