2010-07-21 8 views
7
  1. In che modo è possibile creare campi sintetici in Java?Come creare campi sintetici in java?

  2. È possibile creare campi sintetici in java solo in fase di esecuzione? In caso contrario: C'è un modo standard-compliant a questo al momento della compilazione (senza modificare alcuni byte nel file di classe)

+2

Perché si desidera creare manualmente un campo sintetico? Questo è un po 'contro la sua specifica, dal momento che dice "è qualcosa che il compilatore ha fatto per abilitare un comportamento specifico". Qualsiasi cosa tu voglia fare manualmente dovrebbe essere visibile all'esterno come tale. – perdian

risposta

14

Sono creati dal compilatore quando "stranezze" del linguaggio li richiedono. Un semplice esempio di questo utilizza una classe interna:

public class Test 
{ 
    class Inner 
    { 
    } 
} 

La classe Test.Inner avrà un campo sintetico per rappresentare l'istanza appropriata della classe Test.

Possiamo estendere questo codice un po 'per dimostrare che campo:

import java.lang.reflect.*; 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     for (Field field : Inner.class.getDeclaredFields()) 
     { 
      System.out.println(field.getName() + ": " + field.isSynthetic()); 
     } 
    } 

    class Inner 
    { 
    } 
} 

Con il mio compilatore, che le stampe:

this$0: true 
3

Sì, è fattibile, e si chiama load-time tessitura. Essenzialmente, dovrai definire il tuo ClassLoader che deciderà su un caso classe per classe se modificare un file di classe che deve essere caricato; ciò significa che dovrai ispezionare la classe binaria che viene caricata, eventualmente modificarla, quindi passarla alla JVM per definizione/risoluzione. È un po 'macchinoso, complicato e soggetto a ClassCastExceptions (la stessa classe definita in 2 diversi classloader darà 2 classi diverse che non sono compatibili con l'assegnazione).

Si noti che la tessitura consente di fare molto di più: è possibile aggiungere nuovi metodi, interfacce, campi, modificare il codice delle classi esistenti e altro.

Ci sono già degli strumenti che possono aiutarti - vedi ad esempio AspectJ come modifica linguistica completa, o qualcosa come BCEL o javassist che ti permette di scrivere questi strumenti di tessitura.