javacの-Xlintオプション

Oracle(および以前はSun)が提供するJavaプログラミング言語コンパイラ(javac)には、多くの場合役立つ非標準のオプションがいくつかあります。最も便利なものの1つは、コンパイル中に発生した警告を出力する非標準オプションのセットです。そのオプションのセットは、この投稿の主題です。

非標準オプションのjavacページのセクションには、これらの各オプションの簡単な詳細がリストされています。以下は、そのページの関連するスニペットです。

これらのオプションのリストは、コマンドライン(Java SDKがインストールされている場合)からjavac -help-Xコマンドを使用して入手することもできます。これは、上記のマニュアルページ/ Webページの例よりも簡単で、次に示されています。

実行した以前のスナップショットとしてjavac -help -X、Xlint警告は、(アルファベット順で)されている存在するため10の特定の条件を示している:castdeprecationdivzeroemptyfallthroughfinallyoverridespathserial、およびunchecked。これらのそれぞれを簡単に見て、Xlintがオンになっているときにこれらの警告が発生する原因となるコードスニペットを提供します。 javacのmanページとJavaSE 6 javacページはどちらも、これらのXlintオプションの半分しかリストしていないことに注意してください(ドキュメントは、javacの使用法/ヘルプほど最新ではないようです)。 10個のオプションすべてを要約した便利なNetBeansWikiエントリがあります。

javacコンパイラでは、Xlint警告をすべて有効にするか、まったく有効にしないでください。Xlintがすべてのオプション-Xlint:noneで明示的に指定されていない場合、動作はほとんどの警告を表示しません。興味深いことに、出力には非推奨と未チェックの警告に関する警告が表示され、-Xlintを有効にしてjavacを実行して、これら2種類の警告の詳細を確認することをお勧めします。

この投稿が終わる前に、上記の10個のオプションすべてをカバーする合計13個のXlint警告が報告されるJavaコードを示します。ただし、Xlintを指定しない場合、出力は次の画面のスナップショットに示すようになります。

上の画像が示すように、Xlintがまったく指定されていないか、「none」で明示的に指定されているかにかかわらず、結果は同じです。警告の大部分は表示されませんが、非推奨と推奨事項を含む未チェックの警告への簡単な参照があります詳細については、それぞれ-Xlint:deprecationおよび-Xlint:uncheckedを指定してjavacを実行します。-Xlint:allまたは-Xlintを指定してjavacを実行すると、すべての警告が表示され、非推奨、チェックされていない、およびその他すべての該当するXlint対応の警告に関する詳細が表示されます。これは、ソースコードと各Xlint警告を個別に確認した後に表示されます。

-Xlint:cast

このオプションを使用して、冗長キャストが行われていることをコンパイラーに警告させることができます。これは、ソースのコンパイル時に-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ループ内のpersonオブジェクトをPersonにキャストする必要はありません。-Xlint:castは、次のようなメッセージでこの不要で冗長なキャストを警告します。

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

-Xlint:非推奨

上で説明したように、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では非推奨です。-Xlint、-Xlint:all、または-Xlint:deprecationを指定してjavacを実行した場合の次の出力は、それを確認します(または、開発者が見逃した場合は指摘します)。

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

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

私が意図的にこの警告を強制しようとしたとき、それはハードコードされた(リテラルの)ゼロ因子に対してのみ機能するようでした。また、その場合、例外をスローせずにInfinityを有効な回答として返すことができるため、二重除算のフラグは立てられません。

-Xlint:empty

の目的は-Xlint:empty、「空の」if条件がコードに含まれていることを開発者に通知することです。私のテストから、これは空の「if」ブロックの場合にのみ当てはまるようです。 NetBeansは、いくつかのタイプの空のステートメントに「ヒント」(ソースコードエディタの右マージンにもマークされている黄色の下線付きの警告)を提供しますが-Xlint:empty、空の「if」ステートメントにのみフラグを立てるようです。-Xlint:empty次のソースコードサンプルには、NetBeansがフラグを立てる他のフラグと1つのフラグを含めました。

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

上記のコードは、開発者が望んでいたものではないことはほぼ間違いない、問題のあるセミコロンの配置で埋められています。このコードはコンパイルされますが、、、またはがjavacで使用されている場合-Xlint、開発者はこれらの疑わしい状況について警告されます。それ以外の場合は正常にコンパイルされたときに出力される警告メッセージを次に示します。-Xlint:all-Xlint:empty

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

空の「if」ステートメント句のみにフラグが付けられます。その他はによって報告されません-Xlint:empty

-Xlint:フォールスルー

Javaが提供する魅力的ですが物議を醸す便利さは、switchステートメント内の一般的な式を「フォールスルー」して、1つのコードで同じロジックを複数の整数値に適用する機能です。共有機能を備えた積分値の全てが実際の機能を実行し、提供し、最終的なものを除い空である場合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ます。警告が1つしかない出力を次に示します。

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

caseフラグが立てられてしまったことは、REDたcaseGREEN次caseREDロジックに通って落ちる前に、独自のいくつかのロジックをしました。

-Xlint:ついに

複数の人が「finally節で戻らないでください」と警告しています。実際、「Javaの復活は必ずしもそうとは限らない」というのはJava Hall ofShameにあります。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; } } 

上記には欠陥があり、開発者が意図したものではない可能性があります。次に、Xlintが有効になっているときにjavacが提供する関連する警告を示します。

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

-Xlint:オーバーライド