Qu'est-ce qu'une classe synthétique en Java? Pourquoi devrait-il être utilisé? Comment puis-je l'utiliser?
Qu'est-ce qu'une classe synthétique en Java? Pourquoi devrait-il être utilisé? Comment puis-je l'utiliser?
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.
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.
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:
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 ...
classes / méthodes / champs synthétiques:
Ces éléments sont importants pour la machine virtuelle. Jetez un œil à 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() {
}
}
}
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.
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/
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:
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
Production:
true
true
Bien que cela ne soit pas explicitement mentionné, cela découle de 15.27.4. Évaluation d'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. É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.
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 la démarre.
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.
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 pont:
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Ceci a été créé par le compilateur; il n'apparaît pas dans votre code.
Qu'est-ce qu'une classe synthétique en Java?
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 anonyme
synthetic
classe et c'est une classe interne anonyme dans java.text.DigitListDigitList$1.java
mais c'est un fichier interne dansDigitList.java
Pourquoi devrait-il être utilisé?
C'est un mécanisme à l'intérieur de la logique du compilateur Java pour générer le .class
fichier
Comment puis-je l'utiliser?
Non, 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.
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.