javac의 -Xlint 옵션

Oracle (이전에는 Sun)이 제공하는 Java 프로그래밍 언어 컴파일러 (javac)에는 종종 유용한 여러 비표준 옵션이 있습니다. 가장 유용한 것 중 하나는 컴파일 중에 발생한 경고를 출력하는 비표준 옵션 세트입니다. 이 옵션 세트가이 게시물의 주제입니다.

비표준 옵션에 대한 javac 페이지 섹션에서는 이러한 각 옵션에 대한 간략한 세부 정보를 나열하고 제공합니다. 다음은 해당 페이지의 관련 스 니펫입니다.

이러한 옵션 목록은 javac -help -X 명령을 사용하여 명령 줄 (Java SDK가 설치된 경우)에서도 사용할 수 있습니다. 이것은 위에 표시된 매뉴얼 페이지 / 웹 페이지 예제보다 간단하며 다음에 표시됩니다.

실행에서 이전 스냅 샷으로 javac -help -X나타냅니다 Xlint 경고가 존재하는 열 특정 조건 (알파벳 순서)이다 : cast, deprecation, divzero, empty, fallthrough, finally, overrides, path, serial,와 unchecked. 나는 이들 각각을 간략히 살펴보고 Xlint가 켜져있을 때 이러한 경고가 발생하는 코드를 제공합니다. javac의 man 페이지와 Java SE 6 javac 페이지는 모두 이러한 Xlint 옵션의 절반 만 나열합니다 (문서는 javac 사용 / 도움말만큼 최신 상태가 아닙니다). 10 가지 옵션을 모두 요약 한 유용한 NetBeans Wiki 항목이 있습니다.

javac 컴파일러는 Xlint 경고를 모두 활성화하거나 활성화하지 않습니다. -Xlint : none 옵션이 명시 적으로 지정되어있는 경우 Xlint가 전혀 지정되지 않으면 대부분의 경고가 표시되지 않습니다. 흥미롭게도 출력은 지원 중단 및 확인되지 않은 경고에 대한 경고를 제공하며 이러한 두 가지 유형의 경고에 대한 세부 정보를 보려면 -Xlint를 활성화 한 상태에서 javac를 실행하도록 권장합니다.

이 게시물이 끝나기 전에 위에서 논의한 10 가지 옵션을 모두 포함하는 총 13 개의 Xlint 경고를보고하는 Java 코드를 보여 드리겠습니다. 그러나 Xlint를 지정하지 않으면 출력은 다음 화면 스냅 샷과 같습니다.

위의 이미지에서 알 수 있듯이 Xlint가 전혀 지정되지 않았거나 "none"으로 명시 적으로 지정되었는지 여부에 관계없이 결과는 동일합니다. 대부분의 경고는 표시되지 않지만 사용 중단에 대한 간단한 참조와 권장 사항이있는 확인되지 않은 경고가 있습니다. 추가 세부 사항을 위해 각각 -Xlint : deprecation 및 -Xlint : unchecked로 javac를 실행하십시오. -Xlint : all 또는 -Xlint와 함께 javac를 다른 옵션없이 실행하면 모든 경고가 표시되고 사용되지 않음, 선택 취소 및 기타 모든 적용 가능한 Xlint 사용 경고에 대한 세부 정보를 볼 수 있습니다. 이것은 소스 코드와 각 Xlint 경고를 개별적으로 살펴본 후에 표시됩니다.

-Xlint : 캐스트

이 옵션을 사용하면 컴파일러가 중복 캐스트가 만들어지고 있음을 개발자에게 경고하도록 할 수 있습니다. 다음은 소스를 컴파일 할 때 javac에 -Xlint, -Xlint : all 또는 -Xlint : cast가 제공된 경우 플래그가 지정되는 코드 스 니펫입니다.

/** * 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 옵션은 적분 나누기가 리터럴 0으로 나눌 때를 나타냅니다. 이를 보여주는 코드 예제는 다음과 같습니다.

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

의도적으로이 경고를 강제하려고했을 때 하드 코딩 된 (문자 그대로) 0 제수에서만 작동하는 것처럼 보였습니다. 또한 예외를 발생시키지 않고 Infinity가 유효한 답변으로 반환 될 수 있기 때문에 이중 나눗셈 플래그를 지정하지 않습니다.

-Xlint : 비어 있음

의 목적은 -Xlint:empty개발자에게 "빈" if조건이 코드에 있음을 알리는 것입니다 . 내 테스트에서 이것은 빈 "if"블록의 경우에만 적용되는 것 같습니다. NetBeans는 여러 유형의 빈 문에 대해 "힌트"(소스 코드 편집기의 오른쪽 여백에도 표시되는 노란색 밑줄이있는 경고)를 제공하지만 -Xlint:empty빈 "if"문에만 플래그를 지정하는 것처럼 보입니다. 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:emptyjavac의 사용됩니다. 그렇지 않으면 성공적인 컴파일에서 인쇄되는 경고 메시지가 다음에 표시됩니다.

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

빈 "if"문 절만 플래그가 지정됩니다. 나머지는에서보고하지 않습니다 -Xlint:empty.

-Xlint : fallthrough

Java가 제공하는 유혹적이지만 논란의 여지가있는 편의는 switch하나의 코드로 여러 정수 값에 동일한 논리를 적용하기 위해 명령문 에서 공통 표현식을 "대체"할 수있는 기능 입니다. 공유 기능을 적분 모든 값이 실제로 기능을 수행하고 제공 마지막 하나를 제외하고 비어있는 경우 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플래그있어 그것은 RED했다 case초록색 다음 case적색 로직을 통해 떨어지는 전에 자신의 몇 가지 논리를했다.

-Xlint : 드디어

한 명 이상이 "finally 절에 반환하지 마십시오."라고 경고했습니다. 사실, "Java의 반환이 항상 그런 것은 아닙니다"는 The Java Hall of Shame에 있습니다. 자바 개발자는 사용하여이 사악 상황에 대해 경고 할 수있다 -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 : 재정의