Search code examples
javadecompilerjd-gui

How to understand the synthetic accessor code generated by jd-gui?


All , I was trying to read some code which is generated from the jd-gui. It looks like below.

    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));
       ...
      }
    }

The class agrPullingAgentStudy include an inner class named dcmStudySchedule. and in the inner class.

What I can not understand is the access$xxx which I already knew it is because if the inner class tried to access the outer class members then the generated code will user access$xxx to represent this kind of code. I just want to know if there is any workaround to fix this issue. Or How can I understand this code? Thanks.


Solution

  • Following snippet will produce your decompiled source.

    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();
            }
        }
    }
    

    To understand the agrPullingAgentStudy.access$002(new Date()) it's helpful to do some investigation on the bytecode level.

    First compile the source javac agrPullingAgentStudy .java. It generates two *.class files. agrPullingAgentStudy.class and agrPullingAgentStudy$dcmStudySchedule.class. (ok no surprice till now).

    To access the variable m_dAliveDT from class dcmStudySchedule the compiler generates a synthetic method in agrPullingAgentStudy. The signature is static Date access$002(Date var0).

    How do come to this conclusion? ... Simple: using javap.

    javap -c -v agrPullingAgentStudy.class
    

    reveals the generated bytecode

    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
    

    The #1 refer to the index in the constant pool (will also be shown by the above javap command)

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

    As Java source it would look like

    static Date access$002(Date d) {
        m_dAliveDT = d;               // putstatic #1
        return d;                     // areturn
    }