Opsi -Xlint javac

Kompilator bahasa pemrograman Java (javac) yang disediakan oleh Oracle (dan sebelumnya oleh Sun) memiliki beberapa opsi non-standar yang sering kali berguna. Salah satu yang paling berguna adalah serangkaian opsi non-standar yang mencetak peringatan yang ditemukan selama kompilasi. Kumpulan opsi itu adalah subjek posting ini.

Bagian halaman javac pada daftar opsi non-standar dan memberikan detail singkat tentang setiap opsi ini. Berikut adalah cuplikan yang relevan dari halaman itu.

Daftar opsi ini juga tersedia dari baris perintah (dengan asumsi Java SDK diinstal) dengan perintah: javac -help -X. Ini lebih singkat dari contoh halaman manual / halaman web yang ditunjukkan di atas dan ditampilkan berikutnya.

Sebagai snapshot sebelumnya dari berjalan javac -help -Xmenunjukkan, kondisi spesifik sepuluh yang peringatan Xlint ada adalah (dalam urutan abjad): cast, deprecation, divzero, empty, fallthrough, finally, overrides, path, serial, dan unchecked. Saya melihat secara singkat masing-masing ini dan memberikan cuplikan kode yang mengarah ke peringatan ini terjadi saat Xlint dihidupkan. Perhatikan bahwa halaman manual untuk javac dan halaman javac Java SE 6 keduanya hanya mencantumkan setengah dari opsi Xlint ini (dokumentasi tampaknya tidak mutakhir seperti penggunaan / bantuan javac). Ada entri Wiki NetBeans berguna yang merangkum kesepuluh opsi.

Compiler javac memungkinkan semua atau tidak satu pun peringatan Xlint diaktifkan. Jika Xlint tidak ditentukan sama sekali dari opsi -Xlint: tidak ada yang ditentukan secara eksplisit, perilakunya adalah tidak menampilkan sebagian besar peringatan. Menariknya, keluarannya memberikan peringatan tentang penghentian dan peringatan yang tidak dicentang dan merekomendasikan untuk menjalankan javac dengan -Xlint diaktifkan untuk melihat detail tentang kedua jenis peringatan ini.

Sebelum akhir posting ini, saya akan mendemonstrasikan kode Java yang mengarah ke 13 total peringatan Xlint yang dilaporkan mencakup kesepuluh opsi yang dibahas di atas. Namun, tanpa Xlint yang ditentukan, hasilnya akan seperti yang ditampilkan di snapshot layar berikutnya.

Seperti yang ditunjukkan gambar di atas, apakah Xlint tidak ditentukan sama sekali atau ditentukan secara eksplisit dengan "tidak ada", hasilnya akan sama: sebagian besar peringatan tidak ditampilkan, tetapi ada referensi sederhana ke penghentian dan peringatan yang tidak dicentang dengan rekomendasi untuk menjalankan javac dengan -Xlint: deprecation dan -Xlint: masing-masing tidak dicentang untuk detail tambahan. Menjalankan javac dengan -Xlint: all atau -Xlint tanpa opsi lain akan menampilkan semua peringatan dan akan bekerja untuk melihat detail terkait peringatan yang tidak berlaku lagi, tidak dicentang, dan semua peringatan yang mendukung Xlint yang berlaku. Ini akan ditampilkan setelah melalui kode sumber dan setiap peringatan Xlint satu per satu.

-Xlint: cast

Opsi ini dapat digunakan untuk meminta kompilator memperingatkan pengembang bahwa cast yang berlebihan sedang dibuat. Berikut ini cuplikan kode yang akan ditandai jika -Xlint, -Xlint: all, atau -Xlint: cast diberikan ke javac saat mengompilasi sumber.

