Che cos'è una classe sintetica in Java? Perché dovrebbe essere usato? Come posso usarlo?
Che cos'è una classe sintetica in Java? Perché dovrebbe essere usato? Come posso usarlo?
Risposte:
Ad esempio, quando si dispone di un'istruzione switch, java crea una variabile che inizia con $. Se vuoi vedere un esempio di questo, dai un'occhiata al riflesso Java di una classe che contiene un'istruzione switch. Vedrai queste variabili quando hai almeno un'istruzione switch in qualsiasi punto della classe.
Per rispondere alla tua domanda, non credo che tu sia in grado di accedere (oltre alla riflessione) alle classi sintetiche.
Se stai analizzando una classe di cui non sai nulla (tramite la riflessione) e hai bisogno di sapere cose molto specifiche e di basso livello su quella classe, potresti finire con l'uso di metodi di riflessione Java che hanno a che fare con le classi sintetiche. L'unico "uso" qui è ottenere maggiori informazioni sulla classe per usarla in modo appropriato nel tuo codice.
(Se lo stai facendo, probabilmente stai costruendo un quadro di alcuni tipi che altri sviluppatori potrebbero usare.)
Altrimenti, se non stai usando la riflessione, non ci sono usi pratici di classi sintetiche che conosco.
Java ha la capacità di creare classi in fase di esecuzione. Queste classi sono conosciute come classi sintetiche o proxy dinamici.
Vedere http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html per ulteriori informazioni.
Altre librerie open-source, come CGLIB e ASM, consentono anche di generare classi sintetiche e sono più potenti delle librerie fornite con JRE.
Le classi sintetiche sono utilizzate dalle librerie AOP (Aspect Oriented Programming) come Spring AOP e AspectJ, nonché dalle librerie ORM come Hibernate.
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
dice: restituisce vero se questo membro è stato introdotto dal compilatore; restituisce false altrimenti.
java.lang.reflect.Member#isSynthetic
sia irrilevante per la domanda originale. I membri sono campi, costruttori e metodi. La domanda originale riguardava le classi sintetiche , non i membri sintetici. In Java 8, le espressioni lambda danno origine a classi sintetiche - non sono sicuro di quali altre circostanze possano sorgere.
Bene ho trovato la risposta alla prima domanda su google:
Una classe può essere contrassegnata come sintetica se viene generata dal compilatore, ovvero non viene visualizzata nel codice sorgente.
Questa è solo una definizione di base, ma l'ho trovata in un thread del forum e non c'erano spiegazioni. Sto ancora cercando uno migliore ...
classi / metodi / campi sintetici:
Queste cose sono importanti per la VM. Dai un'occhiata al seguente frammento di codice:
class MyOuter {
private MyInner inner;
void createInner() {
// The Compiler has to create a synthetic method
// to construct a new MyInner because the constructor
// is private.
// --> synthetic "constructor" method
inner = new MyInner();
// The Compiler has to create a synthetic method
// to doSomething on MyInner object because this
// method is private.
// --> synthetic "doSomething" method
inner.doSomething();
}
private class MyInner {
// the inner class holds a syntetic ref_pointer to
// the outer "parent" class
// --> synthetic field
private MyInner() {
}
private void doSomething() {
}
}
}
Secondo questa discussione , sebbene la specifica del linguaggio descriva una proprietà "isSintetica" per le classi, questa viene praticamente ignorata dalle implementazioni e non viene utilizzata per proxy dinamici o classi anonime. I campi sintetici e i costruttori vengono utilizzati per implementare le classi nidificate (non esiste il concetto di classi nidificate nel codice byte, solo nel codice sorgente).
Penso che il concetto di classi sintetiche abbia semplicemente dimostrato di non essere utile, cioè a nessuno importa se una classe sia sintetica. Con campi e metodi, è probabilmente usato esattamente in un punto: per determinare cosa mostrare in una vista della struttura di classe IDE - vuoi che vengano mostrati metodi e campi normali, ma non quelli sintetici usati per simulare le classi nidificate. OTOH, vuoi che vengano mostrate lezioni anonime lì.
Sono creati da JVM in fase di esecuzione quando invocano membri privati della classe interna a scopo di debug
I metodi, i campi, la classe creata da JVM durante l'esecuzione per il suo scopo di esecuzione sono chiamati Synthetic
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
Anche le classi sintetiche o i proxy dinamici vengono utilizzati da EasyMock per creare implementazioni di interfacce o classi astratte in fase di esecuzione.
Quando il compilatore Java compila determinati costrutti, come le classi interne, crea costrutti sintetici ; si tratta di classi, metodi, campi e altri costrutti che non hanno un costrutto corrispondente nel codice sorgente.
Usi:
costrutti sintetici consentono ai compilatori Java di implementare nuove funzionalità del linguaggio Java senza modifiche alla JVM. Tuttavia, i costrutti sintetici possono variare tra le diverse implementazioni del compilatore Java, il che significa che anche i file .class possono variare tra le diverse implementazioni.
riferimento: docs.oracle.com
Come hanno già indicato varie risposte, al compilatore è consentito generare vari costrutti (comprese le classi) che non corrispondono direttamente a qualcosa nel codice Souce. Questi devono essere contrassegnati come sintetici:
Una rappresentazione binaria per una classe o un'interfaccia deve contenere anche tutti i seguenti elementi:
[...]
11. Un costrutto emesso da un compilatore Java deve essere contrassegnato come sintetico se non corrisponde a un costrutto dichiarato esplicitamente o implicitamente nel codice sorgente , a meno che il costrutto emesso non sia un metodo di inizializzazione di classe (JVMS §2.9).
[...]
Come sottolineato da @Holger in un commento a un'altra domanda, esempi rilevanti per tali costrutti sono gli oggetti Class che rappresentano riferimenti a metodi e lambdas:
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
Produzione:
true
true
Sebbene ciò non sia esplicitamente menzionato, segue il 15.27.4. Valutazione run-time delle espressioni lambda :
Il valore di un'espressione lambda è un riferimento a un'istanza di una classe con le seguenti proprietà: [...]
e la dicitura quasi identica per i riferimenti ai metodi ( 15.13.3. Valutazione run-time dei riferimenti ai metodi ).
Poiché questa classe non è esplicitamente menzionata in nessun punto del codice sorgente, deve essere sintetica.
Se lo capisco bene, una classe sintetica viene generata al volo, senza dover dargli un nome esplicito. Per esempio:
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
Questo crea una sottoclasse sintetica di Thread e sovrascrive il suo metodo run (), quindi lo crea un'istanza e lo avvia.
Outer$1.class
.
Una classe sintetica non appare nel tuo codice: è composta dal compilatore. Ad esempio, un metodo bridge creato dal compilatore in Java è in genere sintetico.
public class Pair<T> {
private T first;
private T second;
public void setSecond(T newValue) {
second = newValue;
}
}
public class DateInterval extends Pair<String> {
public void setSecond(String second) {
System.out.println("OK sub");
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
DateInterval interval = new DateInterval();
Pair pair = interval;
pair.setSecond("string1");
}
}
Usando il comando javap -verbose DateInterval
, puoi vedere un metodo bridge:
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Questo è stato creato dal compilatore; non appare nel tuo codice.
Che cos'è una classe sintetica in Java?
Una synthetic
classe è un .class
file generato da Java Compiler e non esiste nel codice sorgente.
Esempio di utilizzo della synthetic
classe: classe interna anonima
synthetic
classe ed è una classe interna anonima all'interno di java.text.DigitListDigitList$1.java
ma è un file interno inDigitList.java
Perché dovrebbe essere usato?
È un meccanismo all'interno della logica del compilatore Java per generare il .class
file
Come posso usarlo?
No, gli sviluppatori NON lo usano direttamente.
Il compilatore Java utilizza synthetic
per generare il .class
file, quindi JVM legge il .class
file per eseguire la logica del programma.
I costrutti sintetici sono classi, metodi, campi ecc. Che non hanno un costrutto corrispondente nel codice sorgente. I costrutti sintetici consentono ai compilatori Java di implementare nuove funzionalità del linguaggio Java senza modifiche alla JVM. Tuttavia, i costrutti sintetici possono variare tra le diverse implementazioni del compilatore Java, il che significa che anche i file .class possono variare tra le diverse implementazioni.