אפשרויות של javac -Xlint

מהדר שפות התכנות Java (javac) המסופק על ידי אורקל (ובעבר על ידי Sun) כולל כמה אפשרויות לא סטנדרטיות שלעתים קרובות שימושיות. אחת השימושיות ביותר היא מכלול האפשרויות הלא סטנדרטיות המדפיסות אזהרות שנתקלו בהן במהלך ההידור. מכלול האפשרויות הזה הנושא של הודעה זו.

החלק של עמוד javac ברשימות אפשרויות לא סטנדרטיות ומספק פרטים קצרים על כל אחת מהאפשרויות הללו. להלן קטע הקוד הרלוונטי מאותו דף.

רשימת אפשרויות אלה זמינה גם משורת הפקודה (בהנחה שהתקנת Java SDK מותקנת) עם הפקודה: javac -help -X. זה קצר יותר מדוגמת דף האיש / דף האינטרנט המוצג לעיל ומוצג בהמשך.

כפי סיכום המצב הקודם מלרוץ javac -help -Xמציין, התנאים הספציפיים עשר עבורו אזהרות Xlint להתקיים הן (לפי סדר אלפביתי): cast, deprecation, divzero, empty, fallthrough, finally, overrides, path, serial, ו unchecked. אני מסתכל בקצרה על כל אחד מאלה ומספק קטע קוד המוביל לאזהרה זו המופיעה כאשר Xlint מופעל. שים לב שדף האיש של javac ודף ה- javac של Java SE 6 מציגים שניהם רק מחצית מאפשרויות ה- Xlint הללו (התיעוד כנראה אינו עדכני כמו השימוש / העזרה של javac). יש ערך שימושי של NetBeans Wiki המסכם את כל עשר האפשרויות.

מהדר ה- javac מאפשר להפעיל את כל אזהרות ה- Xlint או את אף אחת מהן. אם לא מוגדרת כלל Xlint של האפשרות -Xlint: אף אחד לא צוין במפורש, ההתנהגות היא שלא להציג את רוב האזהרות. מעניין שהפלט אכן מספק אזהרה על הוצאה משימוש ואזהרות לא מסומנות וממליץ להריץ javac עם -Xlint מופעל כדי לראות את הפרטים על שני סוגים אלה של אזהרות.

לפני סיום פוסט זה אדגים קוד ג'אווה המוביל ל -13 אזהרות Xlint המדווחות הכוללות את כל עשר האפשרויות שנדונו לעיל. עם זאת, מבלי שצוין Xlint, הפלט הוא כפי שמוצג בתמונת המסך הבאה.

כפי שמציין התמונה לעיל, בין אם לא מוגדר כלל Xlint ובין אם הוא מוגדר במפורש עם "none", התוצאה היא זהה: רוב האזהרות אינן מוצגות, אך ישנן התייחסויות פשוטות להפסקה ואזהרות לא מסומנות עם המלצות. להריץ javac עם -Xlint: הוצאה משימוש ו- -Xlint: לא מסומן בהתאמה לפרטים נוספים. הפעלת javac עם -Xlint: הכל או -Xlint ללא אפשרויות אחרות יציגו את כל האזהרות ויעבדו לראות את הפרטים לגבי אזהרות שהופעלו, לא מסומנות, וכל שאר האזהרות התומכות ב- Xlint. זה יוצג לאחר שעבר על קוד המקור וכל אזהרת Xlint בנפרד.

-בלאנט: שחקנים

ניתן להשתמש באפשרות זו כדי שהמהדר יזהיר את המפתח כי מתבצע צוות מיותר. הנה קטע קוד שיסומן אם -Xlint, -Xlint: all או -Xlint: cast סופקו ל- javac בעת הידור המקור.

