it-swarm.com.de

Synthetische Klasse in Java

Was ist eine synthetische Klasse in Java? Warum sollte es verwendet werden? Wie kann ich es benutzen?

130
andHapp

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 auf die Java-Reflektion einer Klasse, die eine switch-Anweisung enthält. Sie werden diese Variablen sehen, wenn Sie irgendwo in der Klasse über mindestens eine switch-Anweisung verfügen. 

Um Ihre Frage zu beantworten, glaube ich nicht, dass Sie auf die synthetischen Klassen (außer auf Reflektion) zugreifen können.

Wenn Sie eine Klasse analysieren, von der Sie nichts wissen (über Reflektion) und sehr genaue und grundlegende Informationen über diese Klasse benötigen, können Sie Java-Reflektionsmethoden verwenden, die synthetische Klassen betreffen. Die einzige "Verwendung" hier ist, mehr Informationen über die Klasse zu erhalten, um sie in Ihrem Code entsprechend zu verwenden. 

(Wenn Sie dies tun, erstellen Sie wahrscheinlich ein Framework, das andere Entwickler verwenden könnten.)

Andernfalls gibt es keine praktischen Anwendungen synthetischer Klassen, die ich kenne, wenn Sie keine Reflexion verwenden. 

15
Milhous

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 auch 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 ORM-Bibliotheken wie Hibernate verwendet. 

102

Nun, ich habe die Antwort auf die erste Frage bei Google gefunden:

Eine Klasse kann als synthetisch gekennzeichnet werden, wenn es wird vom Compiler generiert, der ist es nicht in der Quelle Code.

Dies ist nur eine grundlegende Definition, aber ich habe sie in einem Forumsthread gefunden und es gab keine Erklärung. Noch auf der Suche nach einem besseren ...

54
andHapp

synthetische Klassen/Methoden/Felder:

Diese Dinge sind für die VM wichtig. Schauen Sie sich das folgende Code-Snippet an:

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() {
    }
  }
}
13
mrhuber

Laut dieser Diskussion wird die Sprachspezifikation zwar eine "isSynthetic" -Eigenschaft für Klassen beschreibt, dies wird jedoch von Implementierungen weitgehend ignoriert und nicht für dynamische Proxies oder anonyme Klassen verwendet. Synthetische Felder und Konstruktoren werden verwendet, um verschachtelte Klassen zu implementieren (es gibt kein Konzept geschachtelter Klassen im Bytecode, nur im Quellcode).

Ich denke, das Konzept der synthetischen Klassen hat sich einfach als nicht nützlich erwiesen, d. H., Es interessiert niemanden, ob eine Klasse synthetisch ist. Bei Feldern und Methoden wird dies wahrscheinlich genau an einer Stelle verwendet: Um zu bestimmen, was in einer IDE -Klassenstrukturansicht angezeigt werden soll, sollen normale Methoden und Felder angezeigt werden, nicht jedoch die synthetischen, um verschachtelte Klassen zu simulieren . OTOH, Sie möchten, dass anonyme Kurse dort angezeigt werden.

8

Sie werden von JVM zur Laufzeit erstellt, wenn sie private Mitglieder der inneren Klasse zu Debugging-Zwecken aufrufen

Die Methoden, Felder und Klassen, die zur Laufzeit von JVM zu Ausführungszwecken erstellt wurden, werden als Synthetik bezeichnet

http://www.javaworld.com/article/2073578/Java-s-synthetic-methods.html

http://javapapers.com/core-Java/java-synthetic-class-method-field/

7
sathis

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/

3
user2427

Wenn der Java-Compiler bestimmte Konstrukte wie innere Klassen kompiliert, erstellt er synthetische Konstrukte; Hierbei handelt es sich um Klassen, Methoden, Felder und andere Konstrukte, die kein entsprechendes Konstrukt im Quellcode enthalten. 
Verwendet: Synthetische Konstrukte ermöglichen Java-Compilern die Implementierung neuer Java-Sprachfunktionen ohne Änderungen an der JVM. Synthetische Konstrukte können jedoch bei verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch bei verschiedenen Implementierungen variieren können.
referenz: docs.Oracle.com

2

Wie verschiedene Antworten bereits gezeigt haben, darf der Compiler verschiedene Konstrukte (einschließlich Klassen) generieren, die nicht direkt einem Quellcode entsprechen. Diese müssen als synthetisch gekennzeichnet sein:

13.1. Die Form eines Binärs

Eine binäre Repräsentation für eine Klasse oder ein Interface muss außerdem Folgendes enthalten:
[...]
11. Ein von einem Java-Compiler ausgegebenes Konstrukt muss als synthetisch gekennzeichnet werden, wenn es nicht einem explizit oder implizit im Quellcode 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:

System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());

Ausgabe:

true
true

Obwohl dies nicht explizit erwähnt wird, folgt es aus 15.27.4. Laufzeitbewertung von Lambda-Ausdrücken :

Der Wert eines Lambda-Ausdrucks ist eine Referenz auf eine Instanz einer Klasse mit den folgenden Eigenschaften: [...]

und der fast identische Wortlaut für Methodenreferenzen ( 15.13.3. Laufzeitbewertung von Methodenreferenzen ). 

Da diese Klasse im Quellcode nicht explizit erwähnt wird, muss sie synthetisch sein.

2
Hulk

Wenn ich es richtig verstanden habe, wird eine synthetische Klasse on the fly generiert, ohne dass sie einen expliziten Namen hat. Zum Beispiel:

//...
Thread myThread = new Thread() {
         public void 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.

1
Ivan

Synthetische Konstrukte sind Klassen, Methoden, Felder usw., die kein entsprechendes Konstrukt im Quellcode enthalten. Synthetische Konstrukte ermöglichen Java-Compilern die Implementierung neuer Java-Sprachfunktionen ohne Änderungen an der JVM. Synthetische Konstrukte können jedoch bei verschiedenen Java-Compiler-Implementierungen variieren, was bedeutet, dass .class-Dateien auch bei verschiedenen Implementierungen variieren können.

0

Eine synthetische Klasse wird in Ihrem Code nicht angezeigt: Sie wird vom Compiler erstellt. Z.B. Eine vom Compiler in Java erstellte Brückenmethode ist normalerweise synthetisch.

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

Mit dem Befehl javap -verbose DateInterval können Sie eine Bridge-Methode sehen:

public void setSecond(Java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

Dies wurde vom Compiler gemacht; Es erscheint nicht in Ihrem Code.

0
JavaFresher