web-dev-qa-db-fra.com

Classe synthétique en Java

Qu'est-ce qu'une classe synthétique en Java? Pourquoi devrait-il être utilisé? Comment puis-je l'utiliser?

130
andHapp

Par exemple, lorsque vous avez une instruction switch, Java crée une variable qui commence par un $. Si vous souhaitez voir un exemple de cela, examinez le reflet Java d'une classe contenant une instruction switch. Vous verrez ces variables lorsque vous aurez au moins une instruction switch dans la classe. 

Pour répondre à votre question, je ne pense pas que vous puissiez accéder (sauf à la réflexion) aux classes synthétiques.

Si vous analysez une classe que vous ne connaissez pas (via la réflexion) et que vous avez besoin de connaître des choses très spécifiques et de bas niveau à propos de cette classe, vous pouvez utiliser des méthodes de réflexion Java liées aux classes synthétiques. La seule "utilisation" ici est d'obtenir plus d'informations sur la classe afin de l'utiliser correctement dans votre code. 

(Si vous faites cela, vous construisez probablement un framework que d'autres développeurs pourraient utiliser.)

Sinon, si vous n'utilisez pas la réflexion, il n'y a pas d'utilisation pratique des classes synthétiques à ma connaissance. 

15
Milhous

Java a la capacité de créer des classes au moment de l'exécution. Ces classes sont appelées classes synthétiques ou procurations dynamiques.

Voir http://Java.Sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html pour plus d'informations.

D'autres bibliothèques à code source ouvert, telles que CGLIB et ASM vous permettent également de générer des classes synthétiques et sont plus puissantes que les bibliothèques fournies avec JRE.

Les classes synthétiques sont utilisées par les bibliothèques AOP (Aspect Oriented Programming) telles que Spring AOP et AspectJ, ainsi que par les bibliothèques ORM telles que Hibernate. 

102
Andrew Newdigate

Eh bien, j'ai trouvé la réponse à la première question sur google:

Une classe peut être marquée comme synthétique si il est généré par le compilateur, que est, il n'apparaît pas dans la source code.

Ceci est juste une définition de base mais je l’ai trouvée dans un fil de discussion et il n’y avait aucune explication. Toujours à la recherche d'un meilleur ...

54
andHapp

classes/méthodes/champs synthétiques:

Ces choses sont importantes pour la VM. Regardez l'extrait de code suivant:

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

Selon cette discussion , bien que la spécification de langage décrive une propriété "isSynthetic" pour les classes, celle-ci est pratiquement ignorée par les implémentations et n'est utilisée ni pour les proxys dynamiques ni pour les classes anonymes. Les champs synthétiques et les constructeurs sont utilisés pour implémenter des classes imbriquées (il n'y a pas de concept de classes imbriquées dans le code octet, seulement dans le code source).

Je pense que le concept de classes synthétiques s’est tout simplement avéré inutile, c’est-à-dire que personne ne se soucie de savoir si une classe est synthétique. Avec les champs et les méthodes, il est probablement utilisé à un endroit précis: pour déterminer les éléments à afficher dans une vue de structure de classe IDE, vous souhaitez que les méthodes et les champs normaux s'affichent ici, mais pas ceux synthétiques utilisés pour simuler des classes imbriquées. . OTOH, vous voulez que les classes anonymes apparaissent là-bas.

8
Michael Borgwardt

Ils sont créés par la JVM au moment de l’exécution lorsqu'ils invoquent des membres privés de la classe interne à des fins de débogage.

Les méthodes, champs et classes créés par la machine virtuelle lors de l’exécution sont appelés synthétiques.

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

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

7
sathis

De plus, EasyMock utilise des classes synthétiques ou des procurations dynamiques pour créer des implémentations d’interfaces ou de classes abstraites lors de l’exécution.

http://www.easymock.org/

3
user2427

Lorsque le compilateur Java compile certaines constructions, telles que les classes internes, il crée constructions synthétiques; Il s'agit de classes, méthodes, champs et autres constructions qui n'ont pas de construction correspondante dans le code source. 
Utilisations: Les constructions synthétiques permettent aux compilateurs Java d'implémenter de nouvelles fonctionnalités du langage Java sans modification de la machine virtuelle Java. Cependant, les constructions synthétiques peuvent varier selon les implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier selon les implémentations.
référence: docs.Oracle.com

2
anavaras lamurep

Comme plusieurs réponses l'ont déjà indiqué, le compilateur est autorisé à générer diverses constructions (y compris des classes) qui ne correspondent pas directement à quelque chose dans le code source. Ceux-ci doivent être marqués comme synthétiques:

13.1. La forme d'un binaire

Une représentation binaire pour une classe ou une interface doit également contenir tous les éléments suivants:
[...]
11. Une construction émise par un compilateur Java doit être marquée comme synthétique si elle ne correspond pas à une construction déclarée explicitement ou implicitement dans le code source, à moins que la construction émise soit une méthode d'initialisation de classe (JVMS §2.9).
[...]

Comme l'a souligné @Holger dans un commentaire sur une autre question, les exemples pertinents de telles constructions sont les objets Class représentant les références de méthode et les lambdas:

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

Sortie:

true
true

Bien que cela ne soit pas explicitement mentionné, il découle de 15.27.4. Évaluation à l'exécution des expressions Lambda :

La valeur d'une expression lambda est une référence à une instance d'une classe avec les propriétés suivantes: [...]

et le libellé presque identique pour les références de méthode ( 15.13.3. Evaluation à l'exécution des références de méthode ). 

Comme cette classe n'est explicitement mentionnée nulle part dans le code source, elle doit être synthétique.

2
Hulk

Si je comprends bien, une classe synthétique est une classe générée à la volée, sans avoir à lui donner un nom explicite. Par exemple:

//...
Thread myThread = new Thread() {
         public void run() {
           // do something ...
         }
       };
myThread.start();
//...

Cela crée une sous-classe synthétique de Thread et remplace sa méthode run (), puis l'instancie et le démarre.

1
Ivan

Les constructions synthétiques sont des classes, méthodes, champs, etc. qui n'ont pas de construction correspondante dans le code source. Les constructions synthétiques permettent aux compilateurs Java d'implémenter de nouvelles fonctionnalités du langage Java sans modification de la machine virtuelle Java. Cependant, les constructions synthétiques peuvent varier selon les implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier selon les implémentations.

0
Srivats krishnan

Une classe synthétique n'apparaît pas dans votre code: elle est constituée par le compilateur. Par exemple. Une méthode de pontage constituée par un compilateur en Java est généralement synthétique.

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

En utilisant la commande javap -verbose DateInterval, vous pouvez voir une méthode de pontage:

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

Cela a été composé par le compilateur; il n'apparait pas dans votre code.

0
JavaFresher