Apa itu kelas sintetis di Jawa? Mengapa harus digunakan? Bagaimana saya bisa menggunakannya?
Apa itu kelas sintetis di Jawa? Mengapa harus digunakan? Bagaimana saya bisa menggunakannya?
Jawaban:
Sebagai contoh, Ketika Anda memiliki pernyataan switch, java membuat variabel yang dimulai dengan $. Jika Anda ingin melihat contoh ini, mengintip ke refleksi java dari kelas yang memiliki pernyataan switch di dalamnya. Anda akan melihat variabel-variabel ini ketika Anda memiliki setidaknya satu pernyataan switch di mana saja di kelas.
Untuk menjawab pertanyaan Anda, saya tidak percaya Anda dapat mengakses (selain refleksi) kelas sintetis.
Jika Anda menganalisis kelas yang tidak Anda ketahui (melalui refleksi) dan perlu mengetahui hal-hal yang sangat spesifik dan tingkat rendah tentang kelas itu, Anda mungkin berakhir menggunakan metode refleksi Java yang ada hubungannya dengan kelas sintetis. Satu-satunya "penggunaan" di sini adalah mendapatkan informasi lebih lanjut tentang kelas untuk menggunakannya secara tepat dalam kode Anda.
(Jika Anda melakukan ini, Anda mungkin sedang membangun semacam kerangka yang bisa digunakan pengembang lain.)
Kalau tidak, jika Anda tidak menggunakan refleksi, tidak ada kegunaan praktis dari kelas sintetis yang saya tahu.
Java memiliki kemampuan untuk membuat kelas saat runtime. Kelas-kelas ini dikenal sebagai Kelas Sintetis atau Proxy Dinamis.
Lihat http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html untuk informasi lebih lanjut.
Pustaka sumber terbuka lainnya, seperti CGLIB dan ASM juga memungkinkan Anda untuk menghasilkan kelas sintetis, dan lebih kuat daripada perpustakaan yang disediakan dengan JRE.
Kelas sintetis digunakan oleh pustaka AOP (Aspect Oriented Programming) seperti Spring AOP dan AspectJ, serta pustaka ORM seperti Hibernate.
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
mengatakan: Mengembalikan nilai true jika anggota ini diperkenalkan oleh kompiler; mengembalikan false jika tidak.
java.lang.reflect.Member#isSynthetic
tidak relevan dengan pertanyaan awal. Anggota adalah bidang, konstruktor dan metode. Pertanyaan aslinya adalah tentang kelas sintetis , bukan anggota sintetis. Di Jawa 8, ekspresi lambda memunculkan kelas sintetis - Saya tidak yakin keadaan apa yang bisa muncul.
Yah saya menemukan jawaban untuk pertanyaan pertama di google:
Kelas dapat ditandai sebagai sintetis jika dihasilkan oleh kompiler, yaitu, itu tidak muncul dalam kode sumber.
Ini hanya definisi dasar tapi saya menemukannya di utas forum dan tidak ada penjelasan. Masih mencari yang lebih baik ...
kelas / metode / bidang sintetis:
Hal-hal ini penting untuk VM. Lihat cuplikan kode berikut:
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() {
}
}
}
Menurut diskusi ini , meskipun spesifikasi bahasa menggambarkan proprty "isSynthetic" untuk kelas, ini cukup diabaikan oleh implementasi dan tidak digunakan untuk proxy dinamis atau kelas anonim. Bidang sintetik dan konstruktor digunakan untuk mengimplementasikan kelas bertingkat (tidak ada konsep kelas bertingkat dalam kode byte, hanya dalam kode sumber).
Saya pikir konsep kelas sintetis terbukti tidak berguna, yaitu tidak ada yang peduli apakah kelas sintetis. Dengan bidang dan metode, ini mungkin digunakan tepat di satu tempat: untuk menentukan apa yang akan ditampilkan dalam tampilan struktur kelas IDE - Anda ingin metode dan bidang normal muncul di sana, tetapi bukan yang sintetis yang digunakan untuk mensimulasikan kelas bersarang. OTOH, Anda TIDAK ingin kelas anonim muncul di sana.
Mereka dibuat oleh JVM pada saat run time ketika mereka memanggil anggota pribadi kelas dalam untuk tujuan debugging
Metode, bidang, kelas yang dibuat oleh JVM selama waktu berjalan untuk tujuan pelaksanaannya disebut Sintetis
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
Juga Kelas Sintetis atau Proxy Dinamis digunakan oleh EasyMock untuk membuat implementasi antarmuka atau kelas abstrak saat runtime.
Ketika kompiler Java mengkompilasi konstruksi tertentu, seperti kelas dalam, itu membuat konstruksi sintetis ; ini adalah kelas, metode, bidang, dan konstruk lain yang tidak memiliki konstruk yang sesuai dalam kode sumber.
Penggunaan:
Konstruksi sintetik memungkinkan kompiler Java untuk mengimplementasikan fitur-fitur bahasa Java baru tanpa perubahan pada JVM. Namun, konstruksi sintetik dapat bervariasi di antara implementasi Java compiler yang berbeda, yang berarti bahwa file .class dapat bervariasi di antara implementasi yang berbeda juga.
referensi: docs.oracle.com
Seperti yang telah ditunjukkan oleh berbagai jawaban, kompiler diperbolehkan untuk menghasilkan berbagai konstruk (termasuk kelas) yang tidak secara langsung berhubungan dengan sesuatu dalam kode sumber. Ini harus ditandai sebagai sintetis:
Representasi biner untuk kelas atau antarmuka juga harus mengandung semua hal berikut:
[...]
11. Sebuah konstruk yang dipancarkan oleh kompiler Java harus ditandai sebagai sintetis jika tidak sesuai dengan konstruk yang dinyatakan secara eksplisit atau implisit dalam kode sumber. , kecuali konstruk yang dipancarkan adalah metode inisialisasi kelas (JVMS §2.9).
[...]
Seperti yang ditunjukkan oleh @ Holger dalam komentar untuk pertanyaan lain, contoh yang relevan untuk konstruksi tersebut adalah objek Kelas yang mewakili referensi metode dan lambda:
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
Keluaran:
true
true
Meskipun ini tidak disebutkan secara eksplisit, ini mengikuti dari 15.27.4. Evaluasi Run-Time dari Ekspresi Lambda :
Nilai ekspresi lambda adalah referensi ke instance kelas dengan properti berikut: [...]
dan kata-kata yang hampir identik untuk referensi metode ( 15.13.3. Evaluasi Run-Time dari Metode Referensi ).
Karena kelas ini tidak disebutkan secara eksplisit di mana pun dalam kode sumber, itu harus sintetis.
Jika saya melakukannya dengan benar, kelas sintetis dihasilkan dengan cepat, tanpa harus memberikannya nama eksplisit. Sebagai contoh:
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
Ini membuat subclass sintetis dari Thread dan menimpa metode run (), lalu instantiate dan mulai.
Outer$1.class
.
Kelas sintetis tidak muncul di kode Anda: itu dibuat oleh kompiler. Misalnya, metode jembatan yang dibuat oleh kompiler di java biasanya sintetis.
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");
}
}
Menggunakan perintah javap -verbose DateInterval
, Anda dapat melihat metode jembatan:
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Ini dibuat oleh kompiler; itu tidak muncul dalam kode Anda.
Apa itu kelas sintetis di Jawa?
Sebuah synthetic
kelas adalah .class
file yang dihasilkan oleh Java Compiler dan itu tidak ada dalam kode sumber.
Contoh penggunaan synthetic
kelas: Kelas batin anonim
synthetic
kelas dan itu adalah kelas batin anonim di dalam java.text.DigitListDigitList$1.java
tetapi itu adalah file dalamDigitList.java
Mengapa harus digunakan?
Ini adalah mekanisme di dalam logika kompiler Java untuk menghasilkan .class
file
Bagaimana saya bisa menggunakannya?
Tidak, pengembang TIDAK menggunakannya secara langsung.
Java compiler digunakan synthetic
untuk menghasilkan .class
file, dan kemudian JVM membaca .class
file tersebut untuk menjalankan logika program.
Konstruk sintetik adalah kelas, metode, bidang dll yang tidak memiliki konstruk yang sesuai dalam kode sumber. Konstruksi sintetik memungkinkan kompiler Java untuk mengimplementasikan fitur-fitur bahasa Java baru tanpa perubahan pada JVM. Namun, konstruksi sintetik dapat bervariasi di antara implementasi Java compiler yang berbeda, yang berarti bahwa file .class dapat bervariasi di antara implementasi yang berbeda juga.