/** * Demonstrates -Xlint:cast warning of a redundant cast. */ private static void demonstrateCastWarning() { final Set people = new HashSet(); people.add(fred); people.add(wilma); people.add(barney); for (final Person person : people) { // Redundant cast because generic type explicitly is Person out.println("Person: " + ((Person) person).getFullName()); } } 

Dalam kode di atas, tidak perlu mentransmisikan objek person di dalam loop for ke Person dan -Xlint: cast akan memperingatkan cast yang tidak perlu dan berlebihan ini dengan pesan yang menyatakan sesuatu seperti:

src\dustin\examples\Main.java:37: warning: [cast] redundant cast to dustin.examples.Person out.println("Person: " + ((Person) person).getFullName()); ^ 

-Xlint: penghentian

Seperti dibahas di atas, peringatan penghentian Xlint terbukti cukup penting untuk membenarkannya diiklankan bahkan ketika Xlint tidak dijalankan secara eksplisit. Peringatan ini terjadi ketika metode yang tidak digunakan lagi dipanggil. Contoh kode berikut menunjukkan kasus seperti itu.

/** * Cause -Xlint:deprecation to print warning about use of deprecated method. */ private static void demonstrateDeprecationWarning() { out.println("Fred's full name is " + fred.getName()); } 

Anda tidak dapat membedakan tanpa kode sumber untuk kelas Person (di mana "fred" adalah sebuah instance), tetapi metode getName () itu tidak digunakan lagi di Person. Output berikut dari menjalankan javac dengan -Xlint, -Xlint: all, atau -Xlint: deprecation mengonfirmasi hal itu (atau menunjukkannya jika developer melewatkannya).

src\dustin\examples\Main.java:47: warning: [deprecation] getName() in dustin.examples.Person has been deprecated out.println("Fred's full name is " + fred.getName()); ^ 

-Xlint: divzero

Opsi divzero Xlint menunjukkan kapan pembagian integral dibagi dengan nol literal. Contoh kode yang akan menunjukkan ini ditampilkan berikut:

/** * Demonstrate -Xlint:divzero in action by dividing an int by a literal zero. */ private static void demonstrateDivideByZeroWarning() { out.println("Two divided by zero is " + divideIntegerByZeroForLongQuotient(2)); } /** * Divide the provided divisor into the provided dividend and return the * resulting quotient. No checks are made to ensure that divisor is not zero. * * @param dividend Integer to be divided. * @return Quotient of division of dividend by literal zero. */ private static long divideIntegerByZeroForLongQuotient(final int dividend) { // Hard-coded divisor of zero will lead to warning. Had the divisor been // passed in as a parameter with a zero value, this would not lead to // that warning. return dividend / 0; } 

Output dari javac saat di atas dikompilasi sekarang ditampilkan.

src\dustin\examples\Main.java:231: warning: [divzero] division by zero return dividend / 0; ^ 

Ketika saya dengan sengaja mencoba memaksakan peringatan ini, sepertinya itu hanya berfungsi untuk pembagi nol (literal) tanpa kode. Juga, itu tidak menandai divisi ganda karena Infinity dapat dikembalikan sebagai jawaban yang valid dalam kasus itu tanpa mengeluarkan pengecualian.

-Xlint: kosong

Tujuan dari -Xlint:emptyadalah untuk memberi tahu pengembang bahwa ada ifpersyaratan "kosong" dalam kode. Dari pengujian saya, ini tampaknya hanya berlaku untuk kasus blok "jika" kosong. NetBeans menyediakan "petunjuk" (peringatan bergaris bawah kuning yang juga ditandai di margin kanan editor kode sumber) untuk beberapa jenis pernyataan kosong, tetapi -Xlint:emptytampaknya hanya menandai pernyataan "jika" kosong. Saya menyertakan yang lain yang ditandai NetBeans bersama dengan satu -Xlint:emptybendera di contoh kode sumber berikutnya.

/** * This method demonstrates how javac's -Xlint:empty works. Note that javac's * -Xlint:empty will only flag the empty statement involved in the "if" block, * but does not flag the empty statements associated with the do-while loop, * the while loop, the for loop, or the if-else. NetBeans does flag these if * the appropriate "Hints" are turned on. */ private static void demonstrateEmptyWarning() { int[] integers = {1, 2, 3, 4, 5}; if (integers.length != 5); out.println("Not five?"); if (integers.length == 5) out.println("Five!"); else; out.println("Not Five!"); do; while (integers.length > 0); for (int integer : integers); out.println("Another integer found!"); int counter = 0; while (counter < 5); out.println("Extra semicolons.");;;; } 

Kode di atas diisi dengan penempatan titik koma bermasalah yang hampir pasti bukan yang diinginkan pengembang. Kode ini akan mengkompilasi, tetapi pengembang memperingatkan situasi ini curiga jika -Xlint, -Xlint:allatau -Xlint:emptydigunakan dengan javac. Pesan peringatan yang dicetak dalam kompilasi yang jika tidak berhasil akan ditampilkan berikutnya.

src\dustin\examples\Main.java:197: warning: [empty] empty statement after if if (integers.length != 5); ^ 

Hanya klausa pernyataan "jika" kosong yang ditandai; yang lainnya tidak dilaporkan oleh -Xlint:empty.

-Xlint: fallthrough

Kenyamanan yang menggoda tetapi kontroversial yang diberikan Java adalah kemampuan untuk "melakukan kesalahan" pada ekspresi umum dalam sebuah switchpernyataan untuk menerapkan logika yang sama ke beberapa nilai integral dengan satu bagian kode. Jika semua nilai integral dengan fungsionalitas bersama kosong kecuali yang terakhir yang benar-benar menjalankan fungsionalitas dan menyediakan break, maka -Xlint:fallthroughtidak akan diaktifkan. Namun, jika beberapa caseekspresi menjalankan logikanya sendiri selain logika fallthrough yang umum, peringatan ini akan dibuat. Contoh yang mendemonstrasikan hal ini ditunjukkan selanjutnya.

/** * Cause -Xlint:fallthrough to print warning about use of switch/case * fallthrough. */ private static void demonstrateFallthroughWarning() { out.print("Wilma's favorite color is "); out.print(wilma.getFavoriteColor() + ", which is "); // check to see if 'artistic' primary color // NOTE: This one will not lead to -Xlint:fallthrough flagging a warning // because no functionality is included in any of the case statements // that don't have their own break. switch (wilma.getFavoriteColor()) { case BLUE: case YELLOW: case RED: out.print("a primary color for artistic endeavors"); break; case BLACK: case BROWN: case CORAL: case EGGSHELL: case GREEN: case MAUVE: case ORANGE: case PINK: case PURPLE: case TAN: case WHITE: default: out.print("NOT a primary artistic color"); } out.print(" and is "); // check to see if 'additive' primary color // NOTE: This switch WILL lead to -Xlint:fallthrough emitting a warning // because there is some functionality being performed in a case // expression that does not have its own break statement. switch (wilma.getFavoriteColor()) { case BLUE: case GREEN: out.println("(it's not easy being green!) "); case RED: out.println("a primary color for additive endeavors."); break; case BLACK: case BROWN: case CORAL: case EGGSHELL: case MAUVE: case ORANGE: case PINK: case PURPLE: case TAN: case YELLOW: case WHITE: default: out.println("NOT a primary additive color."); } } 

Contoh kode di atas dengan sengaja menunjukkan kedua kasus (permainan kata-kata) dari sakelar / kasing yang akan dan tidak akan mengarah ke pesan peringatan berkat -Xlint:fallthrough. Outputnya, dengan hanya satu peringatan, akan ditampilkan berikutnya.

src\dustin\examples\Main.java:95: warning: [fallthrough] possible fall-through into case case RED: ^ 

Yang caseditandai adalah MERAH casemengikuti HIJAU caseyang melakukan beberapa logika sendiri sebelum jatuh ke logika MERAH.

-Xlint: akhirnya

Lebih dari satu orang telah memperingatkan, "Jangan kembali pada klausa akhirnya." Faktanya, "Java kembali tidak selalu" ada di The Java Hall of Shame. Seorang pengembang Java dapat memperingatkan tentang situasi jahat ini dengan menggunakan -Xlint, -Xlint:allatau -Xlint:finally. Sepotong kode sumber yang mendemonstrasikan bagaimana peringatan ini dapat dibuat akan ditampilkan selanjutnya.

/** * Demonstrate -Xlint:finally generating warning message when a {@code finally} * block cannot end normally. */ private static void demonstrateFinallyWarning() { try { final double quotient = divideIntegersForDoubleQuotient(10, 0); out.println("The quotient is " + quotient); } catch (RuntimeException uncheckedException) { out.println("Caught the exception: " + uncheckedException.toString()); } } /** * Divide the provided divisor into the provided dividend and return the * resulting quotient. No checks are made to ensure that divisor is not zero. * * @param dividend Integer to be divided. * @param divisor Integer by which dividend will be divided. * @return Quotient of division of dividend by divisor. */ private static double divideIntegersForDoubleQuotient(final int dividend, final int divisor) { double quotient = 0.0; try { if (divisor == 0) { throw new ArithmeticException( "Division by zero not allowed: cannot perform " + dividend + "/" + divisor); } // This would not have led to Xlint:divzero warning if we got here // with a literal zero divisor because Infinity would have simply been // returned rather than implicit throwing of ArithmeticException. quotient = (double) dividend / divisor; } finally { return quotient; } } 

Hal di atas memiliki kekurangan dan kemungkinan besar bukan yang diinginkan oleh pengembang. Peringatan relevan yang diberikan javac saat Xlint diaktifkan ditampilkan berikutnya.

src\dustin\examples\Main.java:159: warning: [finally] finally clause cannot complete normally } ^ 

-Xlint: menimpa