Toutes les réponses «pas dans votre code» sont obsolètes avec Java 8, car les lambdas peuvent être implémentées sous forme de classes synthétiques (non anonymes).
OrangeDog
Pour être honnête, un lambda n'est toujours pas "strictement" une classe définie explicitement dans votre code. Donc, "pas dans votre code" est toujours valide. Le compilateur génère les classes synthétiques pour vous sans définition explicite dans votre code.
ManoDestra
Réponses:
15
Par exemple, lorsque vous avez une instruction switch, java crée une variable commençant par $. Si vous voulez voir un exemple de ceci, jetez un œil dans le reflet java d'une classe qui contient une instruction switch. Vous verrez ces variables lorsque vous avez au moins une instruction switch n'importe où dans la classe.
Pour répondre à votre question, je ne pense pas que vous puissiez accéder (autre que réflexion) aux classes synthétiques.
Si vous analysez une classe dont vous ne savez rien (via la réflexion) et que vous avez besoin de connaître des choses très spécifiques et de bas niveau sur cette classe, vous pouvez finir par utiliser des méthodes de réflexion Java qui ont à voir avec des classes synthétiques. La seule "utilisation" ici est d'obtenir plus d'informations sur la classe afin de l'utiliser de manière appropriée dans votre code.
(Si vous faites cela, vous construisez probablement une sorte de cadre que d'autres développeurs pourraient utiliser.)
Sinon, si vous n'utilisez pas la réflexion, il n'y a aucune utilisation pratique des classes synthétiques que je connaisse.
Oui, un exemple de code serait bon si vous pouviez fournir un exemple /
nanofarad
36
Cela ne répond pas à la question.
Dawood ibn Kareem
Pour le cas du commutateur, je ne suis pas sûr que cela se produise pour chaque commutateur, mais j'ai observé cela pour le commutateur avec des enums; le compilateur génère une classe anonyme avec un seul champ statique qui fournit un mappage Enum.ordinal () -> 1, 2, 3 ... (donc une séquence sans lacunes), puis une instruction lookupswitch exécute le commutateur sur cette séquence, pas directement sur les ordinaux.
Radim Vansa du
106
Java a la capacité de créer des classes au moment de l'exécution. Ces classes sont appelées classes synthétiques ou proxys dynamiques.
D'autres bibliothèques open-source, 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 le 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.
Les proxys dynamiques ne sont pas des classes synthétiques.Preuve:Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
Miha_x64
3
Le javadoc for java.lang.reflect.Member#isSyntheticdit: Renvoie true si ce membre a été introduit par le compilateur; renvoie false dans le cas contraire.
Guillaume Husta
Je pense que le javadoc pour java.lang.reflect.Member#isSyntheticest sans rapport avec la question initiale. Les membres sont des champs, des constructeurs et des méthodes. La question initiale concernait les classes synthétiques , pas les membres synthétiques. Dans Java 8, les expressions lambda donnent naissance à des classes synthétiques - je ne sais pas dans quelles autres circonstances elles peuvent survenir.
Fr Jeremy Krieg
54
Eh bien, j'ai trouvé la réponse à la première question sur google:
Une classe peut être marquée comme synthétique si elle est générée par le compilateur, c'est-à-dire qu'elle n'apparaît pas dans le code source.
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 ...
Ces éléments sont importants pour la machine virtuelle. Jetez un œil à l'extrait de code suivant:
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(){}}}
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, non, uniquement des méthodes d'accesseurs synthétiques.
Miha_x64
8
Selon cette discussion , bien que la spécification du langage décrit une propriété "isSynthetic" pour les classes, cela est pratiquement ignoré par les implémentations et n'est pas utilisé pour les proxys dynamiques ou 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 en byte code, uniquement en code source).
Je pense que le concept de classes synthétiques s'est 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é exactement à un seul endroit: pour déterminer ce qu'il faut afficher dans une vue de structure de classe IDE - vous voulez que les méthodes et les champs normaux apparaissent là-haut, mais pas ceux synthétiques utilisés pour simuler des classes imbriquées. OTOH, vous voulez que les classes anonymes apparaissent là-haut.
Je suppose que vous voulez dire au moment de la compilation, et non au moment de l'exécution.
Mostowski Collapse le
@sathis, vouliez-vous dire javac, pas JVM?
Miha_x64
3
Des classes synthétiques ou des proxys dynamiques sont également utilisés par EasyMock pour créer des implémentations d'interfaces ou de classes abstraites au moment de l'exécution.
Lorsque le compilateur Java compile certaines constructions, telles que les classes internes, il crée des constructions synthétiques ; ce sont des classes, des méthodes, des champs et d'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 modifier la JVM. Cependant, les constructions synthétiques peuvent varier selon les différentes implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier d'une implémentation à l'autre. référence: docs.oracle.com
Comme plusieurs réponses l'ont déjà souligné, 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:
Une représentation binaire d'une classe ou d'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 , sauf si la construction émise est une méthode d'initialisation de classe (JVMS §2.9).
[...]
Comme indiqué par @Holger dans un commentaire à une autre question, des exemples pertinents pour de telles constructions sont les objets Class représentant des références de méthode et des lambdas:
Je pensais que c'était une classe intérieure anonyme
Kumar Abhinav
2
Je suis d'accord avec @KumarAbhinav. Toutes les classes internes anonymes ne sont pas synthétiques. Voir: xinotes.net/notes/note/1339
bvdb
Les classes internes anonymes ne génèrent pas de classes synthétiques sur Oracle JDK 1.8.0_45, elles génèrent des classes non synthétiques séparées avec des noms de type Outer$1.class.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Une classe synthétique n'apparaît pas dans votre code: elle est constituée par le compilateur. Par exemple, une méthode de pont constituée par un compilateur en java est généralement synthétique.
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");}}
En utilisant la commande javap -verbose DateInterval, vous pouvez voir une méthode de pont:
Les constructions synthétiques sont des classes, des méthodes, des 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 modifier la JVM. Cependant, les constructions synthétiques peuvent varier selon les différentes implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier d'une implémentation à l'autre.
-1. Le même texte, textuellement, a été publié dans la réponse donnée un an avant la vôtre [ stackoverflow.com/a/24271953/1144395] , et cette réponse citait en outre la référence officielle d'où provient le texte et fournissait une mise en forme pour une lecture plus facile . Veuillez ne pas spammer les questions avec des réponses clairement dupliquées.
Réponses:
Par exemple, lorsque vous avez une instruction switch, java crée une variable commençant par $. Si vous voulez voir un exemple de ceci, jetez un œil dans le reflet java d'une classe qui contient une instruction switch. Vous verrez ces variables lorsque vous avez au moins une instruction switch n'importe où dans la classe.
Pour répondre à votre question, je ne pense pas que vous puissiez accéder (autre que réflexion) aux classes synthétiques.
Si vous analysez une classe dont vous ne savez rien (via la réflexion) et que vous avez besoin de connaître des choses très spécifiques et de bas niveau sur cette classe, vous pouvez finir par utiliser des méthodes de réflexion Java qui ont à voir avec des classes synthétiques. La seule "utilisation" ici est d'obtenir plus d'informations sur la classe afin de l'utiliser de manière appropriée dans votre code.
(Si vous faites cela, vous construisez probablement une sorte de cadre que d'autres développeurs pourraient utiliser.)
Sinon, si vous n'utilisez pas la réflexion, il n'y a aucune utilisation pratique des classes synthétiques que je connaisse.
la source
Java a la capacité de créer des classes au moment de l'exécution. Ces classes sont appelées classes synthétiques ou proxys dynamiques.
Voir http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html pour plus d'informations.
D'autres bibliothèques open-source, 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 le 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.
la source
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
dit: Renvoie true si ce membre a été introduit par le compilateur; renvoie false dans le cas contraire.java.lang.reflect.Member#isSynthetic
est sans rapport avec la question initiale. Les membres sont des champs, des constructeurs et des méthodes. La question initiale concernait les classes synthétiques , pas les membres synthétiques. Dans Java 8, les expressions lambda donnent naissance à des classes synthétiques - je ne sais pas dans quelles autres circonstances elles peuvent survenir.Eh bien, j'ai trouvé la réponse à la première question sur google:
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 ...
la source
classes / méthodes / champs synthétiques:
Ces éléments sont importants pour la machine virtuelle. Jetez un œil à l'extrait de code suivant:
la source
Selon cette discussion , bien que la spécification du langage décrit une propriété "isSynthetic" pour les classes, cela est pratiquement ignoré par les implémentations et n'est pas utilisé pour les proxys dynamiques ou 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 en byte code, uniquement en code source).
Je pense que le concept de classes synthétiques s'est 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é exactement à un seul endroit: pour déterminer ce qu'il faut afficher dans une vue de structure de classe IDE - vous voulez que les méthodes et les champs normaux apparaissent là-haut, mais pas ceux synthétiques utilisés pour simuler des classes imbriquées. OTOH, vous voulez que les classes anonymes apparaissent là-haut.
la source
Ils sont créés par 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, classe créés par JVM lors de l'exécution pour son exécution sont appelés Synthetic
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
la source
Des classes synthétiques ou des proxys dynamiques sont également utilisés par EasyMock pour créer des implémentations d'interfaces ou de classes abstraites au moment de l'exécution.
http://www.easymock.org/
la source
Lorsque le compilateur Java compile certaines constructions, telles que les classes internes, il crée des constructions synthétiques ; ce sont des classes, des méthodes, des champs et d'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 modifier la JVM. Cependant, les constructions synthétiques peuvent varier selon les différentes implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier d'une implémentation à l'autre.
référence: docs.oracle.com
la source
Comme plusieurs réponses l'ont déjà souligné, 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
Comme indiqué par @Holger dans un commentaire à une autre question, des exemples pertinents pour de telles constructions sont les objets Class représentant des références de méthode et des lambdas:
Production:
Bien que cela ne soit pas explicitement mentionné, cela découle de 15.27.4. Évaluation d'exécution des expressions Lambda :
et le libellé presque identique pour les références de méthode ( 15.13.3. Évaluation d'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.
la source
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:
Cela crée une sous-classe synthétique de Thread et remplace sa méthode run (), puis l'instancie et la démarre.
la source
Outer$1.class
.Une classe synthétique n'apparaît pas dans votre code: elle est constituée par le compilateur. Par exemple, une méthode de pont constituée par un compilateur en java est généralement synthétique.
En utilisant la commande
javap -verbose DateInterval
, vous pouvez voir une méthode de pont:Ceci a été créé par le compilateur; il n'apparaît pas dans votre code.
la source
Une
synthetic
classe est un.class
fichier généré par Java Compiler et n'existe pas dans le code source.Exemple d'utilisation de la
synthetic
classe: classe interne anonymesynthetic
classe et c'est une classe interne anonyme dans java.text.DigitListDigitList$1.java
mais c'est un fichier interne dansDigitList.java
C'est un mécanisme à l'intérieur de la logique du compilateur Java pour générer le
.class
fichierNon, les développeurs ne l' utilisent PAS directement.
Le compilateur Java utilise
synthetic
pour générer un.class
fichier, puis JVM lit le.class
fichier pour exécuter la logique du programme.Plus de détails
synthetic
classe en détailssynthetic
les sorties de classe dans JDKla source
Les constructions synthétiques sont des classes, des méthodes, des 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 modifier la JVM. Cependant, les constructions synthétiques peuvent varier selon les différentes implémentations du compilateur Java, ce qui signifie que les fichiers .class peuvent également varier d'une implémentation à l'autre.
la source