/** * 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()); } } 

בקוד שלעיל, אין צורך להשליך את האובייקט של האדם בתוך לולאת ה- for לאדם ו- -Xlint: צוות השחקנים יתריע מפני צוות השחקנים המיותר והמיותר הזה עם הודעה המציינת משהו כמו:

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

-קסלינט: הוצאה משימוש

כפי שנדון לעיל, אזהרת הדחה של Xlint נחשבה ככל הנראה חשובה דיה כדי להצדיק את פרסומה גם כאשר Xlint אינו מנוהל במפורש. אזהרה זו מתרחשת כאשר מופעלת שיטה שהוצא משימוש. דוגמת הקוד הבאה מדגימה מקרה כזה.

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

אינך יכול לדעת ללא קוד המקור של מחלקת ה- Person (ש- "fred" הוא מופע לגביו), אך שיטת getName () אינה מוצלחת ב- Person. הפלט הבא מהפעלת javac עם -Xlint, -Xlint: all, או -Xlint: הוצאת דחייה מאשרת את זה (או מציינת אותו אם היזם החמיץ את זה).

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()); ^ 

-קסלינט: divzero

אפשרות ה- divzero Xlint מציינת מתי חלוקה אינטגרלית מתחלקת באפס מילולי. דוגמת קוד שתדגים זאת מוצגת בהמשך:

/** * 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; } 

הפלט מ- javac בעת הידור לעיל מוצג כעת.

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

כשניסיתי בכוח לכפות את האזהרה הזו, נראה שזה עובד רק עבור מחלק אפס מקודד (מילולי). כמו כן, הוא אינו מסמן חלוקה כפולה מכיוון שניתן להחזיר את אינפיניטי כתשובה תקפה במקרה זה מבלי לזרוק חריג.

-קסלינט: ריק

מטרתו -Xlint:emptyהיא להודיע ​​למפתח כי ifבתנאי "ריק" נמצא בקוד. מהבדיקות שלי נראה שזה חל רק על המקרה של גוש "אם" ריק. NetBeans מספק "רמזים" (אותן אזהרות בעלות קו תחתון צהוב המסומנות גם בשוליים הימניים של עורך קוד המקור) למספר סוגים של משפטים ריקים, אך -Xlint:emptyנראה שהם מסמנים רק את הצהרות הריק "אם". שילבתי את האחרים ש- NetBeans מסמנת יחד עם -Xlint:emptyהדגלים האחד במדגם קוד המקור הבא.

/** * 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.");;;; } 

הקוד למעלה מלא במיקום בעייתי של נקודה-פסיק שכמעט בוודאות אינם מה שהמפתח רצה. קוד זה יהיה לקמפל, אבל היזם הזהיר מפני מצבי החשודות האלה אם -Xlint, -Xlint:allאו -Xlint:emptyמשמש עם javac. הודעות האזהרה שמודפסות באוסף המצליח אחרת מוצגות בהמשך.

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

רק סעיף ההצהרה הריק אם מסומן; האחרים לא מדווחים על ידי -Xlint:empty.

-קסלינט: נפילה

נוחות מפתה אך שנויה במחלוקת שג'אווה מספקת היא היכולת "להפיל" ביטויים נפוצים switchבהצהרה להחיל את אותו ההיגיון על מספר ערכים אינטגרליים עם פיסת קוד אחת. אם כל הערכים האינטגרליים עם הפונקציונליות המשותפת ריקים למעט הערך הסופי שמבצע בפועל את הפונקציונליות ומספק a break, -Xlint:fallthroughלא יופעל. עם זאת, אם חלק caseמהביטויים אכן מבצעים הגיון משלהם בנוסף לוגיקת הנפילה הנפוצה, אזהרה זו מופקת. דוגמאות המדגימות זאת מוצגות בהמשך.

/** * 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."); } } 

דוגמת הקוד שלעיל מציגה בכוונה את שני המקרים (משחק מלים המיועד) למתג / מקרה שיוביל ולא יוביל להודעת אזהרה בזכות -Xlint:fallthrough. הפלט, עם אזהרה אחת בלבד, מוצג בהמשך.

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

caseכי יש סימנת היה האדום caseבעקבות GREEN caseכי עשתה קצת היגיון משלה לפני הנפילה דרך היגיון RED.

-קסלינט: סוף סוף

יותר מאדם אחד הזהיר: "אל תחזור בסעיף סופי." למעשה, "החזרת ג'אווה לא תמיד" נמצאת בהיכל הבושה של ג'אווה. מפתח Java ניתן הזהיר לגבי המצב הנפשע הזה באמצעות -Xlint, -Xlint:all, או -Xlint:finally. פיסת קוד מקור המדגימה כיצד ניתן ליצור אזהרה זו מוצגת בהמשך.

/** * 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; } } 

האמור לעיל לקוי וככל הנראה לא כוונתו של היזם. Javac האזהרה הרלוונטי מספק כאשר Xlint מופעל מוצג הבא.

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

-קסלינט: עוקף