Alle "Nicht in Ihrem Code" -Antworten sind mit Java 8 veraltet, da Lambdas als synthetische (nicht anonyme) Klassen implementiert werden können.
OrangeDog
Um fair zu sein, ist ein Lambda immer noch nicht "streng" eine Klasse, die explizit in Ihrem Code definiert ist. "Nicht in Ihrem Code" ist also weiterhin gültig. Der Compiler generiert die synthetischen Klassen für Sie ohne explizite Definition in Ihrem Code.
ManoDestra
Antworten:
15
Wenn Sie beispielsweise eine switch-Anweisung haben, erstellt Java eine Variable, die mit einem $ beginnt. Wenn Sie ein Beispiel dafür sehen möchten, werfen Sie einen Blick in die Java-Reflexion einer Klasse, die eine switch-Anweisung enthält. Sie sehen diese Variablen, wenn Sie irgendwo in der Klasse mindestens eine switch-Anweisung haben.
Um Ihre Frage zu beantworten, glaube ich nicht, dass Sie auf die synthetischen Klassen zugreifen können (außer auf Reflexion).
Wenn Sie eine Klasse analysieren, von der Sie nichts wissen (über Reflektion) und sehr spezifische und einfache Dinge über diese Klasse wissen müssen, verwenden Sie möglicherweise Java-Reflektionsmethoden, die mit synthetischen Klassen zu tun haben. Die einzige "Verwendung" besteht darin, weitere Informationen über die Klasse zu erhalten, um sie in Ihrem Code angemessen zu verwenden.
(Wenn Sie dies tun, erstellen Sie wahrscheinlich ein Framework, das andere Entwickler verwenden könnten.)
Andernfalls, wenn Sie keine Reflexion verwenden, gibt es keine praktischen Verwendungen von synthetischen Klassen, die mir bekannt sind.
Ja, Beispielcode wäre gut, wenn Sie ein Beispiel /
Nanofarad
36
Dies beantwortet die Frage nicht.
Dawood ibn Kareem
Für den Schalterfall bin ich nicht sicher, ob dies für jeden Schalter geschieht, aber ich habe dies für Schalter mit Aufzählungen beobachtet; Der Compiler generiert eine anonyme Klasse mit einem einzelnen statischen Feld, das eine Zuordnung Enum.ordinal () -> 1, 2, 3 ... (also eine Sequenz ohne Lücken) bereitstellt. Anschließend führt ein Lookupswitch-Befehl den Schalter für diese Sequenz aus, nicht direkt auf Ordnungszahlen.
Radim Vansa
106
Java kann zur Laufzeit Klassen erstellen. Diese Klassen werden als synthetische Klassen oder dynamische Proxies bezeichnet.
Andere Open-Source-Bibliotheken wie CGLIB und ASM ermöglichen ebenfalls das Generieren synthetischer Klassen und sind leistungsfähiger als die mit der JRE bereitgestellten Bibliotheken.
Synthetische Klassen werden von AOP-Bibliotheken (Aspect Oriented Programming) wie Spring AOP und AspectJ sowie von ORM-Bibliotheken wie Hibernate verwendet.
Dynamische Proxies sind keine synthetischen Klassen. Beweis:Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
Miha_x64
3
Das Javadoc für java.lang.reflect.Member#isSyntheticsagt: Gibt true zurück, wenn dieses Mitglied vom Compiler eingeführt wurde. Gibt sonst false zurück.
Guillaume Husta
Ich glaube, dass der Javadoc für java.lang.reflect.Member#isSyntheticdie ursprüngliche Frage irrelevant ist. Mitglieder sind Felder, Konstruktoren und Methoden. Die ursprüngliche Frage betraf synthetische Klassen , keine synthetischen Mitglieder. In Java 8 führen Lambda-Ausdrücke zu synthetischen Klassen - ich bin mir nicht sicher, unter welchen anderen Umständen sie auftreten können.
Pater Jeremy Krieg
54
Nun, ich habe die Antwort auf die erste Frage bei Google gefunden:
Eine Klasse kann als synthetisch markiert werden, wenn sie vom Compiler generiert wird, dh nicht im Quellcode erscheint.
Dies ist nur eine grundlegende Definition, aber ich habe sie in einem Forenthread gefunden und es gab keine Erklärung. Immer noch auf der Suche nach einem besseren ...
Diese Dinge sind wichtig für die VM. Schauen Sie sich das folgende Code-Snippet an:
classMyOuter{privateMyInner 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 =newMyInner();// The Compiler has to create a synthetic method// to doSomething on MyInner object because this// method is private.// --> synthetic "doSomething" method
inner.doSomething();}privateclassMyInner{// the inner class holds a syntetic ref_pointer to// the outer "parent" class// --> synthetic fieldprivateMyInner(){}privatevoid doSomething(){}}}
Laut dieser Diskussion wird die Sprachspezifikation, obwohl sie eine "isSynthetic" -Eigenschaft für Klassen beschreibt, von Implementierungen weitgehend ignoriert und weder für dynamische Proxys noch für anonyme Klassen verwendet. Synthetische Felder und Konstruktoren werden verwendet, um verschachtelte Klassen zu implementieren (es gibt kein Konzept für verschachtelte Klassen im Bytecode, nur im Quellcode).
Ich denke, dass sich das Konzept der synthetischen Klassen einfach als nicht nützlich erwiesen hat, dh es interessiert niemanden, ob eine Klasse synthetisch ist. Bei Feldern und Methoden wird es wahrscheinlich genau an einer Stelle verwendet: um zu bestimmen, was in einer IDE-Klassenstrukturansicht angezeigt werden soll - Sie möchten, dass dort normale Methoden und Felder angezeigt werden, nicht jedoch die synthetischen, die zur Simulation verschachtelter Klassen verwendet werden. OTOH, Sie möchten, dass anonyme Klassen dort angezeigt werden.
Ich denke du meinst zur Kompilierungszeit und nicht zur Laufzeit.
Mostowski Zusammenbruch
@sathis, meintest du javac, nicht JVM?
Miha_x64
3
Auch synthetische Klassen oder dynamische Proxies werden von EasyMock verwendet, um zur Laufzeit Implementierungen von Schnittstellen oder abstrakten Klassen zu erstellen.
Wenn der Java-Compiler bestimmte Konstrukte wie z. B. innere Klassen kompiliert, werden synthetische Konstrukte erstellt . Dies sind Klassen, Methoden, Felder und andere Konstrukte, deren Quellcode kein entsprechendes Konstrukt enthält. Verwendung: Mit
synthetischen Konstrukten können Java-Compiler neue Java-Sprachfunktionen implementieren, ohne Änderungen an der JVM vorzunehmen. Synthetische Konstrukte können jedoch zwischen verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch zwischen verschiedenen Implementierungen variieren können. Referenz: docs.oracle.com
Wie bereits in verschiedenen Antworten erwähnt, kann der Compiler verschiedene Konstrukte (einschließlich Klassen) generieren, die nicht direkt mit etwas im Quellcode übereinstimmen. Diese müssen als synthetisch gekennzeichnet werden:
Eine binäre Darstellung für eine Klasse oder Schnittstelle muss außerdem Folgendes enthalten:
[...]
11. Ein von einem Java-Compiler ausgegebenes Konstrukt muss als synthetisch markiert werden, wenn es keinem im Quellcode explizit oder implizit deklarierten Konstrukt entspricht , es sei denn, das ausgegebene Konstrukt ist eine Klasseninitialisierungsmethode (JVMS §2.9).
[...]
Wie von @Holger in einem Kommentar zu einer anderen Frage hervorgehoben, sind relevante Beispiele für solche Konstrukte die Klassenobjekte , die Methodenreferenzen und Lambdas darstellen:
Wenn ich es richtig verstehe, wird eine synthetische Klasse im laufenden Betrieb generiert, ohne dass sie explizit benannt werden muss. Beispielsweise:
//...Thread myThread =newThread(){publicvoid run(){// do something ...}};
myThread.start();//...
Dadurch wird eine synthetische Unterklasse von Thread erstellt und die run () -Methode überschrieben. Anschließend wird sie instanziiert und gestartet.
Ich muss @KumarAbhinav zustimmen. Nicht alle anonymen inneren Klassen sind synthetisch. Siehe: xinotes.net/notes/note/1339
bvdb
Anonyme innere Klassen generieren in Oracle JDK 1.8.0_45 keine synthetischen Klassen, sondern separate nicht synthetische Klassen mit Typnamen Outer$1.class.
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
1
Was ist eine synthetische Klasse in Java?
EIN synthetic Klasse ist eine .classvom Java Compiler generierte Datei im Quellcode nicht vorhanden ist.
Beispiel für die Verwendung von synthetic Klasse: Anonyme innere Klasse
Synthetische Konstrukte sind Klassen, Methoden, Felder usw., deren Quellcode kein entsprechendes Konstrukt enthält. Mit synthetischen Konstrukten können Java-Compiler neue Java-Sprachfunktionen implementieren, ohne die JVM zu ändern. Synthetische Konstrukte können jedoch zwischen verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch zwischen verschiedenen Implementierungen variieren können.
-1. Der gleiche Text wurde wörtlich in der Antwort veröffentlicht, die ein Jahr vor Ihrer [ stackoverflow.com/a/24271953/1144395] gegeben wurde , und in dieser Antwort wurde zusätzlich die offizielle Referenz zitiert, aus der der Text stammt, und die Formatierung zum leichteren Lesen bereitgestellt . Bitte spammen Sie nicht gierig Fragen mit eindeutig doppelten Antworten.
Naki
0
Eine synthetische Klasse erscheint nicht in Ihrem Code: Sie wird vom Compiler erstellt. Beispiel: Eine vom Compiler in Java erstellte Bridge-Methode ist normalerweise synthetisch.
publicclassPair<T>{private T first;private T second;publicvoid setSecond(T newValue){
second = newValue;}}publicclassDateIntervalextendsPair<String>{publicvoid setSecond(String second){System.out.println("OK sub");}publicstaticvoid main(String[] args)throwsNoSuchFieldException,SecurityException{DateInterval interval =newDateInterval();Pair pair = interval;
pair.setSecond("string1");}}
Mit dem Befehl javap -verbose DateIntervalkönnen Sie eine Bridge-Methode anzeigen:
Antworten:
Wenn Sie beispielsweise eine switch-Anweisung haben, erstellt Java eine Variable, die mit einem $ beginnt. Wenn Sie ein Beispiel dafür sehen möchten, werfen Sie einen Blick in die Java-Reflexion einer Klasse, die eine switch-Anweisung enthält. Sie sehen diese Variablen, wenn Sie irgendwo in der Klasse mindestens eine switch-Anweisung haben.
Um Ihre Frage zu beantworten, glaube ich nicht, dass Sie auf die synthetischen Klassen zugreifen können (außer auf Reflexion).
Wenn Sie eine Klasse analysieren, von der Sie nichts wissen (über Reflektion) und sehr spezifische und einfache Dinge über diese Klasse wissen müssen, verwenden Sie möglicherweise Java-Reflektionsmethoden, die mit synthetischen Klassen zu tun haben. Die einzige "Verwendung" besteht darin, weitere Informationen über die Klasse zu erhalten, um sie in Ihrem Code angemessen zu verwenden.
(Wenn Sie dies tun, erstellen Sie wahrscheinlich ein Framework, das andere Entwickler verwenden könnten.)
Andernfalls, wenn Sie keine Reflexion verwenden, gibt es keine praktischen Verwendungen von synthetischen Klassen, die mir bekannt sind.
quelle
Java kann zur Laufzeit Klassen erstellen. Diese Klassen werden als synthetische Klassen oder dynamische Proxies bezeichnet.
Weitere Informationen finden Sie unter http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html .
Andere Open-Source-Bibliotheken wie CGLIB und ASM ermöglichen ebenfalls das Generieren synthetischer Klassen und sind leistungsfähiger als die mit der JRE bereitgestellten Bibliotheken.
Synthetische Klassen werden von AOP-Bibliotheken (Aspect Oriented Programming) wie Spring AOP und AspectJ sowie von ORM-Bibliotheken wie Hibernate verwendet.
quelle
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
sagt: Gibt true zurück, wenn dieses Mitglied vom Compiler eingeführt wurde. Gibt sonst false zurück.java.lang.reflect.Member#isSynthetic
die ursprüngliche Frage irrelevant ist. Mitglieder sind Felder, Konstruktoren und Methoden. Die ursprüngliche Frage betraf synthetische Klassen , keine synthetischen Mitglieder. In Java 8 führen Lambda-Ausdrücke zu synthetischen Klassen - ich bin mir nicht sicher, unter welchen anderen Umständen sie auftreten können.Nun, ich habe die Antwort auf die erste Frage bei Google gefunden:
Dies ist nur eine grundlegende Definition, aber ich habe sie in einem Forenthread gefunden und es gab keine Erklärung. Immer noch auf der Suche nach einem besseren ...
quelle
synthetische Klassen / Methoden / Felder:
Diese Dinge sind wichtig für die VM. Schauen Sie sich das folgende Code-Snippet an:
quelle
Laut dieser Diskussion wird die Sprachspezifikation, obwohl sie eine "isSynthetic" -Eigenschaft für Klassen beschreibt, von Implementierungen weitgehend ignoriert und weder für dynamische Proxys noch für anonyme Klassen verwendet. Synthetische Felder und Konstruktoren werden verwendet, um verschachtelte Klassen zu implementieren (es gibt kein Konzept für verschachtelte Klassen im Bytecode, nur im Quellcode).
Ich denke, dass sich das Konzept der synthetischen Klassen einfach als nicht nützlich erwiesen hat, dh es interessiert niemanden, ob eine Klasse synthetisch ist. Bei Feldern und Methoden wird es wahrscheinlich genau an einer Stelle verwendet: um zu bestimmen, was in einer IDE-Klassenstrukturansicht angezeigt werden soll - Sie möchten, dass dort normale Methoden und Felder angezeigt werden, nicht jedoch die synthetischen, die zur Simulation verschachtelter Klassen verwendet werden. OTOH, Sie möchten, dass anonyme Klassen dort angezeigt werden.
quelle
Sie werden von JVM zur Laufzeit erstellt, wenn sie private Mitglieder der inneren Klasse zum Debuggen aufrufen
Die Methoden, Felder und Klassen, die von JVM zur Laufzeit für die Ausführung erstellt wurden, werden als Synthetic bezeichnet
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
quelle
Auch synthetische Klassen oder dynamische Proxies werden von EasyMock verwendet, um zur Laufzeit Implementierungen von Schnittstellen oder abstrakten Klassen zu erstellen.
http://www.easymock.org/
quelle
Wenn der Java-Compiler bestimmte Konstrukte wie z. B. innere Klassen kompiliert, werden synthetische Konstrukte erstellt . Dies sind Klassen, Methoden, Felder und andere Konstrukte, deren Quellcode kein entsprechendes Konstrukt enthält.
Verwendung: Mit synthetischen Konstrukten können Java-Compiler neue Java-Sprachfunktionen implementieren, ohne Änderungen an der JVM vorzunehmen. Synthetische Konstrukte können jedoch zwischen verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch zwischen verschiedenen Implementierungen variieren können.
Referenz: docs.oracle.com
quelle
Wie bereits in verschiedenen Antworten erwähnt, kann der Compiler verschiedene Konstrukte (einschließlich Klassen) generieren, die nicht direkt mit etwas im Quellcode übereinstimmen. Diese müssen als synthetisch gekennzeichnet werden:
13.1. Die Form einer Binärdatei
Wie von @Holger in einem Kommentar zu einer anderen Frage hervorgehoben, sind relevante Beispiele für solche Konstrukte die Klassenobjekte , die Methodenreferenzen und Lambdas darstellen:
Ausgabe:
Dies wird zwar nicht ausdrücklich erwähnt, folgt aber aus 15.27.4. Laufzeitauswertung von Lambda-Ausdrücken :
und der fast identische Wortlaut für Methodenreferenzen ( 15.13.3. Laufzeitbewertung von Methodenreferenzen ).
Da diese Klasse nirgendwo im Quellcode explizit erwähnt wird, muss sie synthetisch sein.
quelle
Wenn ich es richtig verstehe, wird eine synthetische Klasse im laufenden Betrieb generiert, ohne dass sie explizit benannt werden muss. Beispielsweise:
Dadurch wird eine synthetische Unterklasse von Thread erstellt und die run () -Methode überschrieben. Anschließend wird sie instanziiert und gestartet.
quelle
Outer$1.class
.EIN
synthetic
Klasse ist eine.class
vom Java Compiler generierte Datei im Quellcode nicht vorhanden ist.Beispiel für die Verwendung von
synthetic
Klasse: Anonyme innere Klassesynthetic
Klasse und eine anonyme innere Klasse in java.text.DigitListDigitList$1.java
aber es ist eine innere Datei inDigitList.java
Es ist ein Mechanismus innerhalb der Java-Compiler-Logik, um das zu generieren
.class
DateiNein, Entwickler tun es NICHT verwenden es direkt.
Java-Compiler
synthetic
zum Generieren verwenden.class
Datei , und dann liest JVM die.class
Datei, um die Programmlogik auszuführen.Mehr Details
synthetic
Klasse im Detailsynthetic
Klassen-Exits in JDK aufquelle
Synthetische Konstrukte sind Klassen, Methoden, Felder usw., deren Quellcode kein entsprechendes Konstrukt enthält. Mit synthetischen Konstrukten können Java-Compiler neue Java-Sprachfunktionen implementieren, ohne die JVM zu ändern. Synthetische Konstrukte können jedoch zwischen verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch zwischen verschiedenen Implementierungen variieren können.
quelle
Eine synthetische Klasse erscheint nicht in Ihrem Code: Sie wird vom Compiler erstellt. Beispiel: Eine vom Compiler in Java erstellte Bridge-Methode ist normalerweise synthetisch.
Mit dem Befehl
javap -verbose DateInterval
können Sie eine Bridge-Methode anzeigen:Dies wurde vom Compiler erfunden; es erscheint nicht in Ihrem Code.
quelle