Todas as respostas "fora do seu código" estão desatualizadas no Java 8, pois as lambdas podem ser implementadas como classes sintéticas (não anônimas).
OrangeDog
Para ser justo, um lambda ainda não é "estritamente" uma classe definida explicitamente dentro do seu código. Portanto, "fora do seu código" ainda é válido. O compilador gera as classes sintéticas para você sem definição explícita no seu código.
ManoDestra 15/07/19
Respostas:
15
Por exemplo, quando você tem uma instrução switch, o java cria uma variável que começa com um $. Se você quiser ver um exemplo disso, espreite o reflexo java de uma classe que possui uma instrução switch. Você verá essas variáveis quando tiver pelo menos uma instrução switch em qualquer lugar da classe.
Para responder sua pergunta, não acredito que você possa acessar (além da reflexão) as classes sintéticas.
Se você está analisando uma classe sobre a qual você não conhece nada (via reflexão) e precisa saber coisas muito específicas e de baixo nível sobre essa classe, pode acabar usando métodos de reflexão em Java que têm a ver com classes sintéticas. O único "uso" aqui é obter mais informações sobre a classe para usá-la adequadamente em seu código.
(Se você estiver fazendo isso, provavelmente está criando uma estrutura de algum tipo que outros desenvolvedores poderiam usar.)
Caso contrário, se você não estiver usando reflexão, não há usos práticos de classes sintéticas que eu conheça.
Sim, código de exemplo seria bom se você pudesse dar um exemplo /
nanofarad
36
Isso não responde à pergunta.
Dawood ibn Kareem
Para o caso do switch, não tenho certeza se isso acontece em todos os switches, mas observei isso no switch com enumerações; o compilador gera classe anônima com um campo estático único que fornece um mapeamento Enum.ordinal () -> 1, 2, 3 ... (para uma sequência sem lacunas) e, em seguida, uma instrução de pesquisa executa o comutador nessa sequência, não diretamente em ordinais.
Radim Vansa
106
Java tem a capacidade de criar classes em tempo de execução. Essas classes são conhecidas como Classes sintéticas ou Proxies dinâmicos.
Outras bibliotecas de código-fonte aberto, como CGLIB e ASM, também permitem gerar classes sintéticas e são mais poderosas que as bibliotecas fornecidas com o JRE.
As classes sintéticas são usadas pelas bibliotecas AOP (Aspect Oriented Programming), como Spring AOP e AspectJ, bem como pelas bibliotecas ORM, como o Hibernate.
Proxies dinâmicos não são Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
classes
3
O javadoc para java.lang.reflect.Member#isSyntheticdiz: Retorna true se esse membro foi introduzido pelo compilador; retorna false caso contrário.
Guillaume Husta 17/02
Eu acredito que o javadoc para java.lang.reflect.Member#isSyntheticé irrelevante para a pergunta original. Membros são campos, construtores e métodos. A pergunta original era sobre classes sintéticas , não membros sintéticos. No Java 8, as expressões lambda dão origem a classes sintéticas - não tenho certeza de que outras circunstâncias possam surgir.
P. Jeremy Krieg
54
Bem, eu encontrei a resposta para a primeira pergunta no google:
Uma classe pode ser marcada como sintética se for gerada pelo compilador, ou seja, não aparecer no código-fonte.
Esta é apenas uma definição básica, mas eu a encontrei em um tópico do fórum e não havia explicação. Ainda procurando um melhor ...
Essas coisas são importantes para a VM. Veja o seguinte snippet 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 六四 事件 法轮功, não, apenas métodos de acesso sintético.
precisa saber é o seguinte
8
De acordo com essa discussão , embora a especificação da linguagem descreva uma propriedade "isSynthetic" para classes, isso é praticamente ignorado pelas implementações e não é usado para proxies dinâmicos ou classes anônimas. Os campos e construtores sintéticos são usados para implementar classes aninhadas (não há conceito de classes aninhadas no código de bytes, apenas no código-fonte).
Eu acho que o conceito de classe sintética simplesmente provou não ser útil, ou seja, ninguém se importa se uma classe é sintética. Com campos e métodos, provavelmente é usado em exatamente um lugar: para determinar o que mostrar em uma exibição de estrutura de classe IDE - você deseja que métodos e campos normais sejam exibidos lá, mas não os sintéticos usados para simular classes aninhadas. OTOH, você deseja que classes anônimas apareçam lá.
Esta resposta parece estar desatualizada, já que as referências ao método 8 - lambdas e java utilizam esse recurso. Eu adicionei uma resposta demonstrando isso
Hulk
7
Eles são criados pela JVM em tempo de execução, quando invocam membros privados da classe interna para fins de depuração
Os métodos, campos, classe criados pela JVM durante o tempo de execução para sua finalidade de execução são chamados Synthetic
Eu acho que você quer dizer em tempo de compilação, e não em tempo de execução.
Mostowski Collapse
@athis, você quis dizer javac, não JVM?
Miha_x64
3
Classes sintéticas ou proxies dinâmicos também são usados pelo EasyMock para criar implementações de interfaces ou classes abstratas em tempo de execução.
Quando o compilador Java compila certas construções, como classes internas, ele cria construções sintéticas ; são classes, métodos, campos e outras construções que não possuem uma construção correspondente no código-fonte. Usos:
Construções sintéticas permitem que os compiladores Java implementem novos recursos da linguagem Java sem alterações na JVM. No entanto, construções sintéticas podem variar entre diferentes implementações do compilador Java, o que significa que os arquivos .class também podem variar entre diferentes implementações. referência: docs.oracle.com
Como várias respostas já apontaram, o compilador pode gerar várias construções (incluindo classes) que não correspondem diretamente a algo no código de fonte. Estes devem ser marcados como sintéticos:
Uma representação binária para uma classe ou interface também deve conter todo o
[...] seguinte:
11. Uma construção emitida por um compilador Java deve ser marcada como sintética se não corresponder a uma construção declarada explícita ou implicitamente no código-fonte. , a menos que a construção emitida seja um método de inicialização de classe (JVMS §2.9).
[...]
Conforme apontado por @Holger em um comentário para outra pergunta, exemplos relevantes para essas construções são os objetos Class que representam referências de método e lambdas:
Eu tenho que concordar com @KumarAbhinav. Nem todas as classes internas anônimas são sintéticas. Veja: xinotes.net/notes/note/1339
bvdb
Classes internas anônimas não geram classes sintéticas no Oracle JDK 1.8.0_45, elas geram classes não sintéticas separadas com nomes do tipo Outer$1.class.
Ciro Santilli escreveu:
1
Uma classe sintética não aparece no seu código: é composta pelo compilador. Por exemplo, um método de ponte composto pelo compilador em java é tipicamente 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 o comando javap -verbose DateInterval, você pode ver um método de ponte:
Construções sintéticas são classes, métodos, campos etc. que não possuem uma construção correspondente no código-fonte. Construções sintéticas permitem que os compiladores Java implementem novos recursos da linguagem Java sem alterações na JVM. No entanto, construções sintéticas podem variar entre diferentes implementações do compilador Java, o que significa que os arquivos .class também podem variar entre diferentes implementações.
-1. O mesmo texto, literalmente, foi publicado na resposta dada um ano antes da sua [ stackoverflow.com/a/24271953/1144395] e, ainda mais, essa resposta citou adicionalmente a referência oficial onde o texto se originou e forneceu formatação para facilitar a leitura . Por favor, não envie mensagens de spam avidamente com respostas claramente duplicadas.
Respostas:
Por exemplo, quando você tem uma instrução switch, o java cria uma variável que começa com um $. Se você quiser ver um exemplo disso, espreite o reflexo java de uma classe que possui uma instrução switch. Você verá essas variáveis quando tiver pelo menos uma instrução switch em qualquer lugar da classe.
Para responder sua pergunta, não acredito que você possa acessar (além da reflexão) as classes sintéticas.
Se você está analisando uma classe sobre a qual você não conhece nada (via reflexão) e precisa saber coisas muito específicas e de baixo nível sobre essa classe, pode acabar usando métodos de reflexão em Java que têm a ver com classes sintéticas. O único "uso" aqui é obter mais informações sobre a classe para usá-la adequadamente em seu código.
(Se você estiver fazendo isso, provavelmente está criando uma estrutura de algum tipo que outros desenvolvedores poderiam usar.)
Caso contrário, se você não estiver usando reflexão, não há usos práticos de classes sintéticas que eu conheça.
fonte
Java tem a capacidade de criar classes em tempo de execução. Essas classes são conhecidas como Classes sintéticas ou Proxies dinâmicos.
Consulte http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html para obter mais informações.
Outras bibliotecas de código-fonte aberto, como CGLIB e ASM, também permitem gerar classes sintéticas e são mais poderosas que as bibliotecas fornecidas com o JRE.
As classes sintéticas são usadas pelas bibliotecas AOP (Aspect Oriented Programming), como Spring AOP e AspectJ, bem como pelas bibliotecas ORM, como o Hibernate.
fonte
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
diz: Retorna true se esse membro foi introduzido pelo compilador; retorna false caso contrário.java.lang.reflect.Member#isSynthetic
é irrelevante para a pergunta original. Membros são campos, construtores e métodos. A pergunta original era sobre classes sintéticas , não membros sintéticos. No Java 8, as expressões lambda dão origem a classes sintéticas - não tenho certeza de que outras circunstâncias possam surgir.Bem, eu encontrei a resposta para a primeira pergunta no google:
Esta é apenas uma definição básica, mas eu a encontrei em um tópico do fórum e não havia explicação. Ainda procurando um melhor ...
fonte
classes / métodos / campos sintéticos:
Essas coisas são importantes para a VM. Veja o seguinte snippet de código:
fonte
De acordo com essa discussão , embora a especificação da linguagem descreva uma propriedade "isSynthetic" para classes, isso é praticamente ignorado pelas implementações e não é usado para proxies dinâmicos ou classes anônimas. Os campos e construtores sintéticos são usados para implementar classes aninhadas (não há conceito de classes aninhadas no código de bytes, apenas no código-fonte).
Eu acho que o conceito de classe sintética simplesmente provou não ser útil, ou seja, ninguém se importa se uma classe é sintética. Com campos e métodos, provavelmente é usado em exatamente um lugar: para determinar o que mostrar em uma exibição de estrutura de classe IDE - você deseja que métodos e campos normais sejam exibidos lá, mas não os sintéticos usados para simular classes aninhadas. OTOH, você deseja que classes anônimas apareçam lá.
fonte
Eles são criados pela JVM em tempo de execução, quando invocam membros privados da classe interna para fins de depuração
Os métodos, campos, classe criados pela JVM durante o tempo de execução para sua finalidade de execução são chamados Synthetic
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
fonte
Classes sintéticas ou proxies dinâmicos também são usados pelo EasyMock para criar implementações de interfaces ou classes abstratas em tempo de execução.
http://www.easymock.org/
fonte
Quando o compilador Java compila certas construções, como classes internas, ele cria construções sintéticas ; são classes, métodos, campos e outras construções que não possuem uma construção correspondente no código-fonte.
Usos: Construções sintéticas permitem que os compiladores Java implementem novos recursos da linguagem Java sem alterações na JVM. No entanto, construções sintéticas podem variar entre diferentes implementações do compilador Java, o que significa que os arquivos .class também podem variar entre diferentes implementações.
referência: docs.oracle.com
fonte
Como várias respostas já apontaram, o compilador pode gerar várias construções (incluindo classes) que não correspondem diretamente a algo no código de fonte. Estes devem ser marcados como sintéticos:
13.1 A forma de um binário
Conforme apontado por @Holger em um comentário para outra pergunta, exemplos relevantes para essas construções são os objetos Class que representam referências de método e lambdas:
Resultado:
Embora isso não seja mencionado explicitamente, segue-se de 15.27.4. Avaliação em tempo de execução de expressões lambda :
e a redação quase idêntica para as referências de método ( 15.13.3. Avaliação em tempo de execução das referências de método ).
Como essa classe não é mencionada explicitamente em nenhum lugar do código-fonte, ela deve ser sintética.
fonte
Se eu entendi direito, uma classe sintética é aquela gerada em tempo real, sem precisar dar um nome explícito. Por exemplo:
Isso cria uma subclasse sintética de Thread e substitui seu método run (), depois a instancia e inicia.
fonte
Outer$1.class
.Uma classe sintética não aparece no seu código: é composta pelo compilador. Por exemplo, um método de ponte composto pelo compilador em java é tipicamente sintético.
Usando o comando
javap -verbose DateInterval
, você pode ver um método de ponte:Isso foi composto pelo compilador; não aparece no seu código.
fonte
Uma
synthetic
classe é um.class
arquivo gerado pelo Java Compiler e não existe no código-fonte.Exemplo de uso da
synthetic
classe: Classe interna anônimasynthetic
classe e é uma classe interna anônima dentro de java.text.DigitListDigitList$1.java
mas é um arquivo interno emDigitList.java
É um mecanismo dentro da lógica do compilador Java para gerar o
.class
arquivoNão, os desenvolvedores NÃO o usam diretamente.
O compilador Java usa
synthetic
para gerar.class
arquivo e, em seguida, a JVM lê o.class
arquivo para executar a lógica do programa.Mais detalhes
synthetic
aula em detalhessynthetic
as saídas de classe no JDKfonte
Construções sintéticas são classes, métodos, campos etc. que não possuem uma construção correspondente no código-fonte. Construções sintéticas permitem que os compiladores Java implementem novos recursos da linguagem Java sem alterações na JVM. No entanto, construções sintéticas podem variar entre diferentes implementações do compilador Java, o que significa que os arquivos .class também podem variar entre diferentes implementações.
fonte