Все ответы «не в вашем коде» устарели в Java 8, поскольку лямбда-выражения могут быть реализованы как синтетические (не анонимные) классы.
OrangeDog
Чтобы быть справедливым, лямбда все еще не "строго" класс, определенный явно в вашем коде. Таким образом, «не в вашем коде» остается в силе. Компилятор генерирует синтетические классы для вас без явного определения в вашем коде.
ManoDestra
Ответы:
15
Например, когда у вас есть оператор switch, java создает переменную, которая начинается с $. Если вы хотите увидеть пример этого, загляните в java-отражение класса, в котором есть оператор switch. Вы увидите эти переменные, когда у вас есть хотя бы один оператор switch в любом месте класса.
Чтобы ответить на ваш вопрос, я не верю, что вы можете получить доступ (кроме рефлексии) к синтетическим классам.
Если вы анализируете класс, о котором ничего не знаете (с помощью рефлексии) и вам нужно знать очень специфические и низкоуровневые вещи об этом классе, вы можете использовать методы отражения Java, которые имеют отношение к синтетическим классам. Единственное «использование» здесь - это получить больше информации о классе, чтобы правильно использовать его в своем коде.
(Если вы делаете это, вы, вероятно, создаете какую-то структуру, которую могли бы использовать другие разработчики.)
В противном случае, если вы не используете рефлексию, я не знаю практического использования синтетических классов.
Да, пример кода был бы хорош, если бы вы могли привести пример /
нанофарад
36
Это не отвечает на вопрос.
Дауд ибн Карим
Для случая переключателя я не уверен, происходит ли это для каждого переключателя, но я наблюдал это для переключателя с перечислениями; компилятор генерирует анонимный класс с одним статическим полем, которое обеспечивает отображение Enum.ordinal () -> 1, 2, 3 ... (то есть последовательность без пробелов), а затем инструкция lookupswitch запускает переключение в этой последовательности, а не напрямую по порядковым номерам.
Радим Ванса
106
Java имеет возможность создавать классы во время выполнения. Эти классы известны как синтетические классы или динамические прокси.
Другие библиотеки с открытым исходным кодом, такие как CGLIB и ASM, также позволяют создавать синтетические классы и являются более мощными, чем библиотеки, поставляемые с JRE.
Синтетические классы используются библиотеками AOP (Aspect Oriented Programming), такими как Spring AOP и AspectJ, а также библиотеками ORM, такими как Hibernate.
Динамические прокси не являются синтетическими классами. Доказательство:Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
Miha_x64
3
Javadoc для java.lang.reflect.Member#isSyntheticговорит: Возвращает истину, если этот элемент был введен компилятором; в противном случае возвращает false
Гийом
Я считаю, что Javadoc для не java.lang.reflect.Member#isSyntheticимеет отношения к первоначальному вопросу. Члены - это поля, конструкторы и методы. Первоначальный вопрос был о синтетических классах , а не о синтетических членах. В Java 8 лямбда-выражения порождают синтетические классы - я не уверен, при каких других обстоятельствах они могут возникнуть.
Отец Джереми Криг
54
Ну я нашел ответ на первый вопрос в Google:
Класс может быть помечен как синтетический, если он генерируется компилятором, то есть он не отображается в исходном коде.
Это просто базовое определение, но я нашел его в ветке форума, и не было никакого объяснения. Все еще в поисках лучшего ...
Эти вещи важны для ВМ. Взгляните на следующий фрагмент кода:
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 г., нет, только синтетические методы доступа.
Miha_x64
8
Согласно этой дискуссии , хотя спецификация языка описывает свойство isSynthetic для классов, это в значительной степени игнорируется реализациями и не используется ни для динамических прокси, ни для анонимных классов. Синтетические поля и конструкторы используются для реализации вложенных классов (понятие вложенных классов отсутствует в байт-коде, только в исходном коде).
Я думаю, что концепция синтетических классов просто оказалась бесполезной, то есть никого не интересует, является ли класс синтетическим. С полями и методами это, вероятно, используется точно в одном месте: чтобы определить, что показывать в представлении структуры класса IDE - вы хотите, чтобы там отображались обычные методы и поля, но не синтетические, используемые для имитации вложенных классов. OTOH, вы действительно хотите анонимные классы, чтобы показать там.
Я предполагаю, что вы имеете в виду во время компиляции, а не во время выполнения.
Мостовский Свернуть
@sathis, ты имел ввиду javac, а не JVM?
Miha_x64
3
Также Синтетические Классы или Динамические Прокси используются EasyMock для создания реализаций интерфейсов или абстрактных классов во время выполнения.
Когда компилятор Java компилирует определенные конструкции, такие как внутренние классы, он создает синтетические конструкции ; это классы, методы, поля и другие конструкции, которые не имеют соответствующей конструкции в исходном коде. Использование:
Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях. ссылка: docs.oracle.com
Как уже указывалось в различных ответах, компилятору разрешено генерировать различные конструкции (включая классы), которые не соответствуют напрямую чему-либо в исходном коде. Они должны быть помечены как синтетические:
Бинарное представление для класса или интерфейса также должно содержать все следующее:
[...]
11. Конструкция, испускаемая компилятором Java, должна быть помечена как синтетическая, если она не соответствует конструкции, объявленной явно или неявно в исходном коде. если только выпущенная конструкция не является методом инициализации класса (JVMS §2.9).
[...]
Как отметил @Holger в комментарии к другому вопросу, уместными примерами таких конструкций являются объекты Class, представляющие ссылки на методы и лямбда-выражения:
Я должен согласиться с @KumarAbhinav. Не все анонимные внутренние классы являются синтетическими. Видеть: xinotes.net/notes/note/1339
bvdb
Анонимные внутренние классы не генерируют синтетические классы в Oracle JDK 1.8.0_45, они генерируют отдельные несинтетические классы с именами типа Outer$1.class.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
1
Синтетический класс не появляется в вашем коде: он составлен компилятором. Например, метод моста, составленный компилятором в Java, обычно является синтетическим.
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");}}
Используя команду javap -verbose DateInterval, вы можете увидеть метод моста:
Синтетические конструкции - это классы, методы, поля и т. Д., Которые не имеют соответствующей конструкции в исходном коде. Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях.
-1. Тот же самый текст, дословно, был опубликован в ответе, который был дан за год до вашего [ stackoverflow.com/a/24271953/1144395] , и, кроме того, в этом ответе дополнительно приводилась официальная ссылка на источник текста, и было предоставлено форматирование для более удобного чтения. , Пожалуйста, не жадно спамите вопросы с четко продублированными ответами.
Ответы:
Например, когда у вас есть оператор switch, java создает переменную, которая начинается с $. Если вы хотите увидеть пример этого, загляните в java-отражение класса, в котором есть оператор switch. Вы увидите эти переменные, когда у вас есть хотя бы один оператор switch в любом месте класса.
Чтобы ответить на ваш вопрос, я не верю, что вы можете получить доступ (кроме рефлексии) к синтетическим классам.
Если вы анализируете класс, о котором ничего не знаете (с помощью рефлексии) и вам нужно знать очень специфические и низкоуровневые вещи об этом классе, вы можете использовать методы отражения Java, которые имеют отношение к синтетическим классам. Единственное «использование» здесь - это получить больше информации о классе, чтобы правильно использовать его в своем коде.
(Если вы делаете это, вы, вероятно, создаете какую-то структуру, которую могли бы использовать другие разработчики.)
В противном случае, если вы не используете рефлексию, я не знаю практического использования синтетических классов.
источник
Java имеет возможность создавать классы во время выполнения. Эти классы известны как синтетические классы или динамические прокси.
См. Http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html для получения дополнительной информации.
Другие библиотеки с открытым исходным кодом, такие как CGLIB и ASM, также позволяют создавать синтетические классы и являются более мощными, чем библиотеки, поставляемые с JRE.
Синтетические классы используются библиотеками AOP (Aspect Oriented Programming), такими как Spring AOP и AspectJ, а также библиотеками ORM, такими как Hibernate.
источник
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
говорит: Возвращает истину, если этот элемент был введен компилятором; в противном случае возвращает falsejava.lang.reflect.Member#isSynthetic
имеет отношения к первоначальному вопросу. Члены - это поля, конструкторы и методы. Первоначальный вопрос был о синтетических классах , а не о синтетических членах. В Java 8 лямбда-выражения порождают синтетические классы - я не уверен, при каких других обстоятельствах они могут возникнуть.Ну я нашел ответ на первый вопрос в Google:
Это просто базовое определение, но я нашел его в ветке форума, и не было никакого объяснения. Все еще в поисках лучшего ...
источник
синтетические классы / методы / поля:
Эти вещи важны для ВМ. Взгляните на следующий фрагмент кода:
источник
Согласно этой дискуссии , хотя спецификация языка описывает свойство isSynthetic для классов, это в значительной степени игнорируется реализациями и не используется ни для динамических прокси, ни для анонимных классов. Синтетические поля и конструкторы используются для реализации вложенных классов (понятие вложенных классов отсутствует в байт-коде, только в исходном коде).
Я думаю, что концепция синтетических классов просто оказалась бесполезной, то есть никого не интересует, является ли класс синтетическим. С полями и методами это, вероятно, используется точно в одном месте: чтобы определить, что показывать в представлении структуры класса IDE - вы хотите, чтобы там отображались обычные методы и поля, но не синтетические, используемые для имитации вложенных классов. OTOH, вы действительно хотите анонимные классы, чтобы показать там.
источник
Они создаются JVM во время выполнения, когда они вызывают закрытые члены внутреннего класса для целей отладки.
Методы, поля, класс, созданные JVM во время выполнения для его выполнения, называются синтетическими.
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
источник
Также Синтетические Классы или Динамические Прокси используются EasyMock для создания реализаций интерфейсов или абстрактных классов во время выполнения.
http://www.easymock.org/
источник
Когда компилятор Java компилирует определенные конструкции, такие как внутренние классы, он создает синтетические конструкции ; это классы, методы, поля и другие конструкции, которые не имеют соответствующей конструкции в исходном коде.
Использование: Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях.
ссылка: docs.oracle.com
источник
Как уже указывалось в различных ответах, компилятору разрешено генерировать различные конструкции (включая классы), которые не соответствуют напрямую чему-либо в исходном коде. Они должны быть помечены как синтетические:
13,1. Форма двоичного файла
Как отметил @Holger в комментарии к другому вопросу, уместными примерами таких конструкций являются объекты Class, представляющие ссылки на методы и лямбда-выражения:
Вывод:
Хотя это прямо не упоминается, это следует из 15.27.4. Оценка лямбда-выражений во время выполнения :
и почти идентичная формулировка для ссылок на методы ( 15.13.3. Оценка ссылок на методы во время выполнения) ).
Поскольку этот класс явно не упоминается нигде в исходном коде, он должен быть синтетическим.
источник
Если я правильно понял, синтетический класс генерируется на лету, без необходимости давать ему явное имя. Например:
Это создает синтетический подкласс Thread и переопределяет его метод run (), затем создает его экземпляр и запускает.
источник
Outer$1.class
.Синтетический класс не появляется в вашем коде: он составлен компилятором. Например, метод моста, составленный компилятором в Java, обычно является синтетическим.
Используя команду
javap -verbose DateInterval
, вы можете увидеть метод моста:Это было составлено компилятором; это не появляется в вашем коде.
источник
synthetic
Класс представляет собой.class
файл , созданный с помощью Java Compiler и не существует в исходном коде.Пример использования
synthetic
класса: Анонимный внутренний классsynthetic
классом, и это внутренний анонимный класс внутри java.text.DigitListDigitList$1.java
но это внутренний файл вDigitList.java
Это механизм внутри логики компилятора Java для генерации
.class
файлаНет, разработчики НЕ используют его напрямую.
Компилятор Java используют
synthetic
для генерации.class
файла, а затем JVM читает.class
файл для выполнения логики программы.Подробнее
synthetic
класс в деталяхsynthetic
выходы класса в JDKисточник
Синтетические конструкции - это классы, методы, поля и т. Д., Которые не имеют соответствующей конструкции в исходном коде. Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях.
источник