2016-04-28 1 views
0

Tout, j'essayais de lire du code qui est généré à partir du jd-gui. Cela ressemble à ci-dessous.Comment comprendre le code synthétique de l'accesseur généré par 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)); 
     ... 
     } 
    } 

La classe agrPullingAgentStudy comprennent une classe interne nommée dcmStudySchedule. et dans la classe interne. Ce que je ne comprends pas, c'est le access$xxx que je savais déjà parce que si la classe interne essayait d'accéder aux membres de la classe externe, alors le code généré userait access$xxx pour représenter ce type de code. Je veux juste savoir s'il existe une solution de contournement pour résoudre ce problème. Ou Comment puis-je comprendre ce code? Merci.

Répondre

1

L'extrait suivant produira votre source décompilée.

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

Pour comprendre la agrPullingAgentStudy.access$002(new Date()) il est utile de faire une enquête au niveau de bytecode. Commencez par compiler la source javac agrPullingAgentStudy .java. Il génère deux fichiers *.class. agrPullingAgentStudy.class et agrPullingAgentStudy$dcmStudySchedule.class. (ok pas de surprise jusqu'à maintenant).

Pour accéder à la variable m_dAliveDT de la classe dcmStudySchedule, le compilateur génère une méthode synthétique dans agrPullingAgentStudy. La signature est static Date access$002(Date var0).

Comment arriver à cette conclusion? ... Simple: en utilisant javap.

javap -c -v agrPullingAgentStudy.class 

révèle le bytecode généré

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 

Le #1 se réfèrent à l'indice dans la piscine constante (sera également montré par la commande javap ci-dessus)

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

comme source Java, il ressemblerait

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

Salut Suboptimal, Merci votre belle explication. Quant à votre exemple. qu'est-ce que # 1 signifie dans le code de byte? Il semble qu'il représente le premier membre de la classe externe, et s'il y a beaucoup de membres là-dedans? Comment savoir quel membre représente le #number? Merci. –

+0

@ Joe.wang le '# 1' réfèrent à l'index dans le pool constant. Pour mieux comprendre la sortie de 'javap', il peut être utile de lire la [Java Virutal Machine Sepecification] (http://docs.oracle.com/javase/specs/) à propos du [format de fichier de la classe] (http: // docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html). – SubOptimal

+0

FYI, le décompilateur de Procyon devrait aligner les accesseurs synthétiques, et son désassembleur affiche des références de membre plus utiles que les simples indices de pool constant que javap montre. CFR fait aussi du bon travail avec les accesseurs synthétiques. –