Jawaban:
Kadang-kadang Java generik hanya tidak membiarkan Anda melakukan apa yang ingin Anda, dan Anda perlu untuk secara efektif memberitahu compiler bahwa apa yang Anda lakukan benar-benar akan menjadi hukum pada waktu eksekusi.
Saya biasanya menemukan ini menyakitkan ketika saya mengejek antarmuka generik, tetapi ada contoh lain juga. Ini biasanya layak mencoba untuk bekerja keluar cara menghindari peringatan daripada menekan itu ( Java Generik FAQ membantu di sini) tapi kadang-kadang bahkan jika ini mungkin, membungkuk kode keluar dari bentuk sehingga menekan peringatan adalah lebih rapi. Selalu tambahkan komentar jelas dalam kasus itu!
FAQ generik yang sama memiliki beberapa bagian pada topik ini, dimulai dengan "Apa itu peringatan" tidak dicentang "?" - Layak dibaca.
(YourClazz<?>)
- Java tidak pernah memperingatkan tentang gips karena aman. Ini tidak akan selalu berhasil (lihat FAQ generik untuk detailnya).
Ini adalah anotasi untuk menekan kompilasi peringatan tentang operasi generik yang tidak diperiksa (bukan pengecualian), seperti gips. Ini pada dasarnya menyiratkan bahwa programmer tidak ingin diberitahu tentang ini yang dia sudah sadari ketika mengkompilasi sedikit kode tertentu.
Anda dapat membaca lebih lanjut tentang anotasi khusus ini di sini:
Selain itu, Oracle menyediakan beberapa dokumentasi tutorial tentang penggunaan anotasi di sini:
Seperti yang mereka katakan,
"Peringatan 'tidak dicentang' dapat terjadi ketika berinteraksi dengan kode lama yang ditulis sebelum munculnya obat generik (dibahas dalam pelajaran berjudul Generics)."
Ini juga bisa berarti bahwa versi sistem tipe Java saat ini tidak cukup baik untuk kasus Anda. Ada beberapa proposisi / peretasan JSR untuk memperbaikinya: Ketik token, Token Super , Class.cast ().
Jika Anda benar-benar membutuhkan penindasan ini, persempit sebanyak mungkin (mis. Jangan menaruhnya di kelas itu sendiri atau ke metode yang panjang). Sebuah contoh:
public List<String> getALegacyListReversed() {
@SuppressWarnings("unchecked") List<String> list =
(List<String>)legacyLibrary.getStringList();
Collections.reverse(list);
return list;
}
The SuppressWarning penjelasan digunakan untuk peringatan compiler menekan untuk elemen dijelaskan. Secara khusus, unchecked
kategori ini memungkinkan penindasan peringatan kompiler yang dihasilkan sebagai hasil dari pemeran tipe yang tidak dicentang.
Secara sederhana: Ini adalah peringatan dimana kompiler menunjukkan bahwa ia tidak dapat memastikan keamanan tipe.
Metode layanan JPA misalnya:
@SuppressWarnings("unchecked")
public List<User> findAllUsers(){
Query query = entitymanager.createQuery("SELECT u FROM User u");
return (List<User>)query.getResultList();
}
Jika saya tidak membuat anotasi @SuppressWarnings ("tidak dicentang") di sini, itu akan memiliki masalah dengan baris, di mana saya ingin mengembalikan Daftar Hasil saya.
Dalam cara pintas ketik-safety berarti: Suatu program dianggap aman-tipe jika ia dikompilasi tanpa kesalahan dan peringatan dan tidak memunculkan ClassCastException yang tidak terduga saat runtime.
Saya membangun di http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html
Di Jawa, obat generik diimplementasikan dengan cara penghapusan tipe. Misalnya, kode berikut.
List<String> hello = List.of("a", "b");
String example = hello.get(0);
Dikompilasi sebagai berikut.
List hello = List.of("a", "b");
String example = (String) hello.get(0);
Dan List.of
didefinisikan sebagai.
static <E> List<E> of(E e1, E e2);
Yang setelah penghapusan tipe menjadi.
static List of(Object e1, Object e2);
Kompiler tidak tahu apa jenis generik saat runtime, jadi jika Anda menulis sesuatu seperti ini.
Object list = List.of("a", "b");
List<Integer> actualList = (List<Integer>) list;
Java Virtual Machine tidak tahu jenis generik apa saat menjalankan suatu program, jadi ini mengkompilasi dan berjalan, seperti untuk Java Virtual Machine, ini adalah pemeran untuk List
mengetik (ini adalah satu-satunya hal yang dapat diverifikasi, sehingga hanya memverifikasi itu).
Tapi sekarang tambahkan baris ini.
Integer hello = actualList.get(0);
Dan JVM akan melempar yang tidak terduga ClassCastException
, ketika kompiler Java memasukkan pemeran implisit.
java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer
Sebuah unchecked
peringatan memberitahu seorang programmer yang gips dapat menyebabkan program untuk membuang pengecualian di tempat lain. Menekan peringatan dengan @SuppressWarnings("unchecked")
memberi tahu kompiler bahwa programmer percaya kode aman dan tidak akan menyebabkan pengecualian yang tidak terduga.
Mengapa Anda ingin melakukan itu? Sistem tipe Java tidak cukup baik untuk mewakili semua pola penggunaan tipe yang mungkin. Terkadang Anda mungkin tahu bahwa para pemain aman, tetapi Java tidak menyediakan cara untuk mengatakannya - untuk menyembunyikan peringatan seperti ini, @SupressWarnings("unchecked")
dapat digunakan, sehingga seorang programmer dapat fokus pada peringatan yang sebenarnya. Misalnya, Optional.empty()
mengembalikan tunggal untuk menghindari alokasi opsional kosong yang tidak menyimpan nilai.
private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
Pemain ini aman, karena nilai yang disimpan dalam opsional kosong tidak dapat diambil sehingga tidak ada risiko pengecualian pemain kelas yang tidak terduga.
Anda bisa menekan peringatan kompiler dan memberi tahu para generik bahwa kode yang Anda tulis itu legal menurutnya.
Contoh:
@SuppressWarnings("unchecked")
public List<ReservationMealPlan> retreiveMealPlan() {
List<ReservationMealPlan> list=new ArrayList<ReservationMealPlan>();
TestMenuService testMenuService=new TestMenuService(em, this.selectedInstance);
list = testMenuService.getMeal(reservationMealPlan);
return list;
}
Salah satu triknya adalah membuat antarmuka yang memperluas antarmuka basis generik ...
public interface LoadFutures extends Map<UUID, Future<LoadResult>> {}
Kemudian Anda dapat memeriksanya dengan instanceof sebelum ...
Object obj = context.getAttribute(FUTURES);
if (!(obj instanceof LoadFutures)) {
String format = "Servlet context attribute \"%s\" is not of type "
+ "LoadFutures. Its type is %s.";
String msg = String.format(format, FUTURES, obj.getClass());
throw new RuntimeException(msg);
}
return (LoadFutures) obj;
Sejauh yang saya tahu, untuk saat ini ada hubungannya dengan menekan peringatan tentang obat generik; generik adalah konstruk pemrograman baru yang tidak didukung dalam versi JDK lebih awal dari JDK 5, jadi campuran apa pun dari konstruksi lama dengan yang baru dapat menimbulkan beberapa hasil yang tidak terduga.
Compiler memperingatkan programmer tentang hal itu, tetapi jika programmer sudah tahu, mereka dapat mematikan peringatan yang ditakuti menggunakan SuppressWarnings.
Peringatan dimana kompiler menunjukkan bahwa ia tidak dapat memastikan keamanan tipe. Istilah "tidak dicentang" peringatan itu menyesatkan. Itu tidak berarti bahwa peringatan itu tidak dicentang dengan cara apa pun. Istilah "tidak dicentang" mengacu pada fakta bahwa kompiler dan sistem runtime tidak memiliki informasi tipe yang cukup untuk melakukan semua pemeriksaan tipe yang diperlukan untuk memastikan keamanan tipe. Dalam pengertian ini, operasi tertentu "tidak dicentang".
Sumber paling umum dari peringatan "tidak dicentang" adalah penggunaan tipe mentah. peringatan "tidak dicentang" dikeluarkan ketika suatu objek diakses melalui variabel tipe mentah, karena tipe mentah tidak menyediakan informasi tipe yang cukup untuk melakukan semua pemeriksaan tipe yang diperlukan.
Contoh (peringatan tidak dicentang bersama dengan jenis mentah):
TreeSet set = new TreeSet();
set.add("abc"); // unchecked warning
set.remove("abc");
warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.TreeSet
set.add("abc");
^
Ketika metode add dipanggil, kompiler tidak tahu apakah aman untuk menambahkan objek String ke koleksi. Jika TreeSet adalah koleksi yang berisi String s (atau supertype daripadanya), maka itu akan aman. Tetapi dari informasi jenis yang disediakan oleh tipe mentah TreeSet, kompiler tidak dapat memberi tahu. Karenanya panggilan tersebut berpotensi tidak aman dan peringatan "tidak dicentang" dikeluarkan.
peringatan "tidak dicentang" juga dilaporkan ketika kompiler menemukan pemain yang tipe targetnya adalah tipe parameter atau tipe parameter.
Contoh (peringatan yang tidak dicentang bersama dengan gips ke tipe atau variabel tipe parameter):
class Wrapper<T> {
private T wrapped ;
public Wrapper (T arg) {wrapped = arg;}
...
public Wrapper <T> clone() {
Wrapper<T> clon = null;
try {
clon = (Wrapper<T>) super.clone(); // unchecked warning
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
try {
Class<?> clzz = this.wrapped.getClass();
Method meth = clzz.getMethod("clone", new Class[0]);
Object dupl = meth.invoke(this.wrapped, new Object[0]);
clon.wrapped = (T) dupl; // unchecked warning
} catch (Exception e) {}
return clon;
}
}
warning: [unchecked] unchecked cast
found : java.lang.Object
required: Wrapper <T>
clon = ( Wrapper <T>)super.clone();
^
warning: [unchecked] unchecked cast
found : java.lang.Object
required: T
clon. wrapped = (T)dupl;
Pemain yang tipe targetnya adalah tipe parameter (beton atau wildcard) atau parameter tipe tidak aman, jika pemeriksaan tipe dinamis saat runtime terlibat. Saat runtime, hanya tipe erasure yang tersedia, bukan tipe statis persis yang terlihat dalam kode sumber. Akibatnya, bagian runtime dari gips dilakukan berdasarkan pada tipe erasure, bukan pada tipe statis yang tepat.
Dalam contoh tersebut, para pemain ke Wrapper akan memeriksa apakah objek yang kembali dari super.clone adalah Wrapper, bukan apakah itu adalah wrapper dengan tipe anggota tertentu. Demikian pula, gips ke parameter tipe T dilemparkan untuk mengetik Objek saat runtime, dan mungkin dioptimalkan sekaligus. Karena penghapusan tipe, sistem runtime tidak dapat melakukan pemeriksaan tipe yang lebih berguna saat runtime.
Di satu sisi, kode sumber menyesatkan, karena itu menunjukkan bahwa pemain untuk jenis target masing-masing dilakukan, sementara pada kenyataannya bagian dinamis pemain hanya memeriksa terhadap penghapusan jenis jenis target. Peringatan "tidak dicentang" dikeluarkan untuk menarik perhatian programmer ke ketidakcocokan antara aspek statis dan dinamis para pemain.
Silakan merujuk: Apa itu peringatan "tidak dicentang"?
Anotasi @SuppressWarnings adalah salah satu dari tiga anotasi bawaan yang tersedia di JDK dan ditambahkan bersama @Override dan @Deprecated di Java 1.5.
@SuppressWarnings memerintahkan kompiler untuk mengabaikan atau menekan, peringatan kompiler yang ditentukan dalam elemen beranotasi dan semua elemen program di dalam elemen itu. Misalnya, jika kelas diberi penjelasan untuk menekan peringatan tertentu, maka peringatan yang dihasilkan dalam metode di dalam kelas itu juga akan dipisahkan.
Anda mungkin telah melihat @SuppressWarnings ("tidak dicentang") dan @SuppressWarnings ("serial"), dua contoh paling populer dari anotasi @SuppressWarnings. Mantan digunakan untuk menekan peringatan yang dihasilkan karena pengecoran tidak dicentang sementara peringatan kemudian digunakan untuk mengingatkan tentang menambahkan SerialVersionUID dalam kelas Serializable.
Baca selengkapnya: https://javarevisited.blogspot.com/2015/09/what-is-suppresswarnings-annotation-in-java-unchecked-raw-serial.html#ixzz5rqQaOLUa