Что такое синтетический класс в Java? Зачем его использовать? Как я могу использовать это?
Что такое синтетический класс в Java? Зачем его использовать? Как я могу использовать это?
Ответы:
Например, когда у вас есть оператор 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
говорит: Возвращает истину, если этот элемент был введен компилятором; в противном случае возвращает false
java.lang.reflect.Member#isSynthetic
имеет отношения к первоначальному вопросу. Члены - это поля, конструкторы и методы. Первоначальный вопрос был о синтетических классах , а не о синтетических членах. В Java 8 лямбда-выражения порождают синтетические классы - я не уверен, при каких других обстоятельствах они могут возникнуть.
Ну я нашел ответ на первый вопрос в Google:
Класс может быть помечен как синтетический, если он генерируется компилятором, то есть он не отображается в исходном коде.
Это просто базовое определение, но я нашел его в ветке форума, и не было никакого объяснения. Все еще в поисках лучшего ...
синтетические классы / методы / поля:
Эти вещи важны для ВМ. Взгляните на следующий фрагмент кода:
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() {
}
}
}
Согласно этой дискуссии , хотя спецификация языка описывает свойство 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 для создания реализаций интерфейсов или абстрактных классов во время выполнения.
Когда компилятор Java компилирует определенные конструкции, такие как внутренние классы, он создает синтетические конструкции ; это классы, методы, поля и другие конструкции, которые не имеют соответствующей конструкции в исходном коде.
Использование:
Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях.
ссылка: docs.oracle.com
Как уже указывалось в различных ответах, компилятору разрешено генерировать различные конструкции (включая классы), которые не соответствуют напрямую чему-либо в исходном коде. Они должны быть помечены как синтетические:
Бинарное представление для класса или интерфейса также должно содержать все следующее:
[...]
11. Конструкция, испускаемая компилятором Java, должна быть помечена как синтетическая, если она не соответствует конструкции, объявленной явно или неявно в исходном коде. если только выпущенная конструкция не является методом инициализации класса (JVMS §2.9).
[...]
Как отметил @Holger в комментарии к другому вопросу, уместными примерами таких конструкций являются объекты Class, представляющие ссылки на методы и лямбда-выражения:
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
Вывод:
true
true
Хотя это прямо не упоминается, это следует из 15.27.4. Оценка лямбда-выражений во время выполнения :
Значение лямбда-выражения является ссылкой на экземпляр класса со следующими свойствами: [...]
и почти идентичная формулировка для ссылок на методы ( 15.13.3. Оценка ссылок на методы во время выполнения) ).
Поскольку этот класс явно не упоминается нигде в исходном коде, он должен быть синтетическим.
Если я правильно понял, синтетический класс генерируется на лету, без необходимости давать ему явное имя. Например:
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
Это создает синтетический подкласс Thread и переопределяет его метод run (), затем создает его экземпляр и запускает.
Outer$1.class
.
Синтетический класс не появляется в вашем коде: он составлен компилятором. Например, метод моста, составленный компилятором в Java, обычно является синтетическим.
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");
}
}
Используя команду javap -verbose DateInterval
, вы можете увидеть метод моста:
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Это было составлено компилятором; это не появляется в вашем коде.
Что такое синтетический класс в Java?
synthetic
Класс представляет собой .class
файл , созданный с помощью Java Compiler и не существует в исходном коде.
Пример использования synthetic
класса: Анонимный внутренний класс
synthetic
классом, и это внутренний анонимный класс внутри java.text.DigitListDigitList$1.java
но это внутренний файл вDigitList.java
Зачем его использовать?
Это механизм внутри логики компилятора Java для генерации .class
файла
Как я могу использовать это?
Нет, разработчики НЕ используют его напрямую.
Компилятор Java используют synthetic
для генерации .class
файла, а затем JVM читает .class
файл для выполнения логики программы.
Синтетические конструкции - это классы, методы, поля и т. Д., Которые не имеют соответствующей конструкции в исходном коде. Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, а это означает, что файлы .class также могут различаться в разных реализациях.