Todas las respuestas "no en su código" están desactualizadas con Java 8, ya que las lambdas pueden implementarse como clases sintéticas (no anónimas).
OrangeDog
Para ser justos, una lambda todavía no es "estrictamente" una clase definida explícitamente en su código. Por lo tanto, "no está en su código" sigue siendo válido. El compilador genera las clases sintéticas para usted sin una definición explícita en su código.
ManoDestra
Respuestas:
15
Por ejemplo, cuando tiene una instrucción switch, java crea una variable que comienza con $. Si desea ver un ejemplo de esto, eche un vistazo al reflejo de Java de una clase que tiene una instrucción switch. Verá estas variables cuando tenga al menos una instrucción de cambio en cualquier lugar de la clase.
Para responder a su pregunta, no creo que pueda acceder (aparte de la reflexión) a las clases sintéticas.
Si está analizando una clase de la que no sabe nada (a través de la reflexión) y necesita saber cosas muy específicas y de bajo nivel sobre esa clase, puede terminar usando métodos de reflexión de Java que tienen que ver con clases sintéticas. El único "uso" aquí es obtener más información sobre la clase para usarla adecuadamente en su código.
(Si está haciendo esto, probablemente esté creando un marco de algún tipo que otros desarrolladores podrían usar).
De lo contrario, si no está utilizando la reflexión, no hay usos prácticos de clases sintéticas que yo sepa.
Sí, el código de muestra sería bueno si pudiera proporcionar un ejemplo /
nanofarad
36
Esto no responde la pregunta.
Dawood ibn Kareem
Para el caso del interruptor, no estoy seguro de si esto sucede para cada interruptor, pero he observado esto para el interruptor con enumeraciones; el compilador genera una clase anónima con un solo campo estático que proporciona un mapeo Enum.ordinal () -> 1, 2, 3 ... (entonces una secuencia sin espacios), y luego una instrucción de búsqueda de interruptor ejecuta el interruptor en esta secuencia, no directamente en ordinales.
Radim Vansa
106
Java tiene la capacidad de crear clases en tiempo de ejecución. Estas clases se conocen como clases sintéticas o proxies dinámicos.
Otras bibliotecas de código abierto, como CGLIB y ASM también le permiten generar clases sintéticas, y son más potentes que las bibliotecas proporcionadas con el JRE.
Las bibliotecas de AOP (Programación Orientada a Aspectos) utilizan Spring AOP y AspectJ, así como las bibliotecas de ORM como Hibernate.
Los proxys dinámicos no son clases sintéticas. Prueba:Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
Miha_x64
3
El javadoc para java.lang.reflect.Member#isSyntheticdice: Devuelve verdadero si este miembro fue introducido por el compilador; devuelve falso de lo contrario.
Guillaume Husta
Creo que el javadoc para java.lang.reflect.Member#isSynthetices irrelevante para la pregunta original. Los miembros son campos, constructores y métodos. La pregunta original era sobre clases sintéticas , no miembros sintéticos. En Java 8, las expresiones lambda dan lugar a clases sintéticas; no estoy seguro de qué otras circunstancias pueden surgir.
P. Jeremy Krieg
54
Bueno, encontré la respuesta a la primera pregunta en google:
Una clase puede marcarse como sintética si es generada por el compilador, es decir, no aparece en el código fuente.
Esta es solo una definición básica, pero la encontré en un hilo del foro y no había explicación. Sigo buscando una mejor ...
Estas cosas son importantes para la VM. Eche un vistazo al siguiente fragmento de código:
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 六四 事件 法轮功, no, solo métodos de acceso sintéticos.
Miha_x64
8
De acuerdo con esta discusión , aunque la especificación del lenguaje describe una propiedad "isSynthetic" para las clases, las implementaciones lo ignoran y no se utiliza para servidores proxy dinámicos o clases anónimas. Los campos sintéticos y los constructores se utilizan para implementar clases anidadas (no existe el concepto de clases anidadas en el código de bytes, solo en el código fuente).
Creo que el concepto de clases sintéticas simplemente ha demostrado no ser útil, es decir, a nadie le importa si una clase es sintética. Con los campos y métodos, probablemente se use exactamente en un lugar: para determinar qué mostrar en una vista de estructura de clase IDE: desea que aparezcan los métodos y campos normales allí, pero no los sintéticos utilizados para simular clases anidadas. OTOH, QUIERES que aparezcan clases anónimas allí.
Esta respuesta parece estar desactualizada ya que java 8 - lambdas y referencias de métodos hacen uso de esta característica. He agregado una respuesta que demuestra eso
Hulk el
7
JVM los crea en tiempo de ejecución cuando invocan a miembros privados de la clase interna para fines de depuración
Los métodos, campos, clase creados por JVM durante el tiempo de ejecución para su propósito de ejecución se denominan sintéticos.
Cuando el compilador de Java compila ciertas construcciones, como las clases internas, crea construcciones sintéticas ; Estas son clases, métodos, campos y otras construcciones que no tienen una construcción correspondiente en el código fuente. Usos:
Las construcciones sintéticas permiten que los compiladores de Java implementen nuevas características del lenguaje Java sin cambios en la JVM. Sin embargo, las construcciones sintéticas pueden variar entre diferentes implementaciones del compilador de Java, lo que significa que los archivos .class también pueden variar entre diferentes implementaciones. referencia: docs.oracle.com
Como varias respuestas ya han señalado, el compilador puede generar varias construcciones (incluidas las clases) que no se corresponden directamente con algo en el código fuente. Estos deben marcarse como sintéticos:
Una representación binaria para una clase o interfaz también debe contener todo lo siguiente:
[...]
11. Una construcción emitida por un compilador Java debe marcarse como sintética si no corresponde a una construcción declarada explícita o implícitamente en el código fuente , a menos que la construcción emitida sea un método de inicialización de clase (JVMS §2.9).
[...]
Como señaló @Holger en un comentario a otra pregunta, ejemplos relevantes para tales construcciones son los objetos de clase que representan referencias de métodos y lambdas:
Tengo que estar de acuerdo con @KumarAbhinav. No todas las clases internas anónimas son sintéticas. Ver: xinotes.net/notes/note/1339
bvdb
Las clases internas anónimas no generan clases sintéticas en Oracle JDK 1.8.0_45, generan clases no sintéticas separadas con nombres de tipo Outer$1.class.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Una clase sintética no aparece en su código: está compuesta por el compilador. Por ejemplo, un método puente compuesto por un compilador en Java es típicamente sintético.
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");}}
Usando el comando javap -verbose DateInterval, puede ver un método de puente:
Las construcciones sintéticas son clases, métodos, campos, etc. que no tienen una construcción correspondiente en el código fuente. Las construcciones sintéticas permiten a los compiladores de Java implementar nuevas características del lenguaje Java sin cambios en la JVM. Sin embargo, las construcciones sintéticas pueden variar entre diferentes implementaciones del compilador de Java, lo que significa que los archivos .class también pueden variar entre diferentes implementaciones.
-1. El mismo texto, literalmente, se publicó en la respuesta dada un año antes que la suya [ stackoverflow.com/a/24271953/1144395] , y aún más esa respuesta también citó la referencia oficial donde se origina el texto, y proporcionó formato para una lectura más fácil . Por favor, no envíes preguntas codiciosas con respuestas claramente duplicadas.
Respuestas:
Por ejemplo, cuando tiene una instrucción switch, java crea una variable que comienza con $. Si desea ver un ejemplo de esto, eche un vistazo al reflejo de Java de una clase que tiene una instrucción switch. Verá estas variables cuando tenga al menos una instrucción de cambio en cualquier lugar de la clase.
Para responder a su pregunta, no creo que pueda acceder (aparte de la reflexión) a las clases sintéticas.
Si está analizando una clase de la que no sabe nada (a través de la reflexión) y necesita saber cosas muy específicas y de bajo nivel sobre esa clase, puede terminar usando métodos de reflexión de Java que tienen que ver con clases sintéticas. El único "uso" aquí es obtener más información sobre la clase para usarla adecuadamente en su código.
(Si está haciendo esto, probablemente esté creando un marco de algún tipo que otros desarrolladores podrían usar).
De lo contrario, si no está utilizando la reflexión, no hay usos prácticos de clases sintéticas que yo sepa.
fuente
Java tiene la capacidad de crear clases en tiempo de ejecución. Estas clases se conocen como clases sintéticas o proxies dinámicos.
Consulte http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html para obtener más información.
Otras bibliotecas de código abierto, como CGLIB y ASM también le permiten generar clases sintéticas, y son más potentes que las bibliotecas proporcionadas con el JRE.
Las bibliotecas de AOP (Programación Orientada a Aspectos) utilizan Spring AOP y AspectJ, así como las bibliotecas de ORM como Hibernate.
fuente
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
dice: Devuelve verdadero si este miembro fue introducido por el compilador; devuelve falso de lo contrario.java.lang.reflect.Member#isSynthetic
es irrelevante para la pregunta original. Los miembros son campos, constructores y métodos. La pregunta original era sobre clases sintéticas , no miembros sintéticos. En Java 8, las expresiones lambda dan lugar a clases sintéticas; no estoy seguro de qué otras circunstancias pueden surgir.Bueno, encontré la respuesta a la primera pregunta en google:
Esta es solo una definición básica, pero la encontré en un hilo del foro y no había explicación. Sigo buscando una mejor ...
fuente
clases / métodos / campos sintéticos:
Estas cosas son importantes para la VM. Eche un vistazo al siguiente fragmento de código:
fuente
De acuerdo con esta discusión , aunque la especificación del lenguaje describe una propiedad "isSynthetic" para las clases, las implementaciones lo ignoran y no se utiliza para servidores proxy dinámicos o clases anónimas. Los campos sintéticos y los constructores se utilizan para implementar clases anidadas (no existe el concepto de clases anidadas en el código de bytes, solo en el código fuente).
Creo que el concepto de clases sintéticas simplemente ha demostrado no ser útil, es decir, a nadie le importa si una clase es sintética. Con los campos y métodos, probablemente se use exactamente en un lugar: para determinar qué mostrar en una vista de estructura de clase IDE: desea que aparezcan los métodos y campos normales allí, pero no los sintéticos utilizados para simular clases anidadas. OTOH, QUIERES que aparezcan clases anónimas allí.
fuente
JVM los crea en tiempo de ejecución cuando invocan a miembros privados de la clase interna para fines de depuración
Los métodos, campos, clase creados por JVM durante el tiempo de ejecución para su propósito de ejecución se denominan sintéticos.
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
fuente
EasyMock también utiliza clases sintéticas o proxys dinámicos para crear implementaciones de interfaces o clases abstractas en tiempo de ejecución.
http://www.easymock.org/
fuente
Cuando el compilador de Java compila ciertas construcciones, como las clases internas, crea construcciones sintéticas ; Estas son clases, métodos, campos y otras construcciones que no tienen una construcción correspondiente en el código fuente.
Usos: Las construcciones sintéticas permiten que los compiladores de Java implementen nuevas características del lenguaje Java sin cambios en la JVM. Sin embargo, las construcciones sintéticas pueden variar entre diferentes implementaciones del compilador de Java, lo que significa que los archivos .class también pueden variar entre diferentes implementaciones.
referencia: docs.oracle.com
fuente
Como varias respuestas ya han señalado, el compilador puede generar varias construcciones (incluidas las clases) que no se corresponden directamente con algo en el código fuente. Estos deben marcarse como sintéticos:
13.1 La forma de un binario
Como señaló @Holger en un comentario a otra pregunta, ejemplos relevantes para tales construcciones son los objetos de clase que representan referencias de métodos y lambdas:
Salida:
Si bien esto no se menciona explícitamente, se desprende de 15.27.4. Evaluación en tiempo de ejecución de expresiones lambda :
y la redacción casi idéntica para las referencias de métodos ( 15.13.3. Evaluación en tiempo de ejecución de las referencias de métodos ).
Como esta clase no se menciona explícitamente en ninguna parte del código fuente, tiene que ser sintética.
fuente
Si lo hago bien, se genera una clase sintética sobre la marcha, sin tener que darle un nombre explícito. Por ejemplo:
Esto crea una subclase sintética de Thread y anula su método run (), luego lo instancia y lo inicia.
fuente
Outer$1.class
.Una clase sintética no aparece en su código: está compuesta por el compilador. Por ejemplo, un método puente compuesto por un compilador en Java es típicamente sintético.
Usando el comando
javap -verbose DateInterval
, puede ver un método de puente:Esto fue hecho por el compilador; No aparece en su código.
fuente
Una
synthetic
clase es un.class
archivo generado por Java Compiler y no existe en el código fuente.Ejemplo de uso de la
synthetic
clase: clase interna anónimasynthetic
clase y es una clase interna anónima dentro java.text.DigitListDigitList$1.java
pero es un archivo interno enDigitList.java
Es un mecanismo dentro de la lógica del compilador de Java para generar el
.class
archivoNo, los desarrolladores NO usan directamente.
El compilador de Java utiliza
synthetic
para generar el.class
archivo, y luego JVM lee el.class
archivo para ejecutar la lógica del programa.Más detalles
synthetic
clase en detallessynthetic
las salidas de clase en JDKfuente
Las construcciones sintéticas son clases, métodos, campos, etc. que no tienen una construcción correspondiente en el código fuente. Las construcciones sintéticas permiten a los compiladores de Java implementar nuevas características del lenguaje Java sin cambios en la JVM. Sin embargo, las construcciones sintéticas pueden variar entre diferentes implementaciones del compilador de Java, lo que significa que los archivos .class también pueden variar entre diferentes implementaciones.
fuente