Синтетический класс на Java - PullRequest
       105

Синтетический класс на Java

133 голосов
/ 30 декабря 2008

Что такое синтетический класс в Java? Зачем его использовать? Как я могу использовать это?

Ответы [ 12 ]

103 голосов
/ 30 декабря 2008

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.

54 голосов
/ 30 декабря 2008

Ну я нашел ответ на первый вопрос в Google:

Класс может быть помечен как синтетический, если это генерируется компилятором, что есть, его нет в источнике Код.

Это просто базовое определение, но я нашел его в ветке форума, и объяснений не было. Все еще в поисках лучшего ...

14 голосов
/ 11 августа 2009

синтетические классы / методы / поля:

Эти вещи важны для ВМ. Взгляните на следующий фрагмент кода:

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() {
    }
  }
}
14 голосов
/ 31 декабря 2008

Например, когда у вас есть оператор switch, java создает переменную, которая начинается с $. Если вы хотите увидеть пример этого, загляните в java-отражение класса, в котором есть оператор switch. Вы увидите эти переменные, когда у вас есть хотя бы один оператор switch в любом месте класса.

Чтобы ответить на ваш вопрос, я не верю, что вы можете получить доступ (кроме рефлексии) к синтетическим классам.

Если вы анализируете класс, о котором ничего не знаете (с помощью рефлексии), и вам необходимо знать очень специфические и низкоуровневые вещи об этом классе, вы можете использовать методы отражения Java, связанные с классы. Единственное «использование» здесь - это получить больше информации о классе, чтобы правильно использовать его в своем коде.

(Если вы делаете это, вы, вероятно, создаете какую-то структуру, которую могли бы использовать другие разработчики.)

В противном случае, если вы не используете рефлексию, я не знаю практического использования синтетических классов.

8 голосов
/ 30 декабря 2008

Согласно этому обсуждению , хотя спецификация языка описывает свойство "isSynthetic" для классов, это в значительной степени игнорируется реализациями и не используется ни для динамических прокси, ни для анонимных классов. Синтетические поля и конструкторы используются для реализации вложенных классов (понятие вложенных классов в байт-коде отсутствует, только в исходном коде).

Я думаю, что концепция синтетических классов просто оказалась бесполезной, то есть никого не волнует, является ли класс синтетическим. С полями и методами это, вероятно, используется точно в одном месте: чтобы определить, что показывать в представлении структуры класса IDE - вы хотите, чтобы там отображались обычные методы и поля, но не синтетические, используемые для имитации вложенных классов. OTOH, вы действительно хотите, чтобы там появлялись анонимные классы.

7 голосов
/ 07 августа 2014

Они создаются JVM во время выполнения, когда они вызывают закрытые члены внутреннего класса для целей отладки

Методы, поля, класс, созданные JVM во время выполнения для его выполнения, называются Synthetic

http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html

http://javapapers.com/core-java/java-synthetic-class-method-field/

3 голосов
/ 30 декабря 2008

Кроме того, синтетические классы или динамические прокси используются EasyMock для создания реализаций интерфейсов или абстрактных классов во время выполнения.

http://www.easymock.org/

2 голосов
/ 22 ноября 2018

Как уже указывалось в различных ответах, компилятору разрешено генерировать различные конструкции (включая классы), которые напрямую не соответствуют чему-либо в исходном коде. Они должны быть помечены как синтетические:

13,1. Форма двоичного файла

Двоичное представление для класса или интерфейса также должно содержать все следующее:
[...]
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. Оценка ссылок на методы во время выполнения ).

Поскольку этот класс явно не упоминается нигде в исходном коде, он должен быть синтетическим.

2 голосов
/ 17 июня 2014

Когда компилятор Java компилирует определенные конструкции, такие как внутренние классы, он создает синтетические конструкции ; это классы, методы, поля и другие конструкции, которые не имеют соответствующей конструкции в исходном коде.
Использование: Синтетические конструкции позволяют компиляторам Java реализовывать новые функции языка Java без изменений в JVM. Однако синтетические конструкции могут различаться в разных реализациях компилятора Java, что означает, что файлы .class также могут различаться в разных реализациях. Ссылка:

1 голос
/ 23 июня 2011

Если я правильно понял, синтетический класс генерируется на лету, без необходимости давать ему явное имя. Например:

//...
Thread myThread = new Thread() {
         public void run() {
           // do something ...
         }
       };
myThread.start();
//...

Это создает синтетический подкласс Thread и переопределяет его метод run (), затем создает его экземпляр и запускает его.

...