Как понять синтетический код доступа, сгенерированный jd-gui?

Все, я пытался прочитать какой-то код, сгенерированный из jd-gui. Похоже ниже.

    public class agrPullingAgentStudy
    {
      private static final String PGPR_ID = "agrPullingAgentStudy";
      private static Timer m_tmStudy = null;
      private static Timer m_tmNonStop = null;
      private static Timer m_tmRemove = null;
      private static String m_szManual = "";
      private static String m_szProcRule = "";
      private static String m_szExecHosp = "";
      private static HashMap<String, HashMap> m_hRemoteAll = new HashMap();
      private static HashMap<String, String> m_hProcRule = null;
      private static int m_nImageAfterMins = -120;
      private static boolean m_bDoProcess = false;
      private static Date m_dAliveDT = new Date();
      private static final String LINE_SEP = System.getProperty("line.separator");
    ....



      private class dcmStudySchedule
        extends TimerTask
      {

        public void run()
        {
          String FUN_ID = "runStudySchedule";
          StringBuffer szBuffer = new StringBuffer();
          agrPullingAgentStudy.access$002(new Date());

          ...
        }


       ....
       agrPullingAgentStudy.access$402(agrPullingAgentStudy.m_szExecHosp.substring(0, agrPullingAgentStudy.m_szExecHosp.length() - 1));
       ...
      }
    }

Класс agrPullingAgentStudy включить внутренний класс с именем dcmStudySchedule. и во внутреннем классе.

Что я не могу понять, так это access$xxx что я уже знал, это потому, что если внутренний класс попытался получить доступ к членам внешнего класса, то сгенерированный код будет использовать access$xxx представлять этот вид кода. Я просто хочу знать, есть ли способ обойти эту проблему. Или как я могу понять этот код? Благодарю.

1 ответ

Решение

Следующий фрагмент даст ваш декомпилированный источник.

import java.util.Date;
import java.util.TimerTask;

public class agrPullingAgentStudy {

    private static Date m_dAliveDT = new Date();

    private class dcmStudySchedule extends TimerTask {

        public void run() {
            m_dAliveDT = new Date();
        }
    }
}

Чтобы понять agrPullingAgentStudy.access$002(new Date()) полезно провести некоторое исследование на уровне байт-кода.

Сначала скомпилируйте источник javac agrPullingAgentStudy .java, Генерирует два *.class файлы. agrPullingAgentStudy.class а также agrPullingAgentStudy$dcmStudySchedule.class, (ОК, ничего удивительного до сих пор).

Для доступа к переменной m_dAliveDT из класса dcmStudySchedule компилятор генерирует синтетический метод в agrPullingAgentStudy, Подпись static Date access$002(Date var0),

Как прийти к такому выводу? ... просто: с помощью javap,

javap -c -v agrPullingAgentStudy.class

показывает сгенерированный байт-код

static java.util.Date access$002(java.util.Date);
  descriptor: (Ljava/util/Date;)Ljava/util/Date;
  flags: ACC_STATIC, ACC_SYNTHETIC
  Code:
    stack=2, locals=1, args_size=1
       0: aload_0
       1: dup
       2: putstatic     #1        // Field m_dAliveDT:Ljava/util/Date;
       5: areturn

#1 обратитесь к индексу в константном пуле (также будет показано выше javap команда)

Constant pool:
   #1 = Fieldref       #5.#21   // agrPullingAgentStudy.m_dAliveDT:Ljava/util/Date;
...

В качестве источника Java это будет выглядеть

static Date access$002(Date d) {
    m_dAliveDT = d;               // putstatic #1
    return d;                     // areturn
}
Другие вопросы по тегам