Wszystkie odpowiedzi „nie w Twoim kodzie” są nieaktualne w Javie 8, ponieważ lambdy mogą być implementowane jako klasy syntetyczne (nie anonimowe).
OrangeDog
Szczerze mówiąc, lambda nadal nie jest „ściśle” klasą zdefiniowaną jawnie w kodzie. Zatem „nie w Twoim kodzie” jest nadal ważne. Kompilator generuje klasy syntetyczne bez jawnej definicji w kodzie.
ManoDestra
Odpowiedzi:
15
Na przykład, gdy masz instrukcję switch, java tworzy zmienną zaczynającą się od $. Jeśli chcesz zobaczyć przykład tego, zajrzyj do odbicia Java klasy, która zawiera instrukcję switch. Zobaczysz te zmienne, gdy masz co najmniej jedną instrukcję switch w dowolnym miejscu w klasie.
Odpowiadając na twoje pytanie, nie wierzę, że jesteś w stanie uzyskać dostęp (poza refleksją) do klas syntetycznych.
Jeśli analizujesz klasę, o której nic nie wiesz (poprzez refleksję) i potrzebujesz wiedzieć bardzo szczegółowe i niskopoziomowe informacje o tej klasie, możesz skończyć z wykorzystaniem metod odbicia Java, które mają do czynienia z klasami syntetycznymi. Jedynym „zastosowaniem” tutaj jest uzyskanie większej ilości informacji o klasie w celu odpowiedniego jej wykorzystania w kodzie.
(Jeśli to robisz, prawdopodobnie tworzysz pewnego rodzaju strukturę, z której mogliby korzystać inni programiści).
W przeciwnym razie, jeśli nie używasz refleksji, nie ma praktycznego zastosowania klas syntetycznych, o których wiem.
Tak, przykładowy kod byłby dobry, gdybyś mógł podać przykład /
nanofarad
36
To nie odpowiada na pytanie.
Dawood ibn Kareem
W przypadku przełącznika nie jestem pewien, czy dzieje się tak dla każdego przełącznika, ale zaobserwowałem to w przypadku przełącznika z wyliczeniami; kompilator generuje anonimową klasę z pojedynczym statycznym polem, które zapewnia mapowanie Enum.ordinal () -> 1, 2, 3 ... (czyli sekwencja bez przerw), a następnie instrukcja lookupswitch uruchamia przełącznik na tej sekwencji, a nie bezpośrednio na liczbach porządkowych.
Radim Vansa,
106
Java ma możliwość tworzenia klas w czasie wykonywania. Te klasy są znane jako klasy syntetyczne lub dynamiczne proxy.
Inne biblioteki open source, takie jak CGLIB i ASM, również umożliwiają generowanie klas syntetycznych i mają większe możliwości niż biblioteki dostarczane ze środowiskiem JRE.
Klasy syntetyczne są używane przez biblioteki AOP (Aspect Oriented Programming), takie jak Spring AOP i AspectJ, a także biblioteki ORM, takie jak Hibernate.
Dynamiczne proxy nie są Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
klasami
3
Element javadoc for java.lang.reflect.Member#isSyntheticmówi: Zwraca wartość true, jeśli ten element członkowski został wprowadzony przez kompilator; w przeciwnym razie zwraca false.
Guillaume Husta
Uważam, że javadoc for java.lang.reflect.Member#isSyntheticnie ma związku z pierwotnym pytaniem. Członkami są pola, konstruktory i metody. Pierwotne pytanie dotyczyło klas syntetycznych , a nie syntetycznych członków. W Javie 8 wyrażenia lambda dają początek klasom syntetycznym - nie jestem pewien, jakie inne okoliczności mogą zaistnieć.
Ks. Jeremy Krieg
54
Dobrze znalazłem odpowiedź na pierwsze pytanie w google:
Klasa może być oznaczona jako syntetyczna, jeśli jest generowana przez kompilator, czyli nie pojawia się w kodzie źródłowym.
To tylko podstawowa definicja, ale znalazłem ją w wątku na forum i nie było żadnego wyjaśnienia. Wciąż szukam lepszego ...
Te rzeczy są ważne dla maszyny wirtualnej. Spójrz na następujący fragment kodu:
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, only syntetyczne metody pomocnicze.
Miha_x64
8
Zgodnie z tą dyskusją , chociaż specyfikacja języka opisuje właściwość „isSynthetic” dla klas, jest to prawie ignorowane przez implementacje i nie jest używane ani w przypadku dynamicznych serwerów proxy, ani klas anonimowych. Do implementacji klas zagnieżdżonych używa się pól syntetycznych i konstruktorów (nie ma koncepcji klas zagnieżdżonych w kodzie bajtowym, tylko w kodzie źródłowym).
Myślę, że koncepcja klas syntetycznych po prostu okazała się nieprzydatna, tj. Nikogo nie obchodzi, czy klasa jest syntetyczna. W przypadku pól i metod jest prawdopodobnie używany dokładnie w jednym miejscu: do określenia, co ma być wyświetlane w widoku struktury klas IDE - chcesz, aby pokazywały się tam zwykłe metody i pola, ale nie te syntetyczne używane do symulacji zagnieżdżonych klas. OTOH, CHCESZ, aby pokazywały się tam anonimowe zajęcia.
Ta odpowiedź wydaje się być przestarzała, ponieważ java 8 - lambdy i odwołania do metod wykorzystują tę funkcję. Dodałem odpowiedź, która to potwierdza
Hulk
7
Są tworzone przez maszynę JVM w czasie wykonywania, gdy wywołują prywatne elementy członkowskie klasy wewnętrznej w celu debugowania
Metody, pola i klasy utworzone przez maszynę JVM w czasie wykonywania w celu jej wykonania nazywane są syntetycznymi
Myślę, że masz na myśli w czasie kompilacji, a nie w czasie wykonywania.
Mostowski Collapse
@sathis, czy chodziło Ci o javac, a nie o JVM?
Miha_x64
3
Również klasy syntetyczne lub dynamiczne proxy są używane przez EasyMock do tworzenia implementacji interfejsów lub klas abstrakcyjnych w czasie wykonywania.
Kiedy kompilator Java kompiluje określone konstrukcje, takie jak klasy wewnętrzne, tworzy konstrukcje syntetyczne ; są to klasy, metody, pola i inne konstrukcje, które nie mają odpowiedniej konstrukcji w kodzie źródłowym. Zastosowania:
Konstrukcje syntetyczne umożliwiają kompilatorom języka Java wdrażanie nowych funkcji języka Java bez wprowadzania zmian w JVM. Jednak konstrukcje syntetyczne mogą się różnić w różnych implementacjach kompilatora Java, co oznacza, że pliki .class mogą się różnić również w różnych implementacjach. źródło : docs.oracle.com
Jak już wskazywały różne odpowiedzi, kompilator może generować różne konstrukcje (w tym klasy), które nie odpowiadają bezpośrednio czemuś w kodzie źródłowym. Muszą być oznaczone jako syntetyczne:
Binarna reprezentacja klasy lub interfejsu musi również zawierać wszystkie następujące elementy:
[...]
11. Konstrukcja emitowana przez kompilator języka Java musi być oznaczona jako syntetyczna, jeśli nie odpowiada konstrukcji zadeklarowanej jawnie lub niejawnie w kodzie źródłowym , chyba że emitowana konstrukcja jest metodą inicjalizacji klasy (JVMS §2.9).
[…]
Jak zauważył @Holger w komentarzu do innego pytania, odpowiednimi przykładami takich konstrukcji są obiekty Class reprezentujące odwołania do metod i lambdy:
Muszę się zgodzić z @KumarAbhinav. Nie wszystkie anonimowe klasy wewnętrzne są syntetyczne. Zobacz: xinotes.net/notes/note/1339
bvdb
Anonimowe klasy wewnętrzne nie generują klas syntetycznych w Oracle JDK 1.8.0_45, generują oddzielne niesyntetyczne klasy z nazwami typów Outer$1.class.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Co to jest klasa syntetyczna w Javie?
syntheticKlasa jest .classplik generowany przez Java Compiler i nie istnieje w kodzie źródłowym.
Przykładowe użycie syntheticklasy: Anonimowa klasa wewnętrzna
Konstrukcje syntetyczne to klasy, metody, pola itp., Które nie mają odpowiedniej konstrukcji w kodzie źródłowym. Konstrukcje syntetyczne umożliwiają kompilatorom języka Java wdrażanie nowych funkcji języka Java bez wprowadzania zmian w JVM. Jednak konstrukcje syntetyczne mogą się różnić w różnych implementacjach kompilatora Java, co oznacza, że pliki .class mogą się różnić również w różnych implementacjach.
-1. Ten sam tekst, dosłownie, został zamieszczony w odpowiedzi udzielonej rok wcześniej [ stackoverflow.com/a/24271953/1144395] , a ponadto ta odpowiedź dodatkowo zacytowała oficjalne odniesienie, z którego pochodzi tekst, i zapewniła formatowanie ułatwiające czytanie . Nie spamuj chciwie pytań z wyraźnie zduplikowanymi odpowiedziami.
naki
0
Klasa syntetyczna nie pojawia się w twoim kodzie: jest tworzona przez kompilator. Np. Metoda pomostowa utworzona przez kompilator w Javie jest zazwyczaj syntetyczna.
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");}}
Za pomocą polecenia javap -verbose DateIntervalmożesz zobaczyć metodę mostu:
Odpowiedzi:
Na przykład, gdy masz instrukcję switch, java tworzy zmienną zaczynającą się od $. Jeśli chcesz zobaczyć przykład tego, zajrzyj do odbicia Java klasy, która zawiera instrukcję switch. Zobaczysz te zmienne, gdy masz co najmniej jedną instrukcję switch w dowolnym miejscu w klasie.
Odpowiadając na twoje pytanie, nie wierzę, że jesteś w stanie uzyskać dostęp (poza refleksją) do klas syntetycznych.
Jeśli analizujesz klasę, o której nic nie wiesz (poprzez refleksję) i potrzebujesz wiedzieć bardzo szczegółowe i niskopoziomowe informacje o tej klasie, możesz skończyć z wykorzystaniem metod odbicia Java, które mają do czynienia z klasami syntetycznymi. Jedynym „zastosowaniem” tutaj jest uzyskanie większej ilości informacji o klasie w celu odpowiedniego jej wykorzystania w kodzie.
(Jeśli to robisz, prawdopodobnie tworzysz pewnego rodzaju strukturę, z której mogliby korzystać inni programiści).
W przeciwnym razie, jeśli nie używasz refleksji, nie ma praktycznego zastosowania klas syntetycznych, o których wiem.
źródło
Java ma możliwość tworzenia klas w czasie wykonywania. Te klasy są znane jako klasy syntetyczne lub dynamiczne proxy.
Więcej informacji można znaleźć pod adresem http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html .
Inne biblioteki open source, takie jak CGLIB i ASM, również umożliwiają generowanie klas syntetycznych i mają większe możliwości niż biblioteki dostarczane ze środowiskiem JRE.
Klasy syntetyczne są używane przez biblioteki AOP (Aspect Oriented Programming), takie jak Spring AOP i AspectJ, a także biblioteki ORM, takie jak Hibernate.
źródło
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
mówi: Zwraca wartość true, jeśli ten element członkowski został wprowadzony przez kompilator; w przeciwnym razie zwraca false.java.lang.reflect.Member#isSynthetic
nie ma związku z pierwotnym pytaniem. Członkami są pola, konstruktory i metody. Pierwotne pytanie dotyczyło klas syntetycznych , a nie syntetycznych członków. W Javie 8 wyrażenia lambda dają początek klasom syntetycznym - nie jestem pewien, jakie inne okoliczności mogą zaistnieć.Dobrze znalazłem odpowiedź na pierwsze pytanie w google:
To tylko podstawowa definicja, ale znalazłem ją w wątku na forum i nie było żadnego wyjaśnienia. Wciąż szukam lepszego ...
źródło
syntetyczne klasy / metody / pola:
Te rzeczy są ważne dla maszyny wirtualnej. Spójrz na następujący fragment kodu:
źródło
Zgodnie z tą dyskusją , chociaż specyfikacja języka opisuje właściwość „isSynthetic” dla klas, jest to prawie ignorowane przez implementacje i nie jest używane ani w przypadku dynamicznych serwerów proxy, ani klas anonimowych. Do implementacji klas zagnieżdżonych używa się pól syntetycznych i konstruktorów (nie ma koncepcji klas zagnieżdżonych w kodzie bajtowym, tylko w kodzie źródłowym).
Myślę, że koncepcja klas syntetycznych po prostu okazała się nieprzydatna, tj. Nikogo nie obchodzi, czy klasa jest syntetyczna. W przypadku pól i metod jest prawdopodobnie używany dokładnie w jednym miejscu: do określenia, co ma być wyświetlane w widoku struktury klas IDE - chcesz, aby pokazywały się tam zwykłe metody i pola, ale nie te syntetyczne używane do symulacji zagnieżdżonych klas. OTOH, CHCESZ, aby pokazywały się tam anonimowe zajęcia.
źródło
Są tworzone przez maszynę JVM w czasie wykonywania, gdy wywołują prywatne elementy członkowskie klasy wewnętrznej w celu debugowania
Metody, pola i klasy utworzone przez maszynę JVM w czasie wykonywania w celu jej wykonania nazywane są syntetycznymi
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
źródło
Również klasy syntetyczne lub dynamiczne proxy są używane przez EasyMock do tworzenia implementacji interfejsów lub klas abstrakcyjnych w czasie wykonywania.
http://www.easymock.org/
źródło
Kiedy kompilator Java kompiluje określone konstrukcje, takie jak klasy wewnętrzne, tworzy konstrukcje syntetyczne ; są to klasy, metody, pola i inne konstrukcje, które nie mają odpowiedniej konstrukcji w kodzie źródłowym.
Zastosowania: Konstrukcje syntetyczne umożliwiają kompilatorom języka Java wdrażanie nowych funkcji języka Java bez wprowadzania zmian w JVM. Jednak konstrukcje syntetyczne mogą się różnić w różnych implementacjach kompilatora Java, co oznacza, że pliki .class mogą się różnić również w różnych implementacjach. źródło
: docs.oracle.com
źródło
Jak już wskazywały różne odpowiedzi, kompilator może generować różne konstrukcje (w tym klasy), które nie odpowiadają bezpośrednio czemuś w kodzie źródłowym. Muszą być oznaczone jako syntetyczne:
13.1. Forma binarna
Jak zauważył @Holger w komentarzu do innego pytania, odpowiednimi przykładami takich konstrukcji są obiekty Class reprezentujące odwołania do metod i lambdy:
Wynik:
Chociaż nie jest to wyraźnie wymienione, wynika to z 15.27.4. Ocena wyrażeń lambda w czasie rzeczywistym :
oraz prawie identyczne sformułowanie odniesień do metod ( 15.13.3. Ocena odniesień do metod w czasie wykonywania ).
Ponieważ ta klasa nie jest wyraźnie wymieniona w kodzie źródłowym, musi być syntetyczna.
źródło
Jeśli dobrze rozumiem, klasa syntetyczna to klasa generowana w locie, bez konieczności nadawania jej wyraźnej nazwy. Na przykład:
Spowoduje to utworzenie syntetycznej podklasy Thread i nadpisanie jej metody run (), a następnie utworzenie jej wystąpienia i uruchomienie.
źródło
Outer$1.class
.synthetic
Klasa jest.class
plik generowany przez Java Compiler i nie istnieje w kodzie źródłowym.Przykładowe użycie
synthetic
klasy: Anonimowa klasa wewnętrznasynthetic
klasa i jest to anonimowa klasa wewnętrzna wewnątrz java.text.DigitListDigitList$1.java
ale jest to plik wewnętrzny wDigitList.java
Jest to mechanizm wewnątrz logiki kompilatora Java do generowania
.class
plikuNie, programiści NIE używają go bezpośrednio.
Kompilator Java służy
synthetic
do generowania.class
pliku, a następnie JVM odczytuje.class
plik w celu wykonania logiki programu.Więcej szczegółów
synthetic
zajęciasynthetic
wyjść z klas w JDKźródło
Konstrukcje syntetyczne to klasy, metody, pola itp., Które nie mają odpowiedniej konstrukcji w kodzie źródłowym. Konstrukcje syntetyczne umożliwiają kompilatorom języka Java wdrażanie nowych funkcji języka Java bez wprowadzania zmian w JVM. Jednak konstrukcje syntetyczne mogą się różnić w różnych implementacjach kompilatora Java, co oznacza, że pliki .class mogą się różnić również w różnych implementacjach.
źródło
Klasa syntetyczna nie pojawia się w twoim kodzie: jest tworzona przez kompilator. Np. Metoda pomostowa utworzona przez kompilator w Javie jest zazwyczaj syntetyczna.
Za pomocą polecenia
javap -verbose DateInterval
możesz zobaczyć metodę mostu:Zostało to stworzone przez kompilator; nie pojawia się w Twoim kodzie.
źródło