Co to jest klasa syntetyczna w Javie? Dlaczego warto go używać? Jak mogę tego używać?
Co to jest klasa syntetyczna w Javie? Dlaczego warto go używać? Jak mogę tego używać?
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.
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.
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:
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 ...
syntetyczne klasy / metody / pola:
Te rzeczy są ważne dla maszyny wirtualnej. Spójrz na następujący fragment kodu:
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() {
}
}
}
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.
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ó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:
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
Wynik:
true
true
Chociaż nie jest to wyraźnie wymienione, wynika to z 15.27.4. Ocena wyrażeń lambda w czasie rzeczywistym :
Wartość wyrażenia lambda jest odwołaniem do wystąpienia klasy o następujących właściwościach: [...]
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.
Jeśli dobrze rozumiem, klasa syntetyczna to klasa generowana w locie, bez konieczności nadawania jej wyraźnej nazwy. Na przykład:
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
Spowoduje to utworzenie syntetycznej podklasy Thread i nadpisanie jej metody run (), a następnie utworzenie jej wystąpienia i uruchomienie.
Outer$1.class
.
Co to jest klasa syntetyczna w Javie?
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ętrzna
synthetic
klasa i jest to anonimowa klasa wewnętrzna wewnątrz java.text.DigitListDigitList$1.java
ale jest to plik wewnętrzny wDigitList.java
Dlaczego warto go używać?
Jest to mechanizm wewnątrz logiki kompilatora Java do generowania .class
pliku
Jak mogę tego używać?
Nie, 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.
synthetic
zajęciasynthetic
wyjść z klas w JDKKonstrukcje 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.
Klasa syntetyczna nie pojawia się w twoim kodzie: jest tworzona przez kompilator. Np. Metoda pomostowa utworzona przez kompilator w Javie jest zazwyczaj syntetyczna.
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");
}
}
Za pomocą polecenia javap -verbose DateInterval
możesz zobaczyć metodę mostu:
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Zostało to stworzone przez kompilator; nie pojawia się w Twoim kodzie.