-
FindBugs Bug Descriptions(한글)JAVA 2015. 3. 30. 19:31반응형
가끔씩 뭔말인지 모르겠어서 찾아 보다 일어로 되어 있는 것이 있어 구글신의 도움으로 한글화 했음.
FindBugs Bug Descriptions
this Document lists the Standard BUG patterns Reported by FindBugs version 3.0.1.
Summary
Descriptions
BC : equals 메소드는 인수의 형태를 가정해서는 안된다 (BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS)
equals (Object o)
메서드는o
형식에 대해 어떤 가정도해서는 없습니다.o
가this
와 같은 형태가 아니라면 단순히 false를 반환한다.BIT : 비트 연산 부호를 확인 (BIT_SIGNED_CHECK)
이 방법은
((event.detail & SWT.SELECTED)> 0)
과 같은 식을 비교하고 있습니다. 비트 연산을보다 연산자로 비교하는 것은 의외의 결과 (물론SWT.SELECTED
값에 의한)의 원인이 될 수 있습니다.SWT.SELECTED
가 음수라면, 이것은 버그의 후보입니다.SWT.SELECTED
가 부가 아니더라도 '> 0'대신 '! = 0'을 사용하는 것은 좋은 사례라고 생각합니다.Boris Bokowski
CN : Cloneable를 구현 한 클래스가 clone 메소드를 정의하지 않거나 사용하지 않은 (CN_IDIOM)
이 클래스는
Cloneable
를 구현하고 있습니다 만,clone
메소드를 정의하지 않았거나 사용하지 않습니다.CN : clone 메소드가 super.clone ()를 호출하지 않은 (CN_IDIOM_NO_SUPER_CALL)
이 비 final 클래스는
super.clone ()
를 호출하지clone
메소드를 정의하고 있습니다. 클래스 A 가 서브 클래스 B 에 의해 확장되어 서브 클래스 B 가super.clone ()
를 호출한다면, 클래스 B 의clone
메소드는 유형 A 의 객체를 돌려 줄 가능성이 높습니다. 이것은clone
을위한 범용 규약에 위반합니다.모든
clone
메소드가super.clone ()
를 호출한다면Object.clone ()
가 호출되는 것이 보증되어 항상 올바른 형태의 객체가 반환됩니다.CN : Cloneable를 구현하지 않는 클래스가 clone 메소드를 정의하고있다 (CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE)
이 클래스는
Cloneable
를 구현하고 있지 않는데clone
메소드를 정의하고 있습니다. 이것이 OK (예를 들어, 서브 클론의 구현을 독자적으로 제어하고 싶은 경우입니다) 상황도 있지만 의도 한 것인지 확인하십시오.CNT : 알려진 상수 잡지 값을 찾아 (CNT_ROUGH_CONSTANT_VALUE)
코드의 명확성과 더 나은 정확도를 위해 정의 된 라이브러리 상수를 사용하는 것을 권장합니다.
Co : 추상 클래스는 공변 인 compareTo 메소드를 정의하고있다 (CO_ABSTRACT_SELF)
이 클래스는 공변 인
compareTo
메소드를 정의하고 있습니다.Comparable
인터페이스의compareTo
메서드를 제대로 구현하기 위해서는compareTo
메소드의 파라미터의 형태는java.lang.Object
해야합니다.Co : compareTo () / compare () 잘못 float 또는 double 값을 처리하는 (CO_COMPARETO_INCORRECT_FLOATING)
이 메소드는이 같은 패턴을 사용하여 double 또는 float 값을 비교하고 있습니다 : val1> val2? 1 : val1 <val2? -1 : 0. 이 패턴은 잘못된 정렬 결과와 깨진 컬렉션의 원인이 될지도 모른다 -0.0과 NaN 값에 대한 잘못 작동합니다 (만약 비교 된 값이 키로서 사용되는 경우). 모든 특별한 경우를 정확하게 처리하기 위해 Double.compare 또는 Float.compare 메소드 사용을 고려하십시오.
Co : compareTo () / compare ()는 Integer.MIN_VALUE을 반환 (CO_COMPARETO_RESULTS_MIN_VALUE)
일부 상황에서는이
compareTo
또는compare
메소드는 Integer.MIN_VALUE를 돌려줍니다. 심한 배드 좋습니다.compareTo
메소드의 반환 값에서 중요한 것은 결과의 부호뿐입니다. 그러나 결과의 부호를 해제하는 것을 기대하고compareTo
메소드의 반환 값을 해제 할 수 있습니다. 반환 된 값이 Integer.MIN_VALUE의 경우를 제외하고 있습니다. Integer.MIN_VALUE보다 -1을 반환합니다.Co : 공변 인 compareTo 메소드의 정의 (CO_SELF_NO_OBJECT)
이 클래스는 공변 인
compareTo
메소드를 정의하고 있습니다.Comparable
인터페이스의compareTo
메서드를 제대로 구현하기 위해서는compareTo
메소드의 파라미터의 형태는java.lang.Object
해야합니다.DE : 예외를 버리고 있을지도 모른다 메소드 (DE_MIGHT_DROP)
이 메소드는 예외를 버리고 있을지도 모릅니다. 일반적으로 캐치 한 예외는 어떤 방법으로 처리하거나보고해야합니다 또는 메소드에서 발생해야합니다.
DE : 예외를 무시하고 있을지도 모른다 메소드 (DE_MIGHT_IGNORE)
이 메소드는 예외를 무시하고 있을지도 모릅니다. 일반적으로 예외는 어떤 방법으로 처리하거나보고해야합니다 또는 메소드에서 발생해야합니다.
DMI : 항목 세트의 요소를 추가하는 것은, Entry 객체 재사용을 위해 실패 할지도 모른다 (DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS)
entrySet 메소드는 하나의 Entry 객체를 재사용하고 반복 중에 반환되는 기저 Map의 뷰를 돌려주는 것이 허가되어 있습니다. Java 1.6의 시점에서 IdentityHashMap와 EnumMap 모두 그렇게했습니다. 그런 Map을 통해 반복 할 때 항목 값은 다음 반복으로 진행까지 유효합니다. 예를 들어, addAll 메소드에 그런 entrySet을 건네 주려고 시도는 심각하게 잘못된 것입니다.
DMI : Random 객체가 만들어 1 번 밖에 사용되지 않는 (DMI_RANDOM_USED_ONLY_ONCE)
이 코드는
java.util.Random
객체를 생성하여 하나의 난수를 생성하는 데 사용하고 버리고 있습니다. 이것은별로 좋지 않은 품질의 난수를 생성하고 비효율적입니다. 있다면Random
객체를 하나만 생성하고 저장하도록 코드를 다시 작성하십시오. 그리고 매번 새로운 난수는 기존Random
객체를 호출하여 가져온 것이 필요합니다.생성 된 난수를 추측 할 수없는 것이 중요한 경우에, 난수마다 새로운
Random
객체를 만들고해서는 안됩니다 (값은 너무 쉽게 추측 가능합니다.) 대신java.security.SecureRandom
의 사용을 적극 검토해야합니다 (그리고 필요한 난수마다 새로운SecureRandom
객체를 만드는 것을 방지합니다).DMI : 컬렉션을 지우려면 removeAll 메소드를 사용하지 않는 (DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION)
컬렉션
c
에서 모든 요소를 제거하고 싶다면,c.removeAll (c)
대신c.clear
을 사용하십시오. 컬렉션을 지우려면c.removeAll (c)
를 호출하는 것은 그다지 명확하지 않고, 오타의 오류에 영향을 쉽고 효율적 아니라 일부의 컬렉션은ConcurrentModificationException
를 throw 할 수도 않습니다.Dm : System.exit (...)를 호출하는 메소드 (DM_EXIT)
System.exit (...)
를 호출하는 것은, Java 가상 머신 전체를 종료시켜 버립니다. 그것이 적절한 경우에만 사용해야합니다.System.exit (...)
호출은 다른 코드 호출을 곤란 또는 불가능합니다. 대신 RuntimeException을 발생하는 것을 고려하십시오.Dm : 데인저러스 메소드 runFinalizersOnExit를 호출하는 메소드 (DM_RUN_FINALIZERS_ON_EXIT)
어떤 이유가 있다고해도 결코
System.runFinalizersOnExit
과Runtime.runFinalizersOnExit
를 호출하지 마십시오. Java 라이브러리에서 가장 위험한 방법의 하나입니다. - Joshua BlochES : String 매개 변수를 ==와! =를 사용하여 비교하고있다 (ES_COMPARING_PARAMETER_STRING_WITH_EQ)
이 코드는 참조 등가성을 위해 ==와! =를 사용하여
java.lang.String
매개 변수를 비교하고 있습니다. 문자열 상수 또는 정의準化된 문자열만을 메서드에 전달할 것을 호출자에게 요구하는 것은 필요 이상으로 취약하고 측정 가능한 성능 향상을 제공하지 않습니다. 대신equals (Object)
메소드를 사용하는 것을 고려하십시오.ES : String 객체를 ==와! =를 사용하여 비교하고있다 (ES_COMPARING_STRINGS_WITH_EQ)
이 코드는 참조 등가성을 위해 ==와! =를 사용하여
java.lang.String
객체를 비교합니다. 두 문자열은 소스 파일의 상수 또는String.intern ()
를 사용하여 긍정적準化되지 않는 한 동일한 문자열은 두 개의 다른 String 객체에 의해 나타내지 될지도 모릅니다. 대신equals (Object)
메소드를 사용하는 것을 고려하십시오.Eq : 추상 클래스는 공변의 equals 메소드를 선언하고있다 (EQ_ABSTRACT_SELF)
이 클래스는 공변의
equals
메소드를 정의하고 있습니다.java.lang.Object
의equals
메소드를 올 Y로 대체하기 위해서는equals
메소드의 파라미터의 형태는java.lang.Object
해야합니다.Eq : equals 메소드는 호환되지 않는 피연산자를 체크하고있다 (EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS)
이
equals
메소드는 인수가 호환되지 않는 유형 (즉 슈퍼 타입도 아니고,equals
메소드를 정의하고있는 클래스의 슈퍼 타입도 서브 타입도 아닌 클래스)인지 확인합니다. 예를 들어,Foo
클래스의equals
메소드는 그렇게 보일지도 모릅니다.public boolean equals (Object o) { if (o instanceof Foo) return name.equals (((Foo) o) .name); else if (o instanceof String) return name.equals (o); else return false; }
이것은 대칭적이고 추이적인
equals
메소드를 실현하는 것은 매우 어렵 기 때문에 나쁜 사례로 간주되고 있습니다. 속성이 없으면 전혀 예상하지 못한 동작이 발생할 수 있습니다.Eq : compareTo (...) 메소드를 정의하고 Object.equals ()를 사용하는 클래스 (EQ_COMPARETO_USE_OBJECT_EQUALS)
이 클래스는
compareTo (...)
메소드를 정의하고 있습니다 만,equals
메서드는java.lang.Object
에서 상속 있습니다. 일반적으로equals
메소드가 true를 돌려주는 경우에만compareTo
메소드는 0을 반환한다.이것이 위반된다면 이상한 예측할 수없는 실패가 PriorityQueue 등의 클래스에서 발생합니다. J2SE 5.0에서는PriorityQueue.remove ()
는compareTo
메소드를 사용하지만 Java SE 6에서는equals
메소드를 사용합니다.Comparable 인터페이스의 compareTo 메소드의 JavaDoc을 아래에 인용합니다.
필수라고하는 것은 아닙니다만,
(x.compareTo (y) == 0) == (x.equals (y))
인 것이 권장됩니다. 일반적으로Comparable
인터페이스를 구현하고있는 클래스에서이 조건에 위반하는 클래스는 명확하게이 사실을 나타낼 필요가 있습니다. 「주 :이 클래스는equals
와 일관성이없는 자연 순서 부를가집니다」등이라고 명시하는 것이 좋습니다.Eq : equals 메소드는 하위 유형에 대한 실패 (EQ_GETCLASS_AND_CLASS_CONSTANT)
이 클래스는 서브 클래스에 의한 상속 돌파
equlas
메소드가 있습니다.equals
메소드는 클래스 리터럴을 인수 클래스와 비교하고 있습니다 (예를 들어,Foo
클래스에서Foo.class == o.getClass ()
와 같은 판정을 실시하고 있습니다).this.getClass () == o.getClass ()
이 더 좋다.Eq : 공변 인 equals 메소드의 정의 (EQ_SELF_NO_OBJECT)
이 클래스는 공변의
equals
메소드를 정의하고 있습니다.java.lang.Object
의equals
메소드를 올 Y로 대체하기 위해서는equals
메소드의 파라미터의 형태는java.lang.Object
해야합니다.FI : 하늘의 파이 나라이자는 삭제해야한다 (FI_EMPTY)
하늘의
finalize
메소드는 쓸모 없기 때문에 삭제해야합니다.FI : 파이 나라이자의 명시적인 호출 (FI_EXPLICIT_INVOCATION)
이 메소드는 명시 적으로 객체에
finalize
메소드의 호출이 있습니다. 종결자는 Java 가상 머신에 1 번만 실행되게되어 있기 때문에, 이것은 잘못된 생각입니다.참조로 연결된 여러 개체가 종료 가능 해지면, Java 가상 머신은 모든 객체의
finalize
메소드를 호출합니다. 아마 다른 스레드에서 동시에입니다. 따라서 클래스 X 의finalize
메소드에서 X 에 의해 참조되고있는 객체의finalize
메소드를 호출하는 것은, 특히 잘못된 생각입니다. 왜냐하면 객체가 이미 다른 스레드에 의해 종료되는지도 모르기 때문입니다.FI : 종결자는 필드를 null로 (FI_FINALIZER_NULLS_FIELDS)
이 종결자는 필드를 null로하고 있습니다. 이것은 보통 오류로 가비지 컬렉터를 도와 않습니다. 개체는 어쨌건간에 가비지됩니다.
FI : 종결자는 필드를 null로 할뿐 (FI_FINALIZER_ONLY_NULLS_FIELDS)
이 종결자는 필드를 null로하는 것 외에는 아무것도하지 않습니다. 이것은 전혀 의미가 없으므로 가비지되어 종료되고 다시 가비지되는 것을 요구하고 있습니다.
finalize
메소드를 제거해야합니다.FI : 파이 나라이자는 슈퍼 클래스의 파이 나라이자를 호출하지 않은 (FI_MISSING_SUPER_CALL)
이
finalize
메소드는 슈퍼 클래스의finalize
메소드를 호출하지 않습니다. 따라서 슈퍼 클래스에 정의 된 어떤 파이 나라이자 액션도 실행되지 않습니다.super.finalize ()
의 호출을 추가하십시오.FI : 파이 나라이자는 슈퍼 클래스의 파이 나라이자를 해제하고 (FI_NULLIFY_SUPER)
이 하늘의
finalize
메소드는 명시 적으로 슈퍼 클래스에 의해 정의 된 어떤 종료 자 효과도 해제합니다. 슈퍼 클래스에 정의 된 어떤 파이 나라이자 액션도 실행되지 않습니다. 이것이 의도 한 것이 아닌 경우, 메소드를 제거하십시오.FI : 파이 나라이자는 슈퍼 클래스의 파이 나라이자를 호출하고있을뿐 (FI_USELESS)
이
finalize
메소드는 슈퍼 클래스의finalize
메소드를 호출하고있을뿐입니다. 중복이므로 삭제하십시오.FS : 서식 문자열은 \ n보다 % n을 사용할 것이다 (VA_FORMAT_STRING_USES_NEWLINE)
이 형식 문자열에 개행 문자 (\ n)가 포함되어 있습니다. 일반적으로 서식 문자열은 % n을 사용하는 것이 더 바람직합니다. % n은 플랫폼 특유의 행 구분 기호를 만들어냅니다.
GC : 검사되지 않은 형태로 총칭 호출 (GC_UNCHECKED_TYPE_IN_GENERIC_CALL)
범용 형 매개 변수에서 특정 형태가 예상되는 Object 형을 컴파일 할 때 범용 형 컬렉션 메서드 호출은 인수를 전달합니다. 따라서 표준 Java 형 시스템도 정적 분석도 매개 변수로 전달되는 객체가 적절한 형태 여부에 대한 유용한 정보를 제공 할 수 없습니다.
HE : equals 메소드는 정의되어 있지만 hashCode 메소드는 정의하지 않는 클래스 (HE_EQUALS_NO_HASHCODE)
이 클래스는
equals (Object)
메서드를 재정의하고 있습니다 만,hashCode
메서드는 재정의하지 않습니다. 따라서 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 위반 할지도 모릅니다.HE : equals 메소드를 정의하고 Object.hashCode ()를 사용하는 클래스 (HE_EQUALS_USE_HASHCODE)
이 클래스는
equals (Object)
를 대체하고 있습니다 만,hashCode
메소드는java.lang.Object
에서 상속하고 있습니다 (동일성 해시 코드 (Java 가상 머신에 개체에 할당 된 임의의 값)을 반환합니다 ). 따라서 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 위반 할지도 모릅니다.이 클래스의 인스턴스가 HashMap / HashTable에 결코 대체 될 것이라고 생각하지 않으면 권장되는
hashCode
메소드의 구현은 다음과 같습니다.public int hashCode () { assert false : "hashCode를 호출하는 것은 상정되어 있지 않습니다."; return 42; // 적당한 값 }
HE : hashCode 메소드를 정의하고 있습니다 만 equals 메소드는 정의하지 않는 클래스 (HE_HASHCODE_NO_EQUALS)
이 클래스는
hashCode
메소드를 정의하고 있습니다 만,equals
메소드는 정의하지 않습니다. 이것은 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 위반 할지도 모릅니다.HE : hashCode 메소드를 정의하고 Object.equals ()를 사용하는 클래스 (HE_HASHCODE_USE_OBJECT_EQUALS)
이 클래스는
hashCode
메소드를 정의하고 있습니다 만,equals
메서드는java.lang.Object
에서 상속하고 있습니다 (개체 참조 비교 동등성을 판정합니다). 이것은 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약에 따르는 지 모르지만 아마hashCode
메소드를 재정 의하여 의도 된 것이 아닙니다. (hashCode
메서드를 재정의하는 것은 객체의 동일성이 단순한 참조 등가성보다 복잡한 규약에 근거 것을 의미합니다).이 클래스의 인스턴스가 HashMap / HashTable에 결코 대체 될 것이라고 생각하지 않으면 권장되는
hashCode
메소드의 구현은 다음과 같습니다.public int hashCode () { assert false : "hashCode를 호출하는 것은 상정되어 있지 않습니다."; return 42; // 적당한 값 }
HE : equals 메소드를 상속하고 Object.hashCode ()를 사용하는 클래스 (HE_INHERITS_EQUALS_USE_HASHCODE)
이 클래스는 추상 슈퍼 클래스에서
equals (Object)
메소드를 상속하여java.lang.Object
에서hashCode
메소드를 상속하고 있습니다 (동일성 해시 코드 (Java 가상 머신에 개체에 할당 된 임의의 값) 를 반환합니다). 따라서 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 위반 할지도 모릅니다.hashCode
메소드를 정의하지 않으려 또는 객체가 HashMap / Hashtable에 결코 포함되지 않는 것이라고 생각한다면UnsupportedOperationException
를 슬로우하는hashCode ()
메소드를 정의하십시오.IC : 슈퍼 클래스는 초기화 중에 서브 클래스를 사용하는 (IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION)
클래스는 초기화 중에 서브 클래스를 적극적으로 사용하고 있습니다. 서브 클래스는이 시점에서는 아직 초기화되어 있지 않습니다.
예를 들어, 다음 코드에서foo
는 null입니다.public class CircularClassInitialization { static class InnerClassSingleton extends CircularClassInitialization { static InnerClassSingleton singleton = new InnerClassSingleton (); } static CircularClassInitialization foo = InnerClassSingleton.singleton; }
IMSE : 의심 IllegalMonitorStateException 잡기 (IMSE_DONT_CATCH_IMSE)
IllegalMonitorStateException
은 일반적으로 설계 결함 (잠금을 보유하지 않는 개체에서wait
메소드 또는notify
메소드를 호출)의 경우에만 발생합니다.ISC : static 메소드만을 제공하는 클래스의 불필요한 인스턴스화 (ISC_INSTANTIATE_STATIC_CLASS)
이 클래스는 static 메소드만을 제공하는 클래스의 객체를 생성합니다. 이 개체는 만들 필요가 없습니다. 수식으로 직접 클래스 이름을 사용하는 static 메소드에 액세스하십시오.
It : Iterator.next ()이 NoSuchElementException을 던질 수 없다 (IT_NO_SUCH_ELEMENT)
이 클래스는
java.util.Iterator
를 구현하고 있습니다. 그러나next
메소드는java.util.NoSuchElementException
를 throw 할 수 없습니다.next
메소드는 더 이상 요소를 반환 할 수없는 경우는NoSuchElementException
을 던질 변경해야합니다.J2EE : HttpSession에 비 직렬화 가능 오브젝트의 저장 (J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION)
이 코드는 HttpSession에 비 직렬화 가능 객체를 포함하고 있다고 생각됩니다. 이 세션이 비활성화되거나 전환 된 경우 오류를 초래합니다.
JCIP : 불변 클래스의 필드는 final이 될 (JCIP_FIELD_ISNT_FINAL_IN_IMMUTABLE_CLASS)
클래스는 net.jcip.annotations.Immutable 또는 javax.annotation.concurrent.Immutable에서 주석되어 있습니다. 주석의 규칙은 모든 필드가 final 것을 의무화합니다.
ME : public 열거 메소드가 무조건 필드를 설정하는 Public enum method unconditionally sets its field (ME_ENUM_FIELD_SETTER)
무조건 열거 필드를 설정하는 public 열거 형에서 public 메소드를 선언하고 있습니다. 따라서 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 가변 열거 필드가 지연 초기화에 사용될지도 모른다해도 외계에 노출 배드 좋습니다. 이 메소드를 제거하거나 패키지 전용으로 선언 할 것을 생각하십시오.
ME : 열거 형 필드는 public으로 가변 인 (ME_MUTABLE_ENUM_FIELD)
가변 public 필드가 public 열거 형에 정의되어 있습니다. 따라서 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 가변 열거 필드가 지연 초기화에 사용될지도 모른다해도 외계에 노출 배드 좋습니다.이 메소드를 final 및 패키지 전용으로 선언 할 것을 생각하십시오.
NP : 반환 형식이 Boolean의 메소드가 명시 적으로 null을 반환한다 (NP_BOOLEAN_RETURN_NULL)
Boolean.TRUE, Boolean.FALSE, null를 돌려주는 메소드는 언제 사고가 일어나도 이상하지입니다. 이 메소드는, 마치 부울 값을 반환 것처럼 호출됩니다. 컴파일러는 Boolean 값의 오토 언 박싱을 삽입합니다. null 값이 반환되는 경우 NullPointerException이 발생할 수 있습니다.
NP : null를 돌려지도 모른다 clone 메소드 (NP_CLONE_COULD_RETURN_NULL)
이
clone
메소드는 어떤 조건에서 null을 반환하는 것으로합니다. 그러나clone
메소드는 결코 null를 돌려주는 것은 허용되지 않습니다. 이 경로가 도달 할 수없는 것을 확신하고 있다면, 대신AssertionError
를 throw합니다.NP : equals 메소드는 null 인수를 체크하지 않은 (NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT)
이
equals (Object)
메소드의 구현은 인수로 전달 된 null을 체크하지 않기 때문에java.lang.Object.equals ()
에서 정의 된 약관을 위반하고 있습니다. 모든equals
메소드는 인수에 null이 전달 된 경우 false를 반환한다.NP : null를 돌려지도 모른다 toString 메소드 (NP_TOSTRING_COULD_RETURN_NULL)
이
toString
메소드는 어떤 조건에서 null을 반환하는 것으로합니다. 사양을 관대하게 읽고이 허용된다고 해석 할 수 있을지도 모르지만, 아마 잘못된 생각으로 다른 코드가 손상 원인이 될 수 있습니다. null 대신 빈 문자열 또는 일부 다른 적절한 문자열을 반환합니다.Nm : 클래스 이름은 대문자로 시작해야 (NM_CLASS_NAMING_CONVENTION)
클래스 이름은 첫 글자와 그 뒤 각 단어의 첫 글자를 대문자로 된 명사해야합니다. 클래스 이름은 간단하고 직관적 같이하십시오. 머리 글자 및 약어 (URL이나 HTML 등과 같이 약자가 긴 형식보다 훨씬 널리 사용되고있는 경우를 제외)의 사용은 피하십시오.
Nm : 예외 클래스처럼 명명되어 있지만 클래스는 Exception에서 파생되지 않은 (NM_CLASS_NOT_EXCEPTION)
이 클래스는 예외 클래스에서 파생 된 않았는데 클래스 이름이 "Exception"으로 끝납니다. 이것은이 클래스의 사용자에게 혼란입니다.
Nm : 혼란 이름의 메소드 (NM_CONFUSING)
참조 된 메서드는 대문자 사용을 통해서만 다른 이름이 있습니다.
Nm : 필드 이름은 소문자로 시작해야 (NM_FIELD_NAMING_CONVENTION)
final이 아닌 필드의 이름은 첫 글자는 소문자로하고 연속적인 각 단어의 첫 글자를 대문자로해야합니다.
Nm : Java 이후 버전의 키워드 인 식별자를 사용하는 (NM_FUTURE_KEYWORD_USED_AS_IDENTIFIER)
식별자는 Java 이후 버전의 키워드로 예약되어있는 단어입니다. 코드를 Java 이후 버전에서 컴파일하기 위해서는 변경해야합니다.
Nm : Java 이후 버전의 키워드 인 식별자를 사용하는 (NM_FUTURE_KEYWORD_USED_AS_MEMBER_IDENTIFIER)
이 식별자는 Java 이후 버전의 키워드로 사용됩니다. 이 코드와 API를 참조하는 어떤 코드도 Java 이후 버전에서 컴파일하기 위해서는 변경해야합니다.
Nm : 메소드 이름은 소문자로 시작해야합니다 (NM_METHOD_NAMING_CONVENTION)
메소드 이름은 첫 글자는 소문자로하고 연속적인 각 단어의 첫 글자를 대문자로 동사에해야합니다.
Nm : 클래스 이름은 구현 된 인터페이스의 단순 명을 가로막는 안된다 (NM_SAME_SIMPLE_NAME_AS_INTERFACE)
이 클래스 또는 인터페이스는 인터페이스가 다른 패키지라는 것을 제외하고 구현 된 / 확장 된 인터페이스와 동일한 단순한 이름입니다 (예를 들어,
alpha.Foo
이beta.Foo
을 계승하고있는 상황입니다 ). 이것은 매우 혼동 참조 관계를 해결하기 위해 import 문장을 봐야 않으며, 슈퍼 클래스의 메소드를 재정의해서는 잘못 메소드를 정의하는 상황을 만들어냅니다.Nm : 클래스 이름은 슈퍼 클래스의 단순 명을 가로막는 안된다 (NM_SAME_SIMPLE_NAME_AS_SUPERCLASS)
이 클래스는 슈퍼 클래스가 다른 패키지라는 것을 제외하고는 슈퍼 클래스와 같은 단순 명을입니다 (예를 들어,
alpha.Foo
이beta.Foo
을 확장합니다). 이것은 매우 혼동 참조 관계를 해결하기 위해 import 문장을 봐야 않으며, 슈퍼 클래스의 메소드를 재정의해서는 잘못 메소드를 정의하는 상황을 만들어냅니다.Nm : 매우 혼란 이름의 메소드 (아마 의도적으로) (NM_VERY_CONFUSING_INTENTIONAL)
참조 된 메서드는 대문자 사용을 통해서만 다른 이름이 있습니다. 대문자 사용법이 동일하면 메소드 중 하나가 다른 메서드를 재정의하기 때문에 매우 혼란입니다. 다른 메소드의 존재에서 이러한 방법의 두 존재가 의도적 확실히 혼란시키고 있다고 생각합니다. API의 동결 둘 다 가지지 않을 수없는 경우를 제외하고 그 중 하나를 제거하려고 노력한다.
Nm : 매개 변수의 잘못된 패키지 위해서 슈퍼 클래스의 메소드를 오버라이드 (override)하지 않는 방법 (NM_WRONG_PACKAGE_INTENTIONAL)
파라미터의 형태가 정확하게 슈퍼 클래스로 대응하는 파라미터의 형태와 일치하지 않기 때문에, 서브 클래스의 메소드는 슈퍼 클래스의 유사한 메서드를 재정의하지 않습니다.
예를 들어 다음과 같은 코드입니다.import alpha.Foo; public class A { public int f (Foo x) {return 17;} } ---- import beta.Foo; public class B extends A { public int f (Foo x) {return 42;} public int f (alpha.Foo x) {return 27;} }
클래스
B
에 정의 된f (Foo)
메소드는 클래스A
의f (Foo)
메소드를 오버라이드 (override)하지 않습니다. 이것은 인수의 형태Foo
가 다른 패키지이기 때문입니다.이 경우 하위 클래스가 수퍼 클래스의 메서드와 동일한 시그니처 메소드를 정의하고 있기 때문에 아마 이해할 수 있습니다. 그러나 이러한 방법은 매우 혼란입니다. 유사하지만 동일하지 않은 서명의 메소드를 제거하거나 비추천으로하는 것이 좋을 것이다.
ODR : 데이터베이스 리소스의 청산에 실패 할지도 모른다 메소드 (ODR_OPEN_DATABASE_RESOURCE)
이 메소드는 데이터베이스 자원 (예를 들어, 데이터베이스 연결이나 행 집합)를 작성하고 있습니다 만, 어떤 필드에 대입 않았거나 다른 방법으로도 전달하지 않거나 반환 값도하지 않습니다. 그리고 메소드에서 모든 경로에서 개체를 닫기 것처럼 보이지 않습니다. 메소드에서 모든 경로에서 데이터베이스 리소스 청산이 실패하면 성능 저하 될 수 있습니다. 데이터베이스와의 통신에 문제가있는 응용 프로그램의 원인이 될 수 있습니다.
ODR : 예외 경로에서 데이터베이스 자원의 청산에 실패 할지도 모른다 메소드 (ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH)
이 메소드는 데이터베이스 자원 (예를 들어, 데이터베이스 연결이나 행 집합)를 작성하고 있습니다 만, 어떤 필드에 대입 않았거나 다른 방법으로도 전달하지 않거나 반환 값도하지 않습니다. 그리고 메소드에서 모든 예외 경로에서 개체를 닫기 것처럼 보이지 않습니다. 메소드에서 모든 경로에서 데이터베이스 리소스 청산이 실패하면 성능 저하 될 수 있습니다. 데이터베이스와의 통신에 문제가있는 응용 프로그램의 원인이 될 수 있습니다.
OS : 스트림의 클로즈에 실패 할지도 모른다 메소드 (OS_OPEN_STREAM)
이 방법은 입출력 스트림 오브젝트를 작성하고 있습니다 만, 어떤 필드에 대입하지 않으며 폐쇄 할지도 모른다 다른 방법도 전달하지 않아 반환하고도 없습니다. 그리고 메소드에서 모든 경로에서 폐쇄하도록 보이지 않습니다. 이것은 파일 기술자 누수의 원인이 될 수 있습니다. 스트림이 폐쇄되는 것을 보장하기 위해
finally
블록을 사용하는 것은 일반적으로 좋은 생각입니다.OS : 예외 경로에서 스트림의 클로즈에 실패 할지도 모른다 메소드 (OS_OPEN_STREAM_EXCEPTION_PATH)
이 방법은 입출력 스트림 오브젝트를 작성하고 있습니다 만, 어떤 필드에 대입하지 않으며 폐쇄 할지도 모른다 다른 방법도 전달하고 있지 않고하여 반환하고도 없습니다. 그리고 방법에서 모든 가능성이있는 예외 경로로 폐쇄하도록 보이지 않습니다. 이것은 파일 기술자 누수의 원인이 될 수 있습니다. 스트림이 폐쇄되는 것을 보장하기 위해
finally
블록을 사용하는 것은 일반적으로 좋은 생각입니다.PZ : 반복 항목 객체를 재사용하지 않는 (PZ_DONT_REUSE_ENTRY_OBJECTS_IN_ITERATORS)
이 클래스는 Iterator와 Map.Entry에서 기저 Map의 뷰를 돌려주는 것을 허가 된 두 entrySet 메소드가 있습니다. 이 성공적인 아이디어는 Map 구현으로 사용되었습니다 만, 성가신 코딩 실수의 가능성을 캡처했습니다.map
M
이 entrySet위한 그런 반복자를 반환한다면,c.addAll (m.entrySet ())
는 심각하게 잘못된 것입니다. OpenJDK 1.7의 모든 Map 구현은이를 해결하기 위해 재 작성되었습니다.RC : 상수에 대한 의심 참조 비교 (RC_REF_COMPARISON_BAD_PRACTICE)
이 메서드는 참조 값을 == 나! = 연산자를 사용하여 상수와 비교하고 있습니다. 일반적으로이 형식의 인스턴스를 비교하는 올바른 방법은
equals
메소드입니다. 등가 식별 가능한 인스턴스를 만들 수 있지만 다른 개체이므로 ==로 비교하지 마십시오. 일반적으로 참조에 의해 비교되어야하는 것이 아닌 클래스의 예는java.lang.Integer
,java.lang.Float
등입니다.RC : Boolean 값의 의심 참조 비교 (RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN)
이 방법은 == 또는! = 연산자를 사용하여 두 개의 Boolean 값을 비교하고 있습니다. 일반적으로 2 개의 Boolean 값 (
Boolean.TRUE
와Boolean.FALSE
)뿐입니다 만,new Boolean (b)
생성자를 사용하여 다른 Boolean 객체를 만들 수 있습니다. 그런 객체를 피할 최고입니다. 그러나 그들이 존재한다면 Boolean 객체의 동등성을 확인하기 위해.equals (...)
대신 == 나! =를 사용하고 있다면 다른 결과를 제공합니다.RR : InputStream.read ()의 반환 값을 무시하는 방법 (RR_NOT_CHECKED)
이 방법은 여러 바이트를 반환 할 수있는
java.io.InputStream.read ()
(또는 유사)의 반환 값을 무시하고 있습니다. 반환 값이 체크되지 않으면 호출자는 요구 된 바이트 수보다 적은 바이트 수를 읽어 낸 경우 제대로 처리 할 수 없습니다. 이것은 잠재적 인 버그에서 많은 프로그램은 입력 스트림에서 읽기는 보통 요구 한 전체 데이터 양을 읽어 있지만 산발적으로 실패 할 수 있습니다.RR : InputStream.skip ()의 반환 값을 무시하는 방법 (SR_NOT_CHECKED)
이 방법은 여러 바이트를 스킵 할 가능성이있다
java.io.InputStream.skip ()
의 반환 값을 무시하고 있습니다. 반환 값이 체크되지 않으면 호출자는 요구 된 바이트 수보다 적은 바이트 수 밖에 스킵하지 않으면 제대로 처리 할 수 없습니다. 이것은 잠재적 인 버그에서 많은 프로그램은 입력 스트림로부터 스킵은 보통 요구 한 전체 데이터 양을 생략하고 있지만 산발적으로 실패 할 수 있습니다. 그러나 버퍼 스트림에서skip
메소드는 버퍼의 데이터를 건너 뛰므로 요청한 바이트 스킵는 항상 실패합니다.RV : compareTo () / compare ()의 결과를 무효로한다 (RV_NEGATING_RESULT_OF_COMPARETO)
이 코드는
compareTo
또는compare
메소드의 반환 값을 무효로하고 있습니다. 이것은 의심하거나 나쁜 프로그래밍 방법입니다. 반환 값이 Integer.MIN_VALUE이므로 반환 값을 해제하는 것은 결과의 부호를 해제하지 않습니다. 결과를 무효로하는 것이 아니라 피연산자의 순서를 반대로하여 같은 의도 한 결과를 얻을 수 있습니다.RV : 예외적 반환 값을 무시하는 방법 (RV_RETURN_VALUE_IGNORED_BAD_PRACTICE)
이 메소드는 확인되지 않은 값을 반환합니다. 반환 값은 이상 의외의 결과를 나타낼 수 있으므로 확인해야합니다. 예를 들어,
File.delete ()
는 파일을 잘 제거 할 수 없었던 경우에 예외 상황을 던질 것이 아니라 false를 반환합니다. 결과를 확인하지 않으면 예외 반환 값을 반환하는 메서드 호출 예상외의 행동의 신호로 인식하지 않습니다.SI : 정적 이니셜 라이저는 모든 static final 필드가 할당되기 전에 인스턴스 만들기 (SI_INSTANCE_BEFORE_FINALS_ASSIGNED)
모든 static final 필드가 초기화되기 전에 정적 이니셜 라이저가 클래스의 인스턴스를 만듭니다.
SW : Swing 메소드는 AWT 이벤트 발송 쓰레드에서 호출 할 필요가있다 (SW_SWING_METHODS_INVOKED_IN_SWING_THREAD)
( From JDC Tech Tip )
에 설명 된대로 Swing 메소드,show
메소드setVisible
메소드pack
메소드는 프레임에 관련된 피어를 작성합니다. 피어 만들기에서 시스템 이벤트 발송 쓰레드를 생성합니다. 이것이 문제가 될 수 있습니다. 왜냐하면pack
메소드와validate
메소드가 아직 처리 중에도 이벤트 발송 쓰레드가 리스너에게 통지 있기 때문입니다. 이러한 상황은 2 개의 스레드가 Swing 컴퍼넌트에 액세스 할 수 있습니다 교착 상태 나 다른 스레드 문제가 될 수있는 심각한 결함입니다.pack
메소드의 호출은 구성 요소를 실체화시킵니다. 실체화 때, 이벤트 발송 쓰레드가 리스너에 대한 통지를 시작할 수 있습니다.Se : 직렬화 가능 클래스의 비 transient로 비 직렬화 가능한 인스턴스 필드 (SE_BAD_FIELD)
이 직렬화 가능 클래스는 transient, Serializable,
java.lang.Object
아닌 비 원시적 형의 인스턴스 필드를 정의하여Externalizable
인터페이스 또는readObject
메소드와writeObject
메소드를 구현하도록 보이지 않습니다. 또한Externalizable
인터페이스를 구현하고 있지 않아서,readObject
메소드도writeObject
메소드도 정의하지 않습니다. 비 직렬화 가능 객체가이 필드에 포함된다면 클래스의 객체가 제대로 직렬화 복원되지 않습니다.Se : 비 직렬화 가능 클래스에 직렬화 가능한 내부 클래스가있다 (SE_BAD_FIELD_INNER_CLASS)
이 직렬화 가능 클래스는 직렬화 가능 클래스의 내부 클래스입니다. 내부 클래스를 직렬화하려고하면 관련 외부 클래스의 인스턴스를 묶으려고하기 때문에 런타임 오류가 발생할 수 있습니다.
가능하면 내부 클래스를 static으로 문제를 해결해야합니다. 외부 클래스를 직렬화 가능하게하여 작동 할지도 모르지만, 내부 클래스의 인스턴스를 직렬화하는 것은 외부 클래스도 항상 직렬화하는 것을 의미합니다. 진정으로 원하는 것입니까?
Se : 비 직렬화 가능한 값을 직렬화 가능 클래스의 인스턴스 필드에 저장하고있다 (SE_BAD_FIELD_STORE)
비 직렬화 가능한 값을 직렬화 가능 클래스의 비 transient 필드에 저장합니다.
Se : Comparator는 Serializable를 구현하지 않은 (SE_COMPARATOR_SHOULD_BE_SERIALIZABLE)
이 클래스는
Comparator
인터페이스를 구현하고 있습니다.Serializable
인터페이스를 구현할지 여부 검토해야합니다. 비교기가TreeMap
과 같은 정렬 된 컬렉션을 구축하기 위해 사용될 경우, 비교기가 직렬화 가능한 경우에만TreeMap
는 직렬화 가능합니다. 대부분의 비교기가 대부분 상태가없는해도 직렬화 가능하게하는 것은 간단하고 좋은 방어적인 프로그래밍입니다.Se : 직렬화 가능한 내부 클래스 (SE_INNER_CLASS)
이 직렬화 가능 클래스는 내부 클래스입니다. 내부 클래스를 직렬화하려고하면 관련된 외부 클래스의 인스턴스를 직렬화합니다. 외부 클래스의 인스턴스는 직렬화 가능하므로 실패하지 않습니다. 그러나 의도했던 것보다 더 많은 데이터를 직렬화 할지도 모릅니다. 가능하면 내부 클래스를 static으로 문제를 해결해야합니다.
Se : serialVersionUID가 final이 아닌 (SE_NONFINAL_SERIALVERSIONID)
이 클래스는 final이 아닌
serialVersionUID
필드를 정의합니다. 직렬화를 목적으로 버전 UID를 지정하는 것을 의도하고 있다면 필드는 final이어야합니다.Se : serialVersionUID가 long이 아닌 (SE_NONLONG_SERIALVERSIONID)
이 클래스는 long이 아닌
serialVersionUID
필드를 정의합니다. 직렬화를 목적으로 버전 UID를 지정하는 것을 의도하고 있다면 필드는 long이어야합니다.Se : serialVersionUID가 static이 아닌 (SE_NONSTATIC_SERIALVERSIONID)
이 클래스는 static이 아닌
serialVersionUID
필드를 정의합니다. 직렬화를 목적으로 버전 UID를 지정하는 것을 의도하고 있다면 필드는 static이어야합니다.Se : Serializable 클래스의 슈퍼 클래스에서 인수없이 생성자를 정의하지 않은 (SE_NO_SUITABLE_CONSTRUCTOR)
이 클래스는
Serializable
인터페이스를 구현하고 있습니다 만, 그 슈퍼 클래스는 구현하지 않습니다. 그러한 객체가 직렬화 복원 될 때, 슈퍼 클래스의 필드는 슈퍼 클래스의 인수 없음 생성자를 호출하여 초기화 될 필요가 있습니다. 슈퍼 클래스의 변수없이 생성자가 없기 때문에, 직렬화 및 직렬화 복원 실행시에 실패합니다.Se : Externalizable 클래스가 인수 없음 생성자를 정의하지 않은 (SE_NO_SUITABLE_CONSTRUCTOR_FOR_EXTERNALIZATION)
이 클래스는
Externalizable
인터페이스를 구현하고 있습니다 만, 인수없이 생성자를 정의하지 않습니다.Externalizable
객체가 직렬화 복원 될 때 먼저 인수없이 생성자를 호출하여 구축 될 필요가 있습니다. 이 클래스에는 인수 없음 생성자가 없기 때문에, 직렬화 및 직렬화 복원 실행시에 실패합니다.Se : readResolve 메소드의 반환 값의 형태가 Object로 선언되지 않은 (SE_READ_RESOLVE_MUST_RETURN_OBJECT)
readResolve
메소드가 직렬화기구로 인식되기 위하여는 반환 형식이Object
로 선언되어야합니다.Se : 직렬화 복원에 의해 설정되지 않는 transient 필드 (SE_TRANSIENT_FIELD_NOT_RESTORED)
이 클래스는 여러 위치에서 업데이트되는 필드가 있습니다. 따라서이 클래스의 상태의 일부라고 생각됩니다. 그러나 필드는 transient로 선언되어 있기 때문에, readObject / readResolve으로 값이 설정되지 않습니다.클래스의 직렬화 복원 된 인스턴스에 기본값이 설정됩니다.
SnVI : Serializable 클래스가 serialVersionUID를 정의하고 있지 않다 (SE_NO_SERIALVERSIONID)
이 클래스는
Serializable
인터페이스를 구현하고 있습니다 만,serialVersionUID
필드를 정의하지 않습니다. .class 개체에 대한 참조를 추가하는 것만 큼 간단한 변경으로 클래스에 합성 필드를 추가합니다. 그것은 불행히도 암시의serialVersionUID
를 변경합니다 (예를 들어,String.class
에 대한 참조를 추가하면class $ java $ lang $ String
라는 static 필드를 생성합니다). 또한 바이트 코드 컴파일러에 다른 소스 코드는 클래스 객체 또는 내부 클래스를 참조하기 위해 생성 된 합성 변수에 대해 다른 명명 규칙을 사용 할지도 모릅니다. 버전을 횡단하는 Serializable의 상호 운용성을 보장하기 위해 명시 적으로 serialVersionUID를 추가하는 것을 고려하십시오.UI : 클래스가 확장된다면 getResource 사용은 안전하지 않을지도 모른다 (UI_INHERITANCE_UNSAFE_GETRESOURCE)
이 클래스가 다른 패키지에 의해 확장된다면
this.getClass (). getResource (...)
호출은 의외의 결과를 가져올 수 있습니다.BC : 불가능한 캐스트 (BC_IMPOSSIBLE_CAST)
이 캐스트는 항상 ClassCastException를 슬로우합니다. FindBugs는 instanceof 체크에서 형식 정보를 조사하여 메소드의 반환 값과 필드에서로드 된 값의 형태에 대해 더 정확한 정보를 사용합니다. 따라서 선언 된 변수의 형태는 더 정확한 정보가 있을지도 모른다 모릅니다. 또한 캐스팅이 항상 실행시 예외를 throw할지 여부를 결정하는 데 이용 될 수 있습니다.
BC : 불가능한 다운 캐스트 (BC_IMPOSSIBLE_DOWNCAST)
이 캐스트는 항상 ClassCastException를 슬로우합니다. 분석 캐스팅 값의 정확한 형태가 알고 있다고 믿고 있습니다. 그리고 하위 유형으로 다운 캐스트하려는 시도는 ClassCastException를 슬로우에 의해 항상 실패합니다.
BC : toArray 메소드의 결과 불가능한 다운 캐스트 (BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY)
이 코드는 다음과 같이
Object []
보다 특정 형태의 컬렉션에toArray
메소드를 호출 결과를 캐스팅하고 있습니다.String [] getAsArray (Collection <String> c) { return (String []) c.toArray (); }
이것은 일반적 ClassCastException를 슬로우 해 실패합니다. 거의 모든 컬렉션의
toArray
메소드는Object []
를 리턴합니다. Collection 객체는 선언 된 범용 형 컬렉션 참조가 없기 때문에 정말 아무것도 할 수 없습니다. 컬렉션에서 특정 형태의 배열을 얻는 올바른 방법은c.toArray (new String []);
또는c.toArray (new String [c.size ());
(후자는 경미하게 더 효율적입니다)를 사용 하는 것입니다. 이에 대한 하나의 일반적인 알려진 예외가 있습니다.Arrays.asList (...)
에 의해 반환되는리스트의toArray ()
메소드는 공동 변형 배열을 돌려줍니다. 예를 들어,Arrays.asArray (new String [] { "a"}). toArray ()
는String []
를 리턴합니다. FindBugs는 이러한 경우를 감지하고 억제하려고하지만 간과하고 있을지도 모릅니다.BC : 항상 false를 반환 instanceof (BC_IMPOSSIBLE_INSTANCEOF)
이 instanceof는 항상 false를 반환합니다. 이것은 안전하고 오해와 논리적 오류를 지적하고 있지 않은지 확인하십시오.
BIT : 부호있는 바이트 값의 비트 가산 (BIT_ADD_OF_SIGNED_BYTE)
바이트 값과 분명히 하위 8 비트가있는 것으로 알려진 값을 가산하고 있습니다. 비트 연산을 수행하기 전에 바이트 배열에서로드 된 값은 32 비트까지 부호 확장됩니다. 따라서
b [0]
의 값이0xff
에서x
의 초기 값이0
이라고하면((x << 8) + b [0])
는0xff
가 부호 확장0xffffffff
되기 때문에 결과적으로0xffffffff
를 얻을 수 있습니다.특히 바이트 배열 int에 팩하는 다음과 같은 코드는 심각하게 잘못된 있습니다.
int result = 0; for (int i = 0; i <4; i ++) result = ((result << 8) + b [i]);
대신 다음과 같은 관용구 작동합니다.
int result = 0; for (int i = 0; i <4; i ++) result = ((result << 8) + (b [i] & 0xff));
BIT : 호환되지 않는 비트 마스크 (BIT_AND)
이 방법은 (e & C) 형식의 식을 D 와 비교합니다. 상수 C 의 특정 값과 D 위하여 항상 동일하지 않은 것을 비교합니다. 논리 오류 또는 오타지도 모릅니다.
BIT : ((...) & 0) == 0인지 확인하고있다 (BIT_AND_ZZ)
이 방법은 (e & 0) 형식의 식을 0과 비교하고 있습니다. 그것은 항상 동일 함을 비교합니다. 논리 오류 또는 오타지도 모릅니다.
BIT : 호환되지 않는 비트 마스크 (BIT_IOR)
이 방법은
(e | C)
형식의 식을D
와 비교합니다. 상수 C 의 특정 값과 D 를 위해 항상 동일하지 않은 것을 비교합니다. 논리 오류 또는 오타지도 모릅니다.일반적으로이 버그는 비트 세트에 귀속 관계의 테스트를 실행하려면 코드에서 발생합니다. 그러나 비트 논리 곱 연산자 ( "&") 대신 비트 논리합 연산자 ( "|")를 사용하고 있습니다.
BIT : 부호있는 바이트 값의 비트 논리합 (BIT_IOR_OF_SIGNED_BYTE)
로드 한 바이트 값 (예를 들어, 바이트 배열에서로드 된 값과 반환 값이 바이트 형식 메서드에서 반환 된 값)와 비트 논리합을 실행하고 있습니다. 비트 연산을 수행하기 전에 바이트 값은 32 비트까지 부호 확장됩니다. 따라서
b [0]
의 값이0xff
에서x
의 초기 값이0
이라고하면((x << 8) | b [0])
는0xff
가 부호 확장0xffffffff
되기 때문에 결과적으로0xffffffff
를 얻을 수 있습니다.특히 바이트 배열 int에 팩하는 다음과 같은 코드는 심각하게 잘못된 있습니다.
int result = 0; for (int i = 0; i <4; i ++) { result = ((result << 8) | b [i]); }
대신 다음과 같은 관용구 작동합니다.
int result = 0; for (int i = 0; i <4; i ++) { result = ((result << 8) | (b [i] & 0xff)); }
BIT : 비트 연산 부호를 확인 (BIT_SIGNED_CHECK_HIGH_BIT)
이 방법은
((event.detail & SWT.SELECTED)> 0)
과 같은 식을 비교하고 있습니다. 비트 연산을보다 연산자로 비교하는 것은 의외의 결과 (물론SWT.SELECTED
값에 의한)의 원인이 될 수 있습니다.SWT.SELECTED
가 음수라면, 이것은 버그의 후보입니다.SWT.SELECTED
가 부가 아니더라도 '> 0'대신 '! = 0'을 사용하는 것은 좋은 사례라고 생각합니다.Boris Bokowski
BOA : 슈퍼 클래스의 Adapter에서 구현되는 방법을 잘못 무시하고있는 클래스 (BOA_BADLY_OVERRIDDEN_ADAPTER)
이 메소드는 슈퍼 클래스에서 구현 된 메서드를 재정의합니다. 슈퍼 클래스는 java.awt.event와 javax.swing.event 패키지로 정의되는 수신기를 구현하는 Adapter입니다. 따라서 이벤트가 발생할 때이 메소드가 호출되지 않습니다.
BSHIFT : 쉬프트 연산의 잘못된 구문 분석의 가능성이있다 (BSHIFT_WRONG_ADD_PRIORITY)
코드는 (x << 8 + y)와 같은 작업을 수행합니다. 이것은 맞을지도 모르지만 아마 (x << 8) + y을 할 의도로했습니다. 그러나 시프트 연산 우선 순위가 낮기 때문에 실제로는 x << (8 + y)로서 구문 분석됩니다.
BSHIFT : 32 비트 int의 -31에서 31의 범위를 초과 한 금액에 의한 쉬프트 (ICAST_BAD_SHIFT_AMOUNT)
이 코드는 32 비트 int의 -31에서 31의 범위를 초과 한 금액으로 시프트를 실행하고 있습니다. 이것의 효과는 얼마나 이동 하는지를 결정하기 위해 정수 값의 하위 5 비트 (32로 나눈 나머지)을 사용하는 것입니다 (예를 들어, 40 비트에서 이동하는 것은 8 비트 시프트하는 것과 동일 32 비트에서 이동하는 것은 0 비트로 이동하는 것과 같습니다). 이것은 아마 예상 된 것이 아니라 적어도 혼란입니다.
DLS : return 문에 불필요한 증가가있다 (DLS_DEAD_LOCAL_INCREMENT_IN_RETURN)
return x ++;
같은 return 문이 있습니다. 접두사 증가 / 감소는 식의 값에 영향을주지 않기 때문에, 증가 / 감소 효과가 없습니다. 이 문장이 맞는지 확인하십시오.DLS : 클래스 리터럴의 잘못된 할당 (DLS_DEAD_STORE_OF_CLASS_LITERAL)
이 명령은 변수에 클래스 리터럴을 할당하고 있지만, 결코 사용되지 않습니다. The behavior of this differs in Java 1.4 and in Java 5 J2SE 1.4 및 이전 버전에서는
Foo.class
에 대한 참조는Foo
위한 정적 이니셜 라이저가 이미 실행되고 있지 않으면 실행하도록 강요합니다. J2SE 5.0에서는 그렇지 않습니다.더 자세한 내용과 예제와 J2SE 5.0의 클래스 강제 초기화 방법의 제안은 Sun의 article on Java SE compatibility 를 참조하십시오.
DLS : 덮어 쓴 증가 (DLS_OVERWRITTEN_INCREMENT)
이 코드는 증가 연산 (예를 들어,
i ++
)를 실행하여 즉각적으로 겹쳐있다. 예를 들어,i = i ++
는 원래 값을 증가 값으로 덮어 씁니다.DMI : 거꾸로 된 인수 (DMI_ARGUMENTS_WRONG_ORDER)
이 메소드 호출의 인수는 순서가 잘못된 것 같습니다. 예를 들어, 호출
Preconditions.checkNotNull ( "message"message)
는 인수를 예약했습니다. 체크되는 값은 첫 번째 인수입니다.DMI : 달을위한 잘못된 상수 값 (DMI_BAD_MONTH)
이 코드는 메소드 0에서 11의 범위를 벗어난 달 상수 값을 전달하고 있습니다.
DMI : 정확하게 표시되지 않는 double에서 구축 된 BigDecimal (DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE)
이 코드는 10 진수 숫자로 잘 변환되지 않는 double 값에서 BigDecimal을 만들고 있습니다. 예를 들어, Java에서
new BigDecimal (0.1)
라고 쓰면 0.1와 정확하게 동일한 BigDecimal (스케일이 1 스케일 없음의 값이 1)이 생성되는 싶을지도 모르지만, 실제로는 0.1000000000000000055511151231257827021181583404541015625과 같습니다 합니다.아마
BigDecimal.valueOf (double d)
메소드의 사용이 바람직합니다. BigDecimal (예를 들어,BigDecimal.valueOf (0.1)
0.1을줍니다)을 작성하기 위해서는 double의 문자열 표현을 사용합니다.DMI : hasNext 메소드 next 메소드를 호출하는 (DMI_CALLING_NEXT_FROM_HASNEXT)
hasNext
메소드는,next
메소드를 호출합니다.hasNext
메소드는 반복자의 상태를 변경할되어 있지 않기 때문에, 거의 확실하게 잘못된 것입니다.next
메소드가 반복자의 상태를 변경하는 것으로되어 있습니다.DMI : 컬렉션 자신을 포함해서는 안된다 (DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES)
이 범용 형 컬렉션 메서드 호출은 컬렉션에 자신이 포함되어있는 경우 (예를 들어,
s.contains (s)
가 true)에만 의미가 있습니다. 이것이 진실이라고는 생각하지 않으며 만약 사실이라면 문제의 원인이됩니다 (예를 들어, 무한 재귀되어 해시 코드의 계산). 잘못된 매개 변수를 전달하고있을 가능성이 높습니다.DMI : D' oh! 무의미한 메소드 호출 (DMI_DOH)
이 부분 메서드 호출은 검사에서 명백한 이유로 의미가 없습니다.
DMI : 배열 hashCode 메소드를 호출하는 (DMI_INVOKING_HASHCODE_ON_ARRAY)
이 코드는 배열에서
hashCode
메소드를 호출합니다. 배열hashCode
메소드를 호출하는 것은 System.identityHashCode와 같은 값을 반환하기 때문에 콘텐츠와 배열의 길이를 무시합니다. 배열a
의 내용으로 해시 코드를 필요로한다면,java.util.Arrays.hashCode (a)
를 사용하십시오.DMI : int 대해 Double.longBitsToDouble ()를 호출하는 (DMI_LONG_BITS_TO_DOUBLE_INVOKED_ON_INT)
Double.longBitsToDouble ()
의 호출로 32 비트 int 값이 인자로 전달합니다. 이것은 틀림없이 의도 한 것은 아니며 의도 한 결과를주는 경우는 거의 없습니다.DMI : 컬렉션에 무의미한 호출 (DMI_VACUOUS_SELF_COLLECTION_CALL)
이 호출은 의미가 없습니다. 어떤 컬렉션
c
도c.containsAll (c)
를 호출하는 것은 항상 true 여야합니다. 그리고c.retainAll (c)
효과가있을 리 없습니다.Dm : 런타임 보유없이 어노테이션의 존재를 확인하기 위해 리플렉션을 사용 할 수 없다 (DMI_ANNOTATION_IS_NOT_VISIBLE_TO_REFLECTION)
어노테이션은
@Retention (RetentionPolicy.RUNTIME)
에서 주석되어야 리플렉션 (예를 들어,isAnnotationPresent (...)
메소드)를 사용하여 관측 할 수 없습니다.Dm : ScheduledThreadPoolExecutor의 최대 풀 크기를 바꾸려는 헛된 시도 (DMI_FUTILE_ATTEMPT_TO_CHANGE_MAXPOOL_SIZE_OF_SCHEDULED_THREAD_POOL_EXECUTOR)
ScheduledThreadPoolExecutor
는ThreadPoolExecutor
로부터 상속되지만 상속 된 튜닝 메소드의 일부는 유용하지 않습니다. 특히, corePoolSize thread와 안 바운드 형식의 큐를 사용하는 고정 사이즈 풀로서 동작하기 때문에 maximumPoolSize의 조정은 유용한 효과가 없습니다.
( Javadoc )Dm : 코어 풀 사이즈가 0 ScheduledThreadPoolExecutor 만들기 (DMI_SCHEDULED_THREAD_POOL_EXECUTOR_WITH_ZERO_CORE_THREADS)
코어 풀 사이즈가 0
ScheduledThreadPoolExecutor
은 결코 아무것도 실행하지 않습니다. 최대 풀 크기에 변화는 무시됩니다.
( Javadoc )Dm : EasyMock 메소드에 쓸모없는 / 무의미한 호출 (DMI_VACUOUS_CALL_TO_EASYMOCK_METHOD)
이 호출은 EasyMock 메소드에 어떤 객체도 전달하지 않기 때문에 아무것도하지 않습니다.
Dm : Math.max과 Math.min의 잘못된 조합 (DM_INVALID_MIN_MAX)
이 코드는
Math.min (0 Math.max (100, value))
과 같은 구문을 사용하여 경계 값을 제한하려고하고 있습니다. 그러나 정수의 순서가 잘못되었습니다.Math.min (100 Math.max (0, value))
이어야합니다. 결과적으로이 코드는 항상 동일한 결과 (만약 값이 NaN이면 NaN)을 만들어냅니다.EC : equals 메소드를 사용하여 배열 및 비 배열을 비교하고있다 (EC_ARRAY_AND_NONARRAY)
이 메서드는 배열과 배열이라고 생각되지 않는 참조를 비교하기 위해
.equals (Object o)
를 호출합니다. 비교되는 것이 다른 형태라면 같지 않은다는 보장되어 있기 때문에 비교는 거의 확실히 잘못된 것입니다. 비록 그들이 모두 배열했다하더라도 배열의equals
메소드는 두 배열이 동일한 객체라고 결정하면됩니다. 배열의 내용을 비교하기 위해서는java.util.Arrays.equals (Object [], Object [])
를 사용하십시오.EC : 배열의 equals 메소드 호출은 ==와 동일하다. (EC_BAD_ARRAY_COMPARE)
이 메서드는 배열에서
.equals (Object o)
를 호출합니다. 배열은Object
의equals
메소드를 오버라이드 (override)하지 않기 때문에, 배열에서equals
메소드를 호출 할 주소를 비교하는 것과 같습니다. 배열의 내용을 비교하기 위해서는java.util.Arrays.equals (Object [], Object [])
를 사용하십시오. 배열의 주소를 비교하기 위해 명시 적으로==
를 사용하여 참조 등가성을 체크하는 것은 그만큼 혼동 없을 것입니다.EC : equals (...) 메소드를 사용하여 호환되지 않는 배열을 비교하고있다 (EC_INCOMPATIBLE_ARRAY_COMPARE)
이 메서드는 호환되지 않는 형식의 배열을 비교하기 위해
.equals (Object o)
를 호출합니다 (예를 들어,String []
과StringBuffer []
,String []
와int []
). 그들은 결코 동일하지 않습니다. 또한equals (...)
이 배열을 비교하는 데 사용되는 때, 그들이 동일한 배열인지 확인뿐만 배열의 내용은 무시합니다.EC : equals (null)의 호출 (EC_NULL_ARG)
이 메소드는 null 값 인수를 전달
equals (Object)
를 호출하고 있습니다.equals
메소드의 규약에 의하면,이 호출은 항상 false를 반환해야합니다.EC : equals 메서드를 호출 관계의 클래스와 인터페이스를 비교하고있다 (EC_UNRELATED_CLASS_AND_INTERFACE)
이 방법은 한 클래스에서 다른이 인터페이스 인 두 참조에서
equals (Object)
메소드를 호출합니다. 클래스는 그 클래스의 비 추상 서브 클래스를 포함하여 인터페이스를 구현하지 않습니다. 따라서 비교되는 두 개체는 실행시에 같은 클래스의 멤버 일 가능성이 낮습니다 (일부 응용 프로그램 클래스를 해석 할 수 없거나 동적 클래스 로딩이 실행시에 일어날 수있는 경우 제외) .equals
메소드의 규약에 의하면, 다른 클래스의 객체는 항상 같지 않음으로 비교해야합니다. 따라서java.lang.Object.equals (Object)
에 의해 정의 된 규약에 의하면,이 비교의 결과는 실행시 항상 false입니다.EC : equals 메소드를 호출하여 다른 형태의 인터페이스를 비교하고있다 (EC_UNRELATED_INTERFACES)
이 방법은 모두 다른 서브 타입이 아닌 독립적 인 인터페이스 형의 2 개의 참조에서
equals (Object)
메소드를 호출합니다. 그리고 두 인터페이스를 구현하는 알려진 비 추상 클래스가 없습니다. 따라서 비교되는 두 개체는 실행시에 같은 클래스의 멤버 일 가능성이 낮습니다 (일부 응용 프로그램 클래스를 해석 할 수 없거나 동적 클래스 로딩이 실행시에 일어날 수있는 경우 제외) .equals
메소드의 규약에 의하면, 다른 클래스의 객체는 항상 같지 않음으로 비교해야합니다. 따라서java.lang.Object.equals (Object)
에 의해 정의 된 규약에 의하면,이 비교의 결과는 실행시 항상 false입니다.EC : equals 메소드를 호출 해 다른 유형을 비교하고있다 (EC_UNRELATED_TYPES)
이 메소드는, 다른 클래스 형의 2 개의 참조에서
equals (Object)
메소드를 호출하여 분석을 실행시 다른 클래스의 객체가 될 것을 시사하고 있습니다. 또한 호출 될 것이다 equals 메소드의 검사는이 호출은 항상 false를 반환하거나 equals 메소드가 대칭 (Object 클래스의 equals위한 계약에 필요한 성질)이 아님 중 하나를 제안합니다 있습니다.EC : 참조 등가성을 사용하여 다른 유형을 비교하고있다 (EC_UNRELATED_TYPES_USING_POINTER_EQUALITY)
이 메소드는 다른 형태라고 생각되는 2 개의 참조를 비교하기 위해 참조 동일성을 사용하고 있습니다. 이 비교의 결과는 항상 false입니다.
Eq : equals 메소드는 항상 false를 리턴 (EQ_ALWAYS_FALSE)
이 클래스는 항상 false를 반환
equlas
메소드를 정의하고 있습니다. 이것은 객체가 자신과 등가가 아닌 것을 의미하고,이 클래스의 유용한 Map과 Set을 만들 수 없습니다. 보다 근본적으로,equals
메소드의 요구 사항 중 하나 인 반사를 충족하지 않는 것입니다.아마 의도 된 것은 객체는 자신과 동일하다는 개체 동일성입니다. 이것은
Object
클래스에서 상속되는 동작입니다. 다른 수퍼 클래스에서 상속 된equals
메서드를 재정의 할 필요가 있다면 다음과 같은 코드를 사용할 수 있습니다.public boolean equals (Object o) { return this == o; }
Eq : equals 메소드는 항상 true를 반환 (EQ_ALWAYS_TRUE)
이 클래스는 항상 true를 반환
equals
메소드를 정의하고 있습니다. 이것은 기발한하지만 그다지 좋은 방법이 아닙니다. 또한,equals
메소드가 대칭이 없다는 것을 의미합니다.Eq : equals 메소드는 클래스 객체가 아닌 클래스 이름을 비교하고있다 (EQ_COMPARING_CLASS_NAMES)
이 메서드는 클래스 이름을 비교하여 두 개체가 동일한 클래스인지 확인합니다. 다른 클래스 로더에 의해로드 된 클래스라면 같은 이름으로 다른 클래스가있을 수 있습니다. 클래스 객체가 같은인지 확인하십시오.
Eq 열거 형은 공변 인 equals 메소드를 정의하고있다 (EQ_DONT_DEFINE_EQUALS_FOR_ENUM)
이 클래스는 열거를 정의하고 열거 동등성는 객체 동일성을 사용하여 정의되어 있습니다. 열거 값에 대한 공변 인
equals
메소드를 정의하는 것은 끔찍한 나쁜 사례입니다. 두 가지 열거 값이equals
메소드는 "등가가 없다"고 판정되어 공변 인equals
메소드에서는 「등가」으로 판정되기 때문입니다. 공변 인equals
메소드를 정의하지 마십시오.Eq : equals (Object) 메소드를 오버라이드 (override)하지 않는 equals 메소드의 정의 (EQ_OTHER_NO_OBJECT)
이 클래스는
equals
메소드를 정의하고 있습니다 만,java.lang.Object
클래스의equals (Object)
메서드를 재정의하지 않습니다. 대신 수퍼 클래스에서equals (Object)
메소드를 상속하여boolean equals (Object)
메소드를 정의해야합니다.Eq : Object.equals (Object)를 오버라이드 (override)하지 않는 equals 메소드의 정의 (EQ_OTHER_USE_OBJECT)
이 클래스는
equals
메소드를 정의하고 있습니다 만,java.lang.Object
클래스의equals (Object)
메서드를 재정의하지 않습니다. 클래스는boolean equals (Object)
메소드를 정의해야합니다.Eq : equals 메소드는 슈퍼 클래스의 equals 메서드를 재정의하고 있지만, 대칭 않을지도 모른다 (EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC)
이 클래스는 슈퍼 클래스의
equals
메서드를 재정의하는equals
메소드를 정의하고 있습니다. 두equals
메소드는 두 객체가 동일한 지 여부의 판정에서instanceof
를 사용하고 있습니다.equals
메소드는 대칭 적 (a.equals (b) == b.equals (a)
) 인 것이 중요하기 때문에 이것은 위험을 수반합니다. B 가 A 의 하위 유형 인 A 의equals
메소드는 인수가instanceof A
인지 확인합니다. 그리고 B 의equals
메소드는 인수가instanceof B
인지 확인합니다. 이러한 메소드에 의해 정의 된 동치 관계가 대칭이 아니라는 것입니다.Eq : 공변 인 equals 메소드를 정의하여 Object.equals (Object)를 계승하고있다 (EQ_SELF_USE_OBJECT)
이 클래스는 공변의
equals
메소드를 정의하고 있습니다 만,equals (Object)
메소드는java.lang.Object
클래스에서 상속하고 있습니다. 클래스는boolean equals (Object)
메소드를 정의해야합니다.FE : NaN의 등가성을위한 절망적 인 테스트 (FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER)
이 코드는 부동 소수점이 특별한 비 수치와 같은지 확인합니다 (예를 들어
if (x == Double.NaN)
). 그러나NaN
의 특별한 의미에 대한 값은NaN
과 등가가 없습니다. 따라서x == Double.NaN
는 항상 false로 평가합니다.x
값이 특별한 비 숫자인지 확인하기 위하여는Double.isNaN (x)
를 사용합니다 (또는x
가 부동 소수점 정밀도이라면Float.isNaN (x)
).FS : 서식 지시자에 전달하는 인수에 호환되지 않는 (VA_FORMAT_STRING_BAD_ARGUMENT)
서식 지시자는 해당 인수와 호환성이 없습니다. 예를 들어
System.out.println ( "% d \ n", "hello");
% d 서식 지시자는 숫자 인수를 필요로하지만 숫자가 아닌 문자열이 전달됩니다. 이 문장이 실행되면 실행시 예외가 발생합니다.FS : 주어진 인수의 형태는 서식 지시자에 일치하지 않습니다 (VA_FORMAT_STRING_BAD_CONVERSION)
인수 중 하나는 해당 서식 지시자와 호환되지 않습니다. 결과적으로 실행될 때 런타임 예외를 생성합니다. 예를 들어,
String.format ( "% d", "1")
는 문자열 "1"이 서식 지시자 "% d"와 호환이 없기 때문에 예외를 생성합니다.FS : printf 스타일의 서식이 예상되는 곳에 MessageFormat이 주어집니다 (VA_FORMAT_STRING_EXPECTED_MESSAGE_FORMAT_SUPPLIED)
Java의 printf 서식 캐릭터 라인과 인수 목록을 기대하는 메소드가 불려 있습니다. 그러나 서식 캐릭터 라인에는 어떤 서식 지시자 (예를 들어, % s)도 포함하지 않고 메시지 포맷 요소 (예 : {0})가 포함되어 있습니다.printf 스타일의 포맷 문자열이 필요한 때 MessageFormat 문자열을주고있을 가능성이 높습니다. 실행시에 모든 인수는 무시되고 서식 캐릭터 라인은 정확하게 포맷되지 않고 반환됩니다.
FS : 서식 문자열에서 실제로 사용되는보다 많은 인수가 전달되는 (VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED)
가변 인자에 의한 서식 문자열 메소드가 불려 있지만 서식 문자열에서 실제로 사용되는 더 인수를 전달하고 있습니다. 이것은 실행시 예외의 원인이되지 않지만 코드는 포맷 된 문자열에 포함되는 것을 의도 한 정보를 조용히 생략하고 있을지도 모릅니다.
FS : 잘못된 형식 문자열 (VA_FORMAT_STRING_ILLEGAL)
서식 문자열은 구문 적으로 무효입니다. 이 문장이 실행되면 실행시 예외가 발생합니다.
FS : 서식 문자열은 부족한 인수를 참조하는 (VA_FORMAT_STRING_MISSING_ARGUMENT)
서식 문자열로 서식 지시자를 충족하기 위해 충분한 인수가 전달되지 않습니다. 이 문장이 실행되면 실행시 예외가 발생합니다.
FS : 서식 문자열위한 이전 인수가없는 (VA_FORMAT_STRING_NO_PREVIOUS_ARGUMENT)
이 형식 문자열은 이전의 서식 지시자의 인수가 재사용되도록하기 위해 "상대 인덱스 ("< ")"를 지정하고 있습니다. 그러나 이전 인수가 없습니다. 예를 들어,
formatter.format ( "% <s % s", "a", "b")
가 실행되면 MissingFormatArgumentException가 발생합니다.GC : 형식 매개 변수와 메소드 인수 무관 (GC_UNRELATED_TYPES)
범용 형 컬렉션 메서드 호출 컬렉션의 매개 변수와 호환되지 않는 클래스 인수가 있습니다 (즉, 인수의 형태는 일반 유형 인수에 대응하는 슈퍼 타입에서도 하위 유형도 없습니다). 따라서 컬렉션은 여기에서 사용 된 메소드 인수와 동일하다 어떤 개체도 포함되어 있지 않습니다. 아마 잘못된 값이 메소드에게 건네진 있습니다. 일반적으로 2 개의 비 관련 클래스의 인스턴스는 등가가 없습니다. 예를 들어,
Foo
와Bar
클래스가 하위 유형에 관계가 없다면Foo
인스턴스는Bar
의 인스턴스와 등가의 리가 없습니다. 기타 문제 대칭 않는equals
메소드가 될 가능성이 높습니다. 예를 들어,Foo
가String
과 동일하다 같이Foo
클래스를 정의한다면,String
는String
만과 등가이기 때문에,equals
메소드는 대칭이 없습니다.드물게 비대칭
equals
메소드를 정의하여 아직 어떻게 든 그 코드를 작동시키고 있습니다. API 아무도 문서화되지 않았거나 보증도하지 않지만,Collection <String>
에Foo
가 있는지 확인하고 싶다면, 인수의equals
메소드 (예를 들어,Foo
클래스의equals
메소드)를 사용하여 동등성을 체크합니다.HE : 해시 된 상황에서 해시 수없는 클래스의 사용이 서명으로 선언 된 (HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS)
메소드, 필드, 클래스는 해시 가능한 클래스가 필요한 상황에서 해시 수없는 클래스가 사용되는 범용적인 서명을 선언하고 있습니다. 클래스는
equals
메소드를 선언하고 있습니다 만,hashCode
메소드는java.lang.Object
에서 상속 있습니다. 이것은 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 따르지 않기 때문에 해시 수 없습니다.HE : 해시 데이터 구조로 hashCode 메소드가없는 클래스를 사용하는 (HE_USE_OF_UNHASHABLE_CLASS)
이 클래스는
equals (Object)
메소드를 정의하고 있습니다 만,hashCode
메소드를 정의하지 않습니다. 이것은 「등가 인 객체는 등가 인 해시 코드를 보관 유지할 필요가있다 "는hashCode
메소드의 범용 규약을 따르지 않습니다. 이 클래스의 인스턴스는 해시 데이터 구조에서 사용되고 있습니다. 가장 중요한 문제를 해결해야합니다.ICAST : int 값을 long으로 변환하여 절대 시간으로 사용하고있다 (ICAST_INT_2_LONG_AS_INSTANT)
이 코드는 32 비트 int 값을 64 비트 long 값으로 변환하여 절대 시간 값을 필요로하는 메소드 매개 변수로 전달합니다. 절대 시간 값은 「신기원」(즉, 1970 년 1 월 1 일, 00 : 00 : 00 GMT)로 알려진 표준 기준 시간에서 밀리 초입니다.
예를 들어, 다음의 메소드 (신기원으로부터의 초를 Date로 변환하는 것을 의도 한)은 심하게 손상되었습니다.Date getDate (int seconds) {return new Date (seconds * 1000);}
곱셈은 32 비트 연산을 사용하여 64 비트 값으로 변환됩니다. 32 비트 값은 64 비트로 변환되어 절대 시간 값을 나타내는 데 사용 될 때, 1969 년 12 월과 1970 년 1 월의 날짜 밖에 표현할 수 없습니다.
위의 방법의 올바른 구현은 다음과 같습니다.
// 실패, 2037 년 이후의 날짜 Date getDate (int seconds) {return new Date (seconds * 1000L);} // 더 나은 모든 날짜에서 작동 Date getDate (long seconds) {return new Date (seconds * 1000);}
ICAST : 정수 값을 double로 캐스팅 Math.ceil ()에 전달 (ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL)
이 코드는 정수 (예 : int 또는 long)를 배정 밀도 부동 소수점으로 변환하고 그 결과를
Math.ceil ()
에 전달하고 있습니다. 정수를 double로 변환하면 소수 부분이없는 수치를 얻을 수 있으므로,이 연산은 항상 no-op입니다.Math.ceil ()
에 전달 된 값을 생성하는 연산이 배정 밀도 부동 소수점 연산을 사용하여 실행하는 것을 의도 한 가능성이 높습니다.ICAST : 정수 값을 float에 캐스트 해 Math.round ()에 전달 (ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND)
이 코드는 정수 값을 float 정밀도 부동 소수점으로 변환하고 그 결과를
Math.round ()
에 전달 인수에 가장 가까운 int / long를 돌려줍니다. 정수를 float로 변환하면 소수 부분이없는 수치를 얻을 수 있으므로,이 연산은 항상 no-op입니다.Math.round ()
에 전달 된 값을 생성하는 연산이 부동 소수점 연산을 사용하여 실행하는 것을 의도 한 가능성이 높습니다.IJU : run 메소드에서 JUnit 주장은 JUnit에서보고되지 않은 (IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD)
run
메소드에서 JUnit assertion가 실행되고 있습니다. 실패한 JUnit 주장은 예외를 throw합니다. 따라서,이 예외가 테스트 메소드를 실행 한 스레드가 아닌 스레드에서 발생한다면, 예외는 스레드를 종료하지만, 테스트 실패가 없습니다.IJU : TestCase는 suite 메소드의 잘못된 선언을하고있다 (IJU_BAD_SUITE_METHOD)
JUnit의 TestCase 클래스에서
suite
메소드를 구현하고 있습니다. 그러나suite
방법은public static junit.framework.Test suite ()
또는
public static junit.framework.TestSuite suite ()
중 하나를 선언해야합니다.
IJU : TestCase는 시험이 없다 (IJU_NO_TESTS)
JUnit의 TestCase 클래스에서 어떤 테스트 메소드를 구현하지 않습니다.
IJU : TestCase는 super.setup ()를 호출하지 setUp 메소드를 구현하고있는 (IJU_SETUP_NO_SUPER)
JUnit의 TestCase 클래스에서
setUp
메소드를 구현하고 있습니다.setUp
메소드는super.setUp ()
를 호출해야하는데 그렇게하지 않습니다.IJU : TestCase는 비 static 인 suite 메소드를 구현하고있는 (IJU_SUITE_NOT_STATIC)
JUnit의 TestCase 클래스에서
suite
메소드를 구현하고 있습니다.suite
메소드는 static으로 선언해야하는데 그렇게하지 않습니다.IJU : TestCase는 super.tearDown ()를 호출하지 tearDown 메소드를 구현하고있는 (IJU_TEARDOWN_NO_SUPER)
JUnit의 TestCase 클래스에서
tearDown
메소드를 구현하고 있습니다.tearDown
메소드는super.tearDown ()
를 호출해야하는데 그렇게하지 않습니다.IL : 컬렉션 자신을 추가하고 (IL_CONTAINER_ADDED_TO_ITSELF)
컬렉션은 자신을 추가하고 있습니다. 그 결과, hashCode를 계산하면
StackOverflowException
를 throw합니다.IL : 명백한 무한 루프 (IL_INFINITE_LOOP)
이 루프는 예외를 throw하는 이외의 방법으로 종료 할 수 없다고 생각합니다.
IL : 명백한 무한 재귀 루프 (IL_INFINITE_RECURSIVE_LOOP)
이 방법은 무조건 자신을 호출합니다. 이것은 스택 오버플로되는 무한 재귀 루프를 보여줍니다.
IM : 정수 잉여의 결과 정수 곱셈 (IM_MULTIPLYING_RESULT_OF_IREM)
이 코드는 정수 잉여의 결과에 정수를 곱합니다. 혼란 연산자의 우선 순위가 없음을 보장합니다. 예를 들어, i % 60 * 1000은 i % (60 * 1000) 대신 (i % 60) * 1000입니다.
INT : int 값과 long 정수와의 잘못된 비교 (INT_BAD_COMPARISON_WITH_INT_VALUE)
이 코드는 int 값과 int 값으로 표현되는 값의 범위를 벗어난 long 정수를 비교하고 있습니다. 이 비교는 무의미 아마도 잘못된 있습니다.
INT : 부가 아닌 값과 음의 정수 또는 제로의 잘못된 비교 (INT_BAD_COMPARISON_WITH_NONNEGATIVE_VALUE)
이 코드는 음수가 아닌 것이 보증되는 값과 음의 정수 또는 0과 비교하고 있습니다.
INT : 부호있는 바이트의 잘못된 비교 (INT_BAD_COMPARISON_WITH_SIGNED_BYTE)
부호있는 바이트 취할 수있는 값의 범위는 -128 ~ 127입니다. 그 범위 밖에서 부호있는 바이트를 값과 비교하는 것은 무의미 잘못 있다고합니다. 부호있는 바이트
b
범위가 0 ~ 255의 부호없는 바이트로 변환하려면0xff & b
를 사용하십시오.IO : 객체 출력 스트림에 추가 무산 (IO_APPENDING_TO_OBJECT_OUTPUT_STREAM)
이 코드는 파일을 추가 모드로 열려 객체 출력 스트림에서 결과를 랩하고 있습니다. 이것은 파일에 저장된 기존의 객체 출력 스트림에 추가 할 수없는 것입니다. 객체 출력 스트림에 추가하고 싶다면, 객체 출력 스트림을 열어 둘 필요가 있습니다.
추가 모드에서 파일을 열고 객체 출력 스트림에 쓸 수있는 유일한 상황은 파일을 읽을 때 랜덤 액세스 모드로 열고 추가를 시작하는 데까지 바이트 오프셋을 추구하고 계획하는 경우입니다.
IP : 메소드로 읽어 않고 덮어되는 매개 변수 (IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN)
이 매개 변수의 초기 값은 무시되고 여기에 덮어 쓰기되어 있습니다. 이것은 종종 매개 변수에 쓰기가 호출자에게 리턴된다는 잘못된 생각을 보여줍니다.
MF : 슈퍼 클래스의 필드 숨기기 필드를 정의하고있는 클래스 (MF_CLASS_MASKS_FIELD)
이 클래스는 슈퍼 클래스의 가시 인스턴스 필드와 같은 이름으로 필드를 정의하고 있습니다. 이것은 혼란스럽고 방법이 필드를 업데이트하거나 액세스한다면 실수를 지적 할지도 모릅니다.
MF : 필드 숨기기 변수를 정의하는 방법 (MF_METHOD_MASKS_FIELD)
이 메서드는이 클래스 또는 수퍼 클래스의 필드와 동일한 이름으로 로컬 변수를 정의하고 있습니다. 필드에서 초기화되지 않은 값을 읽어 초기화되지 않은 필드를 그대로 유지하거나 모두를 일으키는 원인이 될지도 모릅니다.
NP : null 값을 이용하고있다 (NP_ALWAYS_NULL)
여기에서 null 값을 이용하려고하고 있습니다. 코드가 실행될 때 NullPointerException이 발생합니다.
NP : null 값을 예외 경로로 이용하고있다 (NP_ALWAYS_NULL_EXCEPTION)
예외 경로상의 여기서 null 값을 이용하고 있습니다. 코드가 실행될 때 NullPointerException이 발생합니다. 현재 FindBugs는 실행 불가능한 예외 경로를 거두어 있지 않기 때문에, 가양지도 모른다주의하십시오.
switch 문 default가 종종 실행 불가능하므로 FindBugs가 예외 경로 인 default를 검토하는 것에주의하십시오.
NP : null 인수를 체크하지 않은 메소드 (NP_ARGUMENT_MIGHT_BE_NULL)
이 메서드에 매개 변수가 null인지 확인하기 위하여 항상 검사되어야 값으로 특정되었습니다. 그러나 null 체크를하지 않고 null 값이 이용되고 있습니다.
NP : 항상 null 값의 객체로 close 메소드를 호출하는 (NP_CLOSING_NULL)
close
메소드는 항상 null 값의 객체로 불려 있습니다. 이 문장이 실행된다면 NullPointerException이 발생합니다. 여기에서 청산해야 뭔가를 결코 청산하지 않는다는 큰 위험이 있습니다.NP : null 값을 이용하는 것이 보증되는 (NP_GUARANTEED_DEREF)
문장 또는 분기가 실행된다면 이때 값은 null이며, null 값을 이용하는 (포워드 경로에서 실행시 예외를 수반하는 것 이외는) 것이 보증되어 있습니다.
또한
if (x == null) throw new NullPointerException ();
는x
의 참조 해제로 처리된다는 점에 유의하십시오.NP : null 값을 예외 경로로 이용하는 것이 보증되는 (NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH)
예외 경로상의 문장 또는 분기가 실행된다면 이때 값은 null이며, null 값을 이용한다 (포워드 경로에서 실행시 예외를 수반하는 것 이외는) 것이 보증되어 있습니다.
NP : 비 null 필드는 초기화되지 않은 (NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)
필드는 null이 아닌 것으로 표시되어 있지만 생성자에서 기록되지 않습니다. 필드 생성자 동안 다른 위치에서 초기화하거나 사용하기 전에 항상 초기화 될지도 모릅니다.
NP : 메소드 호출은 null이 아닌 매개 변수에 null을 전달하는 (NP_NONNULL_PARAM_VIOLATION)
이 메서드는 비 null이어야한다 메소드의 파라미터로 null 값을 전달하고 있습니다. 이 매개 변수는 @ Nonnull으로 명시 적으로 주석되어했거나 해석이 항상 null 값을 이용한다고 표시했습니다.
NP : null를 돌려지도 모른다 메소드가 @Nonnull 선언 된 (NP_NONNULL_RETURN_VIOLATION)
이 메서드는 null 값을 반환지도 모르다 메소드 (또는 슈퍼 클래스의 메소드)의 반환 값에 @Nonnull가 선언되고 있습니다.
NP : null 것으로 알려진 값을 해당 유형의 인스턴스인지 확인하고있다 (NP_NULL_INSTANCEOF)
체크 된 값이 null이 보장되어 있기 때문에 instanceof는 항상 faluse를 돌려줍니다. 이것은 안전하고 오해와 논리적 오류를 지적하고 있지 않은지 확인하십시오.
NP : null 값을 이용하고있는 가능성이있다 (NP_NULL_ON_SOME_PATH)
따라서 분기 또는 문장이 실행된다면 null 값이 이용되고 NullPointerException이 발생합니다. 물론 문제는 분기 또는 문장이 실행 불가능하고, NullPointerException가 결코 발생할 수 없다는 것일지도 모릅니다. 그것을 결정하는 것은 FindBugs의 능력을 초과하고 있습니다.
NP : null 값을 예외 경로로 이용하고있는 가능성이있다 (NP_NULL_ON_SOME_PATH_EXCEPTION)
예외 경로상의 여기서 null 값이 이용되고 있습니다. 코드가 실행될 때 NullPointerException이 발생할 수 있습니다. 현재 FindBugs는 실행 불가능한 예외 경로를 거두어 있지 않기 때문에, 가양지도 모른다주의하십시오.
switch 문 default가 종종 실행 불가능하므로 FindBugs가 예외 경로 인 default를 검토하는 것에주의하십시오.
NP : 메소드 호출은 null이 아닌 매개 변수에 null을 전달하는 (NP_NULL_PARAM_DEREF)
이 메소드 호출은 null이 아닌 메소드 파라미터에 null 값을 전달하고 있습니다. 매개 변수는 항상 비 null로 할 파라미터로 주석되어했거나 해석이 항상 null 값을 이용한다고 표시했습니다.
NP : 메소드 호출은 null이 아닌 매개 변수에 null을 전달하는 (NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS)
알려진 모든 대상 메소드가 null이 아니라는 것을 매개 변수에 요구하는 호출 장소에서 아마도 null 값을 전달하고 있습니다. 매개 변수는 항상 비 null로 할 파라미터로 주석되어했거나 해석이 항상 null 값을 이용한다고 표시했습니다.
NP : 비 null 파라미터에 null를 건네 비 가상 메소드 호출 (NP_NULL_PARAM_DEREF_NONVIRTUAL)
null의 가능성이있는 값이 null이 아닌 메소드 매개 변수로 전달됩니다. 매개 변수는 항상 비 null로 할 파라미터로 주석되어했거나 해석이 항상 null 값을 이용한다고 표시했습니다.
NP : Optional의 귀가 형태를 가지는 메소드가 명시 적으로 null을 반환 (NP_OPTIONAL_RETURN_NULL)
Optional 리턴 형 사용은 항상 명시 적으로 null를 돌려주는 것은 설계가 원하지 않는 것을 의미합니다. null 값이 같은 경우 반환은 계약 위반, 아마 클라이언트 코드를 파괴하는 것입니다.
NP : @Nonnull에서 주석 된 필드에 null을 포함하고있는 (NP_STORE_INTO_NONNULL_FIELD)
@Nonnull로 주석 된 필드에 null 할지도 모른다 값을 포함하고 있습니다.
NP : 기록되지 않은 필드의 읽기 (NP_UNWRITTEN_FIELD)
프로그램은 결코 null이 아닌 값을 쓸 생각되지 않는 필드의 값을 이용하고 있습니다. 이 값을 이용하면 NullPointerException이 발생합니다.
Nm : 클래스는 equal (Object)를 정의하고 있습니다. equals (Object)에해야하나요? (NM_BAD_EQUAL)
이 클래스는
equal (Object)
라는 메소드를 정의하고 있습니다. 이 메소드는java.lang.Object
의equals (Object)
을 (아마도 의도적으로) 대체하지 않습니다.Nm : 클래스는 hashcode ()를 정의하고 있습니다. hashCode ()를 사용해야하나요? (NM_LCASE_HASHCODE)
이 클래스는
hashcode ()
라는 메소드를 정의하고 있습니다. 이 메소드는java.lang.Object
의hashCode
메소드를 (아마도 의도적으로) 대체하지 않습니다.Nm : 클래스는 tostring ()를 정의하고 있습니다. toString ()에해야하나요? (NM_LCASE_TOSTRING)
이 클래스는
tostring ()
라는 메소드를 정의하고 있습니다. 이 메소드는java.lang.Object
의toString
메소드를 (아마도 의도적으로) 대체하지 않습니다.Nm : 명백한 메소드와 생성자의 혼란 (NM_METHOD_CONSTRUCTOR_CONFUSION)
이 정규 메소드는 정의하고있는 클래스와 같은 이름입니다. 이것은 생성자를 의도했을 가능성이 높습니다. 그렇다면 void 반환 선언을 제거하십시오. 우연히 메소드를 정의한 것이 실수라고 알 적절한 생성자를 정의했지만, 하위 호환성을 위해서이 메소드를 제거 할 수 없다면 메소드를 비추천으로합니다.
Nm : 매우 혼란 이름의 메소드 (NM_VERY_CONFUSING)
참조 된 메서드는 대문자 사용을 통해서만 다른 이름이 있습니다. 대문자 사용법이 동일하면 메소드 중 하나가 다른 메서드를 재정의하기 때문에 매우 혼란입니다.
Nm : 매개 변수의 잘못된 패키지 위해서 슈퍼 클래스의 메소드를 오버라이드 (override)하지 않는 방법 (NM_WRONG_PACKAGE)
파라미터의 형태가 슈퍼 클래스에 대응하는 파라미터의 형태와 정확하게 일치하지 않기 때문에, 서브 클래스의 메소드는 슈퍼 클래스의 유사한 메서드를 재정의하지 않습니다.
예를 들어 다음과 같은 코드입니다.import alpha.Foo; public class A { public int f (Foo x) {return 17;} } ---- import beta.Foo; public class B extends A { public int f (Foo x) {return 42;} }
클래스
B
에 정의 된f (Foo)
메소드는 클래스A
의f (Foo)
메소드를 오버라이드 (override)하지 않습니다. 이것은 인수의 형태Foo
가 다른 패키지이기 때문입니다.QBA : 논리식에서 boolean 리터럴 값을 할당하는 방법 (QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT)
이 방법은 if 나 while 표현식에서의 boolean 변수 boolean 리터럴 값 (true 또는 false)를 지정하고 있습니다. 아마도 이것은 = 의한 할당이 아닌 ==를 사용하여 논리 비교를하게되어있었습니다.
RANGE : 배열 인덱스가 범위를 벗어 (RANGE_ARRAY_INDEX)
배열 연산이 행해지고 있지만 배열 인덱스가 범위 외이므로 실행시 ArrayIndexOutOfBoundsException이 발생하는 것입니다.
RANGE : 배열의 길이가 범위를 벗어 (RANGE_ARRAY_LENGTH)
메서드는 배열 매개 변수와 길이 매개 변수로 불려 있지만 길이는 다루지 않습니다. 실행시 IndexOutOfBoundsException이 발생하는 것입니다.
RANGE : 배열 오프셋 범위 외 (RANGE_ARRAY_OFFSET)
메서드는 배열 매개 변수와 오프셋 파라미터로 호출되지만, 오프셋은 다루지 않습니다. 실행시 IndexOutOfBoundsException이 발생하는 것입니다.
RANGE : 문자열 인덱스는 범위 외 (RANGE_STRING_INDEX)
문자열 메소드가 불려갑니다. 지정된 문자열 인덱스는 범위 외입니다. 실행시 StringIndexOutOfBoundsException이 발생하는 것입니다.
RC : 의심 참조 비교 (RC_REF_COMPARISON)
이 방법은 == 또는! = 연산자를 사용하여 두 개의 참조 값을 비교하고 있습니다. 일반적으로이 형식의 인스턴스를 비교하는 올바른 방법은
equals
메소드입니다. 등가 식별 가능한 인스턴스를 만들 수 있지만 다른 개체이므로 ==로 비교하지 마십시오. 참조에 의해 일반적으로 비교 안된다 클래스의 예는java.lang.Integer
,java.lang.Float
등입니다.RCN : 이미 사용하고 있던 값의 null 체크 (RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE)
여기에서 값이 null인지 체크하고 있습니다 만, 이미 값을 이용했기 때문에 null 일 수는 없습니다. 값이 null이라면 이전의 이용에 NullPointerException이 발생했던 것입니다. 기본적으로 값이 null 인 것을 허락 여부에 관계없이이 코드와 이전 값의 이용은 일치하지 않습니다. 검사가 중복되거나 이전 값의 이용은 잘못된 것입니다.
RE : 정규식에 대한 잘못된 구문 (RE_BAD_SYNTAX_FOR_REGULAR_EXPRESSION)
이 코드는 정규식 구문에 따르면 무효 인 정규식을 사용하고 있습니다. 이 문장이 실행될 때 PatternSyntaxException를 슬로우합니다.
RE : 정규식을 위해 사용되는 File.separator (RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION)
이 코드는 정규식이 필요한 장소에서
File.separator
을 사용하고 있습니다. 이것은File.separator
가 백 슬래시 인 Windows 플랫폼에서는 실패합니다. 백 슬래시는 정규 표현식에서 이스케이프 문자로 해석됩니다. 다른 방법으로는File.separator
대신File.separatorChar == '\\'? "\\\\": File.separator
를 사용할 수 있습니다.RE : 정규식을 위해 사용되고있다 "."또는 "|"(RE_POSSIBLE_UNINTENDED_PATTERN)
String 함수를 호출 해 "."또는 "|"이 인수로 정규 표현식을 가지고 매개 변수로 전달됩니다. 이것은 의도 한 것입니까? 예
s.replaceAll ( ".", "/")
는 모든 문자가 '/'문자로 치환 된 String을 반환s.split ( ".")
는 항상 길이가 0 인 String 배열을 반환"ab | cd".replaceAll ( "|", "/")
는"/ a / b / | / c / d /"
를 반환"ab | cd".split ( "|")
는 6 개의 요소가있는 배열을 반환 :[a, b, |, c, d]
RV : 0에서 1의 난수 값은 정수 값 0으로 반올림 (RV_01_TO_INT)
0에서 1의 난수 값은 정수 값 0으로 반올림됩니다. 아마 정수로 반올림 전에 다른하여 난수를 배수하고 싶었거나
Random.nextInt (n)
메소드를 사용 싶었던 것입니다.RV : 부호있는 32 비트 해시 코드의 절대 값을 계산하는 잘못된 시도 (RV_ABSOLUTE_VALUE_OF_HASHCODE)
이 코드는 해시 코드를 생성하여 절대 값을 계산하고 있습니다. 해시 코드가
Integer.MIN_VALUE
이라면 결과는 마찬가지로 음입니다 (Math.abs (Integer.MIN_VALUE) == Integer.MIN_VALUE
이므로).문자열 2 ^ 32 개에 1 개는
Integer.MIN_VALUE
의 해시 코드를 가지고 있고, "polygenelubricants", "GydZG _", "DESIGNING WORKHOUSES"이 적용됩니다.RV : 부호있는 정수 난수의 절대 값을 계산하는 잘못된 시도 (RV_ABSOLUTE_VALUE_OF_RANDOM_INT)
이 코드는 부호있는 정수 난수를 생성하여 절대 값을 계산하고 있습니다. 난수 생성기에서 반환되는 숫자가
Integer.MIN_VALUE
이라면 결과는 마찬가지로 음입니다 (Math.abs (Integer.MIN_VALUE) == Integer.MIN_VALUE
이므로). (같은 문제는 long 값에서도 마찬가지로 일어나고 있습니다.)RV : compareTo 의해 반환 된 특정 값 코드 확인 (RV_CHECK_COMPARETO_FOR_SPECIFIC_RETURN_VALUE)
이 코드는 compareTo 또는 compare 메소드를 호출하여 반환 값이 특정 값 (예 : 1 또는 -1)인지 확인합니다. 이러한 메소드를 호출 할 때 특정 0이 아닌 값이 아니라 결과의 부호만을 체크해야합니다. 다수 또는 대부분의 compareTo와 비교 메소드는 -1 또는 1을 반환하지만, 일부는 다른 값을 반환합니다.
RV : 만든 예외를 슬로우하는 것이 아니라 버리고있다 (RV_EXCEPTION_NOT_THROWN)
이 코드는 예외 또는 오류 객체를 생성하고 있습니다 만, 아무것도하지 않습니다.
예를 들어 다음과 같은 코드입니다.if (x <0) { new IllegalArgumentException ( "x must be nonnegative"); }
아마 프로그래머의 의도는 만든 예외를 슬로우하는 것이 었습니다.
if (x <0) { throw new IllegalArgumentException ( "x must be nonnegative"); }
RV : 반환 값을 무시하는 방법 (RV_RETURN_VALUE_IGNORED)
이 메소드의 반환 값은 체크해야합니다. 이 경고의 일반적인 원인은 객체가 업데이트된다고 생각하고 불변 객체의 메소드를 호출하는 것입니다.
예를 들어 다음과 같은 코드입니다.String dateString = getHeaderField (name); dateString.trim ();
프로그래머는
trim
메소드가dateString
의해 참조되는 String 객체가 업데이트된다고 생각하고 있습니다. 그러나 String 객체는 불변으로trim
메소드가 새로운 String 객체를 반환 무시하고 있습니다. 이 코드는 다음과 같이 수정해야합니다.String dateString = getHeaderField (name); dateString = dateString.trim ();
RpC : 조건 테스트의 반복 (RpC_REPEATED_CONDITIONAL_TEST)
이 코드는 조건 테스트가 두 번, 즉 첫 번째 조건 테스트가 올바른 경우 두 번째 조건 테스트가 실행됩니다 (예를 들어,
x == 0 || x == 0
) 아마 두 번째 조건 테스트는 다른 것을 의도하고 있습니다 (예를 들어,x == 0 || y == 0
)SA : 필드의 자동 할당 (SA_FIELD_SELF_ASSIGNMENT)
이 메소드는 필드의 자기 대입 있습니다.
예를 들어 다음과 같은 코드입니다.int x; public void foo () { x = x; }
그런 대입 쓸모 없기 때문에, 논리적 오류 또는 오타지도 모릅니다.
SA : 필드와 자신과 자기 비교 (SA_FIELD_SELF_COMPARISON)
이 메서드는 필드를 자체적으로 비교합니다. 논리 오류 또는 오타지도 모릅니다. 올바른 비교하고 있는지 확인하십시오.
SA : 필드의 의미 자체 연산 (예를 들어, x & x) (SA_FIELD_SELF_COMPUTATION)
이 방법은 필드와 같은 필드에 다른 참조가 무의미한 계산을 수행하고 있습니다 (예를 들어, x & x 또는 x - x). 이 계산의 특성으로 인해 연산은 의미를 가진다는 생각되지 않기 때문에, 논리적 오류 또는 오타지도 모릅니다. 계산을 확인하십시오.
SA : 필드에 대입이 아닌 로컬 변수에 자기 대입 (SA_LOCAL_SELF_ASSIGNMENT_INSTEAD_OF_FIELD)
이 메소드는 로컬 변수의 자기 대입이 로컬 변수 및 필드 같은 이름입니다.
예를 들어 다음과 같은 코드입니다.int foo; public void setFoo (int foo) { foo = foo; }
그런 대입 도움이되지 않습니다. 그렇지 않고 필드에 대입하려고 했습니까?
SA : 로컬 변수와 자신과 자기 비교 (SA_LOCAL_SELF_COMPARISON)
이 메소드는 로컬 변수를 자체적으로 비교합니다. 논리 오류 또는 오타지도 모릅니다. 올바른 비교하고 있는지 확인하십시오.
SA : 변수의 의미 자체 연산 (예를 들어, x & x) (SA_LOCAL_SELF_COMPUTATION)
이 메소드는 로컬 변수와 동일한 변수에 다른 참조가 무의미한 계산을 수행하고 있습니다 (예를 들어, x & x 또는 x - x). 이 계산의 특성으로 인해 연산은 의미를 가진다는 생각되지 않기 때문에, 논리적 오류 또는 오타지도 모릅니다. 계산을 다시 한 번 확인하십시오.
SF : switch 문장 떨어지지을 위해 저장이 사용할 수있는 (SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH)
이전 case에 저장된 값을 switch 문 떨어지지 위해 여기에서 덮어되어 있습니다. 이전 case의 끝에 break 또는 return을 넣는 것을 잊지 가능성이 있습니다.
SF : 던져 switch 문 떨어지지을 위해 저장이 사용할 수있는 (SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW)
이전 case에 저장된 값이 예외가 발생되는 장소에서 switch 문 떨어지지 위해 여기에서 잃어버린 있습니다. 이전 case의 끝에 break 또는 return을 넣는 것을 잊지 가능성이 있습니다.
SIC : 비 static 내부 클래스와 스레드 로컬 교착 상태 (SIC_THREADLOCAL_DEADLY_EMBRACE)
이 클래스는 내부 클래스입니다 만, 아마 static 내부 클래스해야합니다. 실제로 내부 클래스와 외부 클래스의 스레드 로컬 사이에 교착 심각한 위험이 있습니다. 내부 클래스가 static이 아니기 때문에, 외부 클래스에 대한 참조를 유지합니다. 스레드 로컬 내부 클래스 인스턴스의 참조가 있다면, 내부와 외부의 인스턴스 모두가 도달 할 수 가비지되지 않습니다.
SIO : instanceof 연산자를 사용하여 불필요한 유형 검사 (SIO_SUPERFLUOUS_INSTANCEOF)
객체가 요구하는 형식인지 여부에 관계없이 정적으로 판정되는 instanceof 연산자를 사용하여 형식 검사를하고 있습니다.
SQL : 인덱스가 0에서 PreparedStatement에 액세스하려고하고있는 메소드 (SQL_BAD_PREPARED_STATEMENT_ACCESS)
인덱스가 0에서
PreparedStatement
의 setXXX 메소드를 호출합니다. 인덱스는 1부터 시작하기 때문에, 이것은 항상 실수입니다.SQL : 인덱스가 0에서 ResultSet에 액세스하려고하고있는 메소드 (SQL_BAD_RESULTSET_ACCESS)
인덱스가 0에서
ResultSet
의 getXXX, updateXXX 메소드를 호출합니다.ResultSet
의 인덱스는 1부터 시작하기 때문에, 이것은 항상 실수입니다.STI : interrupted 메소드를 호출하는 데 불필요한 currentThread 메소드를 호출하는 (STI_INTERRUPTED_ON_CURRENTTHREAD)
이 메소드는
interrupted
메소드를 호출Thread.currentThread ()
를 호출합니다.interrupted
메소드는 static 메서드이므로Thread.interrupted ()
를 사용하는 편이 간단 명료합니다.STI : 스레드 인스턴스에서 static Thread.interrupted ()를 호출하는 (STI_INTERRUPTED_ON_UNKNOWNTHREAD)
이 메서드는 현재 스레드가 아닌 Thread 객체 인 것처럼 보이는 Thread 객체
Thread.interrupted ()
를 호출합니다.interrupted
메소드는 static이므로, 제작자가 의도 한 것과는 다른 개체에서 호출됩니다.Se : 직렬화기구를 위해 private로해야한다 메소드 (SE_METHOD_MUST_BE_PRIVATE)
이 클래스는
Serializable
인터페이스를 구현하여 사용자 정의 직렬화 / 직렬화 복원을위한 메소드를 정의하고 있습니다. 그러나, 그 메소드가 private로 선언되어 있지 않기 때문에 직렬화 / 직렬화 복원 API에 의해 무시됩니다.Se : readResolve 메소드가 static 메소드로 선언되는 (SE_READ_RESOLVE_IS_STATIC)
readResolve
메소드가 직렬화기구로 인식되기 위해서는 static 메소드로 선언하지 않습니다.TQ : 형식 한정자 주석 된 값이 그 한정자를 부여하지 않은 값을 필요로하는 곳에서 사용되고있다 (TQ_ALWAYS_VALUE_USED_WHERE_NEVER_REQUIRED)
형식 한정자 주석 된 값이 그 한정자를 부여하지 않은 값을 필요로하는 곳에서 사용되고 있습니다.
더 정확하게, when = ALWAYS를 지정된 형식 한정자 주석 된 값이 도달하는 것이 보증되어 있는지 동일한 형식 한정자 when = NEVER을 지정하는 장소에서 사용하고 있습니다.
예를 들어, @ NonNegative는 형식 한정자 주석 @Negative (when = When.NEVER)의 약어합니다. 다음 코드는 return 문이 @NonNegative 값을 요구한다 @Negative로 표시되는 값을 받기 때문에이 경고를 생성합니다.
public @NonNegative Integer example (@Negative Integer value) { return value; }
TQ : 호환되지 않는 형식 한정자에 의한 비교 값 (TQ_COMPARING_VALUES_WITH_INCOMPATIBLE_TYPE_QUALIFIERS)
형식 한정자 주석을 지정한 값이 그 규정되지 않은 값과 비교하고 있습니다.
더 정확하게, when = ALWAYS를 지정된 형식 한정자 주석 된 값이 동일한 형식 한정자 when = NEVER을 지정하는 값과 비교합니다.
예를 들어, @ NonNegative는 형식 한정자 주석 @Negative (when = When.NEVER)의 약어합니다. 다음 코드는 return 문이 @NonNegative 값을 요구한다, @ Negative로 표시되는 값을 받기 때문에이 경고를 생성합니다.
public boolean example (@Negative Integer value1, @NonNegative Integer value2) { return value1.equals (value2); }
TQ : 유형 수정자를 지정하지 않을지도 모른다 값이 해당 형식 한정자를 필요로하는 방식으로 항상 사용되는 (TQ_MAYBE_SOURCE_VALUE_REACHES_ALWAYS_SINK)
형태 수식 자에 의해 표시된 값의 인스턴스가 아닌 잠재적으로 주석 된 값입니다. 값은 그 형태 수식 자에 의해 표시된 값을 필요로하는 방식으로 사용되는 것이 보증되고 있습니다.
TQ : 유형 수정자를 지정하고 있을지도 모른다 값이 해당 형식 한정자를 금지하는 방법으로 항상 사용되는 (TQ_MAYBE_SOURCE_VALUE_REACHES_NEVER_SINK)
형태 수식 자에 의해 표시된 값의 인스턴스 인 잠재적으로 주석 된 값입니다. 값은 그 형태 수식 자에 의해 표시된 값을 금지하는 방법으로 사용되는 것이 보장되어 있습니다.
TQ : 형식 한정자 주석되어 있지 않은 값이 그 수식자가 붙은 값을 필요로하는 곳에서 사용되고있다 (TQ_NEVER_VALUE_USED_WHERE_ALWAYS_REQUIRED)
형식 한정자 주석되어 있지 않은 값이 그 수식자가 붙은 값을 필요로하는 곳에서 사용되고 있습니다.
더 정확하게, when = NEVER을 지정한 형식 한정자 주석 된 값이 동일한 형식 한정자 when = ALWAYS을 지정하는 장소에서 사용하고 있습니다.
TQ : 유형 수정자가없는 값이 한정자를 필요로하는 곳에서 사용되고있다 (TQ_UNKNOWN_VALUE_USED_WHERE_ALWAYS_STRICTLY_REQUIRED)
값이 타입 한정자 주석을 필요로하는 방법으로 사용되고 있습니다. 형식 한정자는 엄격이므로 도구는 적절한 주석을 지정하지 않은 값을 거절합니다.
정확한 주석을 지정하고 있기 때문에 값을 강제 변환합니다. 반환 값이 정확한 주석에 주석되는 동일성 기능을 정의합니다. 이것은 강력한 형식 한정자 주석으로 비 주석 값을 값으로 바꾸는 유일한 방법입니다.
UMAC : 호출 불가능한 메소드가 이름 클래스에 정의되어있는 (UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS)
이 이름 클래스는 직접 불려 가지 않는 슈퍼 클래스 메서드를 재정의하지 않는 메소드를 정의하고 있습니다. 다른 클래스의 메소드가 이름 클래스에서 선언 된 메소드를 직접 호출 할 수 없기 때문에,이 메소드는 호출 불가능하다고 생각됩니다. 메소드는 단지 죽은 코드일지도 모릅니다. 그러나 메소드가 슈퍼 클래스에 선언 된 메서드를 재정의하는 것을 의도했을 가능성도 있습니다. 그리고 오타 또는 다른 오류에 대한 메소드는 실제로 의도하는 메서드를 재정의하지 않습니다.
UR : 생성자에서 초기화되지 않은 필드를 읽는 (UR_UNINIT_READ)
이 생성자는 아직 값이 대입되지 않은 필드를 판독합니다. 종종 프로그래머가 생성자의 매개 변수 대신 실수로 필드를 사용할 때 발생합니다.
UR : 슈퍼 클래스의 생성자에서 호출되는 메서드에서 초기화되지 않은 필드를 읽는 (UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR)
이 메소드는 슈퍼 클래스의 생성자에서 호출되어 있습니다. 이 시점에서는 클래스의 필드는 아직 초기화되어 있지 않습니다.
이것은 많은 구상 클래스를 만들기 때문입니다. 다음 클래스를 검토하십시오.
abstract class A { int hashCode; abstract Object getValue (); A () { hashCode = getValue (). hashCode (); } } class B extends A { Object value; B (Object v) { this.value = v; } Object getValue () { return value; } }
B
가 구축 될 때,B
의 생성자가value
값을 설정하기 전에A
클래스의 생성자가 호출됩니다. 따라서A
의 생성자가getValue
를 호출 할 때value
초기화되지 않은 값을 읽습니다.USELESS_STRING : 이름없는 배열에서 toString 메소드를 호출하는 (DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY)
이 코드는 이름의 배열에서
toString
메소드를 호출합니다. "[C @ 16f0472"같은 꽤 쓸모없는 결과를 생성합니다. 배열의 내용을주고 읽을 문자열로 변환하기 위해Arrays.toString ()
를 사용하는 것을 고려하십시오.
"Programming Puzzlers"제 3 장 퍼즐 12을 참조하십시오.USELESS_STRING : 배열에서 toString 메소드를 호출하는 (DMI_INVOKING_TOSTRING_ON_ARRAY)
이 코드는 배열에서
toString
메소드를 호출합니다. "[C @ 16f0472"같은 꽤 쓸모없는 결과를 생성합니다. 배열의 내용을주고 읽을 문자열로 변환하기 위해Arrays.toString ()
를 사용하는 것을 고려하십시오.
"Programming Puzzlers"제 3 장 퍼즐 12을 참조하십시오.USELESS_STRING : 서식 문자열을 사용하여 쓸모없는 방법으로 배열을 포맷하고있다 (VA_FORMAT_STRING_BAD_CONVERSION_FROM_ARRAY)
서식 문자열로 포맷 된 인수 중 하나는 배열입니다. [I @ 304282 같이 배열의 내용을 표시하지 꽤 쓸모 서식을 사용하여 포맷됩니다. 형식으로 취급하기 전에
Arrays.asList (...)
를 사용하여 배열을 랩하는 것을 고려하십시오.UwF : null로 설정 될뿐만 필드 (UWF_NULL_FIELD)
이 필드 상수 값 null를 기입합니다. 따라서 필드의 읽기는 null를 돌려줍니다. 오류를 확인하십시오. 쓸모 있다면 제거하십시오.
UwF : 기록되지 않은 필드 (UWF_UNWRITTEN_FIELD)
이 필드는 결코 기록되지 않습니다. 이 필드에서의 읽기는 기본값을 반환합니다. 오류를 확인하십시오 (필드는 초기화해야 했습니까?). 쓸모 있다면 제거하십시오.
VA : 가변 인자를 기대하고있는 메소드에 원시 형의 배열을 전달하는 (VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG)
이 코드는 가변 인수를 취하는 메소드에 원시 형의 배열을 전달하고 있습니다. 이것은 원시 형의 배열을 유지하기 위해 길이가 1 인 배열을 만들고 메서드에 전달합니다.
LG : 로거의 변경은 OpenJDK의 약한 참조로 인해 잠재적으로 손실 (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE)
OpenJDK는 잠재적 비 호환성을 도입했습니다. 특히
java.util.logging.Logger
는 동작이 변경되어 있습니다. 강 참조를 사용하는 대신에 약한 참조를 내부적으로 사용하고 있습니다. 그것은 말이 사항이지만, 불행히도 일부 코드는 이전 동작에 의존하고 있습니다. 로거 구성을 변경할 때 로거에 대한 참조를 버립니다. 즉, 가비지 컬렉터는 메모리를 회수 할 수 있습니다. 그것은 로거 구성이 손실되는 것을 의미합니다.
예를 들어, 다음을 고려하십시오.public static void initLogging () throws Exception { Logger logger = Logger.getLogger ( "edu.umd.cs"); logger.addHandler (new FileHandler ()); // 로거 구성 변경 logger.setUseParentHandlers (false); // 다른 로거 구성 변경}
로거의 참조는 메소드의 끝 (메소드는 탈출하지 않습니다)에서 손실되기 때문에
initLogging
호출 후에 가비지 컬렉션의 순환이 있다면, 로거 구성은 손실됩니다 (왜냐하면 Logger는 약 참조를 유지하는 것만 그래서).public static void main (String [] args) throws Exception { initLogging (); // 파일 핸들러를 로거에 추가 System.gc (); // 로거 구성이 손실 Logger.getLogger ( "edu.umd.cs"). info ( "Some message"); // 기대 한대로 파일에 기록되지 않습니다}
Ulf Ochsenfahrt와 Eric Fellheimer
OBL : 스트림과 리소스 정리에 실패 할지도 모른다 메소드 (OBL_UNSATISFIED_OBLIGATION)
이 메서드는 스트림 데이터베이스 객체 또는 정리 작업을 명시 적으로 필요로하는 다른 리소스 정리 (청산하는 정리) 실패 할지도 모릅니다.
일반적으로 메소드가 스트립 및 기타 리소스를 연다면, 메소드는 스트림과 자원이 메소드가 돌아 오기 전에 정리되는 것을 확인하기 위해 try / finally 블록을 사용한다.
이 버그 패턴은 OS_OPEN_STREAM과 ODR_OPEN_DATABASE_RESOURCE과 기본적으로 동일하지만 다른 (그리고 잘하면 더 좋은) 정적 분석 기술을 기반으로합니다. 우리는이 버그 패턴의 유효성에 대한 피드백을 얻는 것에 관심이 있습니다. 두 가지 방법으로 의견을 보내 주시기 바랍니다.
- send email to findbugs@cs.umd.edu
- file a bug report : http://findbugs.sourceforge.net/reportingBugs.html
특히,이 버그 패턴의 오 검출 억제 탐색 법은 상세하게 조정되어 있지 않기 때문에, 오 탐지에 대한 보고서는 우리의 도움이됩니다.
분석 기술의 설명은 Weimer과 Necula에 따르면 Finding and Preventing Run-Time Error Handling Mistakes 를 참조하십시오.
OBL : 체크 예외 스트림과 리소스 정리에 실패 할지도 모른다 메소드 (OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE)
이 메서드는 스트림 데이터베이스 객체 또는 정리 작업을 명시 적 필요로하는 다른 리소스 정리 (청산하는 정리) 실패 할지도 모릅니다.
일반적으로 메소드가 스트립 및 기타 리소스를 연다면, 메소드는 스트림과 자원이 메소드가 돌아 오기 전에 정리되는 것을 확인하기 위해 try / finally 블록을 사용한다.
이 버그 패턴은 OS_OPEN_STREAM과 ODR_OPEN_DATABASE_RESOURCE과 기본적으로 동일하지만 다른 (그리고 잘하면 더 좋은) 정적 분석 기술을 기반으로합니다. 우리는이 버그 패턴의 유효성에 대한 피드백을 얻는 것에 관심이 있습니다. 두 가지 방법으로 의견을 보내 주시기 바랍니다.
- send email to findbugs@cs.umd.edu
- file a bug report : http://findbugs.sourceforge.net/reportingBugs.html
특히,이 버그 패턴의 오 검출 억제 탐색 법은 상세하게 조정되어 있지 않기 때문에, 오 탐지에 대한 보고서는 우리의 도움이됩니다.
분석 기술의 설명은 Weimer과 Necula에 따르면 Finding and Preventing Run-Time Error Handling Mistakes 를 참조하십시오.
Dm : 호출 한 메소드의 Locale 매개 변수의 사용을 고려한다 (DM_CONVERT_CASE)
문자열이 플랫폼의 기본 인코딩을 사용하여 대문자, 소문자로 변환되어 있습니다. 국제 문자로 사용하면 잘못된 변환 할 수 있습니다.
- String.toUpperCase (Locale l)
- String.toLowerCase (Locale l)
Dm : 기본 인코딩에 따라 (DM_DEFAULT_ENCODING)
byte에서 String (또는 String에서 byte)로 변환 할 기본 플랫폼 인코딩이 적절하다고 가정 메서드 호출을 발견했습니다. 이 응용 프로그램의 작동이 플랫폼간에 다른 원인이됩니다. 대체 API를 사용하여 문자 집합 이름 또는 Charset 객체를 명시 적으로 지정하십시오.
DP : doPrivileged 블록 내에서 작성되어야 클래스 로더 (DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED)
이 코드는 클래스 로더를 작성하고 있습니다 만, 보안 관리가 설치된다면 허용이 필요합니다. 이 코드가 보안 권한이없는 코드에서 호출한다면, 클래스 로더의 작성은 doPrivileged 블록에서 수행해야합니다.
DP : doPrivileged 블록 내에서 호출 할 메소드 (DP_DO_INSIDE_DO_PRIVILEGED)
이 코드는 보안 권한 검사가 필요한 메소드를 호출합니다. 이 코드에 보안 권한이 주어진다해도 보안 권한이없는 코드에서 호출한다면 doPrivileged 블록에서 호출해야합니다.
EI : 가변 객체에 대한 참조를 반환하여 내부 표현을 폭로 할지도 모른다 메소드 (EI_EXPOSE_REP)
객체의 필드에 포함 된 가변 객체의 참조를 반환하면 객체의 내부 표현을 노출합니다. 인스턴스가 신뢰할 수없는 코드에 의해 접근된다면, 가변 객체의 체크되지 않은 변경 사항이 보안이나 다른 중요한 속성을 위태롭게 할 것입니다. 뭔가 다른 일을해야합니다. 개체의 새 복사본을 반환 할 많은 상황에서 더 나은 방법입니다.
EI2 : 가변 객체에 대한 참조를 캡처하여 내부 표현을 폭로 할지도 모른다 메소드 (EI_EXPOSE_REP2)
이 코드는 객체의 내부 표현에 외부의 가변 객체의 참조를 포함하고 있습니다. 인스턴스가 신뢰할 수없는 코드에 의해 접근된다면, 가변 객체의 체크되지 않은 변경 사항이 보안이나 다른 중요한 속성을 위태롭게 할 것입니다. 뭔가 다른 일을해야합니다. 개체의 새 복사본을 반환 할 많은 상황에서 더 나은 방법입니다.
FI : 종결자는 public이 아니라 protected로해야 (FI_PUBLIC_SHOULD_BE_PROTECTED)
이 클래스의
finalize
메소드는 public이 아니라 protected로해야합니다.MS : static 필드에 가변 객체를 포함하여 내부 정적 상태를 폭로 할지도 모른다 메소드 (EI_EXPOSE_STATIC_REP2)
이 코드는 static 필드에 외부의 가변 객체를 포함하고 있습니다. 가변 객체의 체크되지 않은 변경 사항이 보안이나 다른 중요한 속성을 위태롭게 할 것입니다. 뭔가 다른 일을해야합니다. 객체의 복사본을 저장하는 것은 많은 상황에서 더 나은 방법입니다.
MS : final이 아닌 필드는 악성 코드로부터 보호 할 수 없다 (MS_CANNOT_BE_FINAL)
이 가변 static 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 불행히도 이런 사용법은 간단하게 해결할 수 없습니다.
MS : 배열을 반환하여 내부 표현을 폭로 할지도 모른다 public static 메소드 (MS_EXPOSE_REP)
public static 메서드는 클래스의 정적 상태의 일부인 배열의 참조를 돌려줍니다. 이 메소드를 호출 어떤 코드도 기본 배열을 자유롭게 변경할 수 있습니다. 해결책은 배열의 복사본을 반환합니다.
MS : final하고 패키지 보안 모드로해야 할 필드 (MS_FINAL_PKGPROTECT)
이 가변 static 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 필드는 취약점을 방지하기 위해 final 및 / 또는 패키지 보안 모드로합니다.
MS : 가변 배열의 필드 (MS_MUTABLE_ARRAY)
이 final static 필드는 배열을 참조하고 있기 때문에 악성 코드와 우연히 다른 패키지에 액세스 할 수 있습니다. 이 코드는 배열의 콘텐츠를 자유롭게 변경할 수 있습니다.
MS : 가변 컬렉션의 필드 (MS_MUTABLE_COLLECTION)
가변 컬렉션의 인스턴스가 final static 필드에 할당합니다. 따라서 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 취약점을 피하기 위해 Collections.unmodifiableSet / List / Map 등에서이 필드를 랩하는 것을 고려해보십시오.
MS : 패키지 보안 모드로해야 가변 컬렉션의 필드 (MS_MUTABLE_COLLECTION_PKGPROTECT)
가변 컬렉션의 인스턴스가 final static 필드에 할당합니다. 따라서 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 필드는 취약점을 피하기 위해 패키지 보안 모드에 있습니다. 대신 Collections.unmodifiableSet / List / Map 등에서이 필드를 랩해도 취약점을 피할 수 있습니다.
MS : 가변 Hashtable 필드 (MS_MUTABLE_HASHTABLE)
이 final static 필드는 Hashtable를 참조하고 있기 때문에 악성 코드와 우연히 다른 패키지에 액세스 할 수 있습니다. 이 코드는 Hashtable의 콘텐츠를 자유롭게 변경할 수 있습니다.
MS : 인터페이스에서 이동하여 패키지 보안 모드로해야 할 필드 (MS_OOI_PKGPROTECT)
인터페이스에 정의 된 final static 필드가 배열이나 Hashtable 등의 가변 객체를 참조합니다. 이 가변 객체는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 이를 해결하기 위해 필드는 클래스로 이동해야 취약점을 방지하기 위해 패키지 보안 모드로합니다.
MS : 패키지 보안 모드로해야 할 필드 (MS_PKGPROTECT)
이 가변 static 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 필드는 취약점을 방지하기 위해 패키지 보안 모드로합니다.
MS : final이 될 필드 (MS_SHOULD_BE_FINAL)
final이 아닌 public static 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 필드는 취약점을 방지하기 위해 final합니다.
MS : final이 아닌 필드는 리팩토링 할 것이다 (MS_SHOULD_BE_REFACTORED_TO_BE_FINAL)
final이 아닌 public static 필드는 악성 코드와 우연히 다른 패키지에 의해 변경할 수 있습니다. 필드는 취약점을 방지하기 위해 final합니다. 그러나 정적 이니셜 라이저에는 여러 필드에 쓸 수 있기 때문에, 어떤 리팩토링을 필요로 할 것이다.
AT : 병행 추상의 호출 순서는 원자 않을지도 모른다 (AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION)
이 코드는 병행 추상화 (예를 들어, 동시에 해시 맵)의 호출 순서가 있습니다. 이러한 호출은 원자 적으로 실행되지 않습니다.
DC : 필드 번 확인 가능 (DC_DOUBLECHECK)
이 메소드는 두 번 확인 잠금 인스턴스가 있을지도 모릅니다. 이 숙어는 Java의 메모리 모델은 올바르지 않습니다.
자세한 내용은 http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 를 참조하십시오.DC : 부분적으로 초기화 된 객체를 노출 할 가능성이있다 (DC_PARTIALLY_CONSTRUCTED)
더블 체크 흔들 함께 지연 초기화 필드를 사용하는 방법과 같습니다. 이 필드를 잘 volatile로 선언되는 동안 객체의 내부 구조가 필드에 할당 된 후에 변경 될 수 있습니다. 따라서 다른 스레드가 부분적으로 초기화 된 개체를 볼지도 모릅니다.
이 문제를 고치기 위해 먼저 로컬 변수를 객체에 저장하여 완전히 구축 한 후 volatile 필드를 저장하는 것을 고려하십시오.
DL : Boolean 동기화 (DL_SYNCHRONIZATION_ON_BOOLEAN)
Boolean
같은 복싱 된 원시 형의 정수로 동기화하고 있습니다.private static Boolean inited = Boolean.FALSE; synchronized (inited) { if (! inited) { init (); inited = Boolean.TRUE; } }
일반적으로 2 개의
Boolean
객체 만 존재하고 있습니다. 이 코드는 다른 무관 한 코드와 같은 개체에서 동기화하고있을 가능성이 있기 때문에, 무응답 및 교착 상태의 원인이됩니다.DL : 교착 상태의 원인이 될 수있다 권투 된 원시 형의 동기화 (DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE)
이 코드는 Integer 같은 복싱 된 원시 형의 정수로 동기화하고 있습니다.
private static Integer count = 0; synchronized (count) { count ++; }
Integer
객체는 캐시 공유 할 수 있습니다. 다른 무관 한 코드와 같은 개체에서 동기화하고있을 가능성이 있기 때문에, 무응답 및 교착 상태의 원인이됩니다.CERT의 CON08-J. Do not synchronize on objects that may be reused 를 참조하십시오.
DL : 긍정적 準化 문자열의 동기화 (DL_SYNCHRONIZATION_ON_SHARED_CONSTANT)
이 코드는 긍정적 準化 문자열에서 동기화하고 있습니다.
private static String LOCK = "LOCK"; synchronized (LOCK) { ... }
문자열 상수는 정의準化되어 Java 가상 머신에로드 된 모든 클래스에서 공유됩니다. 따라서 이것은 다른 코드가 잠겨있는지도 모른다 무언가를 잠근 수 있습니다. 이것은 차단 및 교착 상태의 행동의 진단을 어렵게하고, 매우 이상한 결과가 될 가능성이 있습니다.
자세한 내용은 http://www.javalobby.org/java/forums/t96352.html 과 http://jira.codehaus.org/browse/JETTY-352 를 참조하십시오.DL : 권투 된 프리미티브 값의 동기화 (DL_SYNCHRONIZATION_ON_UNSHARED_BOXED_PRIMITIVE)
이 코드는 분명히 공유되지 않은
Integer
같은 복싱 된 원시 형으로 동기화하고 있습니다.private static final Integer fileLock = new Integer (1); synchronized (fileLock) { .. do something .. }
이 코드는 fileLock를 다음과 같이 선언하면 더 좋아집니다.
private static final Object fileLock = new Object ();
기존 코드로 잘못 할지도 모르지만, 오해하기 쉽기 때문에 미래 리팩토링해야 할지도 모릅니다. 예를 들어, IntelliJ의 "Remove Boxing"같은 리팩토링은 Java 가상 머신을 통해 공유되는 양準化된
Integer
객체를 사용하도록 대체 버려, 매우 혼란 행동과 잠재적 교착 상태의 원인이됩니다 .Dm : Condition에서 wait 메소드를 호출하는 (DM_MONITOR_WAIT_ON_CONDITION)
이 메소드는
java.util.concurrent.locks.Condition
개체에서wait
메소드를 호출합니다.Condition
객체를 대기시키기 위해서는Condition
인터페이스로 정의 된await
메소드를 사용한다.Dm : 기본 빈 run 메소드를 사용하여 생성 된 스레드 (DM_USELESS_THREAD)
이 메소드는
Thread
클래스에서 파생 된run
메소드를 지정하지 않거나Runnable
객체를 전달하지 않고 스레드를 만들고 있습니다. 이 스레드는 시간 낭비입니다.ESync : 빈 synchronized 블록 (ESync_EMPTY_SYNC)
이 코드는 빈 synchronized 블록이 있습니다.
synchronized () { }
빈 synchronized 블록은 성공적 제대로 사용하기가 어렵습니다. 빈 synchronized 블록은 일부러 결코 좋은 해결책이 없습니다.
IS : 일관성없는 동기화 (IS2_INCONSISTENT_SYNC)
이 클래스의 필드는 동기화에 대해 일관성없이 사용되는 것 같습니다. 이 버그 리포트는 버그 패턴 검출기가 다음과 같이 판단한 것을 나타냅니다.
- 클래스는 잠긴 액세스 및 잠금 해제 된 액세스가 혼재하고있어
- 클래스는 javax.annotation.concurrent.NotThreadSafe로 주석되지 않습니다
- 적어도 하나의 잠긴 액세스가 클래스 자신의 방법 중 하나에 의해 실행되고
- 읽기의 2 배의 가중치를 쓰기에서 비동기 필드의 액세스 (읽기 및 쓰기) 수가 모든 액세스 불과 1/3
<="" p="" style="color: rgb(0, 0, 0); font-family: 'Apple SD Gothic Neo'; font-size:12pt; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: -webkit-left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);">
검출기 어디서 필드가 동기화없이 액세스 할 믿습니다했는지를 나타내는 코드의 위치에 "비동기 액세스 '라는 라벨이 붙어있는 노드를 선택할 수 있습니다.
부정확 한 여러가지 원인이 검출기에 있다는 점에 유의하십시오. 예를 들어, 검출기는 잠금을 보유하는 모든 상황을 정적으로 감지 할 수있는 것은 아닙니다. 또한 검출기가 잠긴 액세스 및 잠금 해제 된 액세스의 구별이 정확한 경우에도 문제의 코드는 여전히 올바른지도 모릅니다.
IS : 병행 액세스에 대해서 가드 않은 필드 (IS_FIELD_NOT_GUARDED)
이 필드는 net.jcip.annotations.GuardedBy 또는 javax.annotation.concurrent.GuardedBy에서 주석되어 있지만 주석에 위반된다고 생각되는 방법으로 액세스 할 수 있습니다.
JLM : Lock으로 동기화하는 (JLM_JSR166_LOCK_MONITORENTER)
이 메소드는
java.util.concurrent.locks.Lock
를 구현 한 객체에서 동기화하고 있습니다. 그러한 객체는synchronized (...)
구문보다acquire ()
/release ()
를 사용하여 잠금 및 잠금 해제합니다.JLM : java.util.concurrent의 인스턴스에서 동기화하고 (JLM_JSR166_UTILCONCURRENT_MONITORENTER)
이 메소드는 java.util.concurrent 패키지의 클래스 (또는 서브 클래스)의 인스턴스로 동기화합니다. 이 클래스의 인스턴스는
synchronized
의 사용과는 다른 호환되지 않는 그들 자신의 병행 제어 메커니즘을 가지고 있습니다. 예를 들어,AtomicBoolean
에서 동기화해도 다른 스레드가AtomicBoolean
를 변경하는 것을 방지하지 않습니다.그런 코드는 맞을 수도 있지만, 장래 코드를 유지해야한다 사람들을 혼란시킬지도 모르기 때문에 신중하게 검토하고 문서화해야합니다,
JLM : util.concurrent 추상 모니터 스타일의 wait 메소드를 사용하는 (JML_JSR166_CALLING_WAIT_RATHER_THAN_AWAIT)
이 메서드는
await ()
메서드signal
메소드signalAll
메소드를 제공하는 오브젝트 (예를 들어, util.concurrent의 Condition 객체)에서wait
메소드notify
메소드notifyAll
메소드를 호출합니다. 이것은 아마도 당신이 원하는 것은 아닙니다. 비록 그것이 희망하더라도 다른 개발자가 매우 혼란을 이해하고 설계를 변경하는 것을 검토해야합니다.LI : static 필드의 잘못된 지연 초기화 (LI_LAZY_INIT_STATIC)
이 메소드는 volatile 아닌 static 필드의 비동기 지연 초기화합니다. 컴파일러와 프로세서가 명령을 정렬지도 모르기 때문에, 메소드가 여러 스레드에서 호출된다면 스레드 완전히 초기화 된 개체를 본다고는 보장되지 않습니다. 필드에 액세스 할 때, 도중에 초기화 된 인스턴스가 보여 버리는 위험이 있습니다. 이 문제를 해결하기 위해 필드를 volatile 수 있습니다.
자세한 내용은 Java Memory Model web site 를 참조하십시오.LI : 업데이트되는 static 필드의 잘못된 지연 초기화 (LI_LAZY_INIT_UPDATE_STATIC)
이 메소드는 static 필드의 비동기 지연 초기화합니다. 필드가 설정된 후 그 위치에 저장되는 객체는 또한 업데이트되거나 사용됩니다. 그것이 설정되면 즉시 필드를 설정하는 것은 다른 스레드 보입니다. 필드를 설정하는 새로운 접근이 객체를 초기화하는데 도움이 있다면, 그것은 완전히 초기화 될 때까지 어떤 다른 스레드도 포함 된 개체에 액세스하는 것을 막지 않는 한, 매우 심각한 멀티 스레드 버그가 있습니다.
비록 메소드가 여러 스레드에서 호출되지 않는다고 확신해도 그것은 필드에 설정된 값이 완전히 데이터를로드하거나 초기화 될 때까지 static 필드를 설정하지 않는 편이 좋을지도 없습니다.
ML : 필드를 동기화 가드하려는 헛된 시도 (ML_SYNC_ON_FIELD_TO_GUARD_CHANGING_THAT_FIELD)
이 메서드는 필드의 동시 업데이트에 동기화 가드하려고합니다. 그러나 필드를 가드하면 필드가 아닌 필드가 참조하는 객체의 잠금을 획득합니다. 이것은 당신이 필요로하는 상호 배제 할 수 없을지도 모릅니다. 다른 스레드 (다른 목적을위한) 참조 된 개체의 잠금을 획득 할지도 모릅니다.
이 패턴의 예는 다음과 같습니다.private Long myNtfSeqNbrCounter = new Long (0); private Long getNotificationSequenceNumber () { Long result = null; synchronized (myNtfSeqNbrCounter) { result = new Long (myNtfSeqNbrCounter.longValue () + 1); myNtfSeqNbrCounter = new Long (result.longValue ()); } return result; }
ML : 업데이트 된 필드에서 동기화하는 방법 (ML_SYNC_ON_UPDATED_FIELD)
이 메서드는 가변 필드에서 참조 된 개체에 동기화합니다. 다른 스레드가 다른 개체에서 동기화하고 있을지도 모르기 때문에 유용한 의미를 가지고있을 가능성이 낮습니다.
MSF : 가변 서블릿 필드 (MSF_MUTABLE_SERVLET_FIELD)
Web 서버는 일반적으로 서블릿과 JSP 클래스의 인스턴스를 하나 만듭니다 (즉, 싱글 톤으로 취급합니다). 여러 스레드가 동시에 여러 개의 요청에 부응하기 위해 인스턴스에서 메서드를 호출합니다. 따라서 일반적으로 가변 인스턴스 필드는 경쟁 상태를 만듭니다.
MWN : 일관성없는 notify 메소드 (MWN_MISMATCHED_NOTIFY)
이 메소드는 객체가 분명 잠금을 보유하지 않고
Object.notify ()
와Object.notifyAll ()
를 호출합니다. 유지되는 잠금이없는 상태에서notify
메소드 나notifyAll
메소드를 호출하는 것은IllegalMonitorStateException
를 throw 할 수 있습니다.MWN : 일관성없는 wait 메소드 (MWN_MISMATCHED_WAIT)
이 메소드는 객체가 분명 잠금을 보유하지 않고
Object.wait ()
를 호출합니다. 유지되는 잠금이없는 상태에서wait
메소드를 호출하는 것은IllegalMonitorStateException
를 throw 할 수 있습니다.NN : 알몸의 notify 메소드 (NN_NAKED_NOTIFY)
notify
메소드 또는notifyAll
메소드에의 호출은 가변 객체 상태에 어떤 (명백한) 부수적 인 변화도 초래하지 않았습니다. 일반적으로 다른 스레드가 기대하고있는 몇 가지 조건이 진정 되었기 때문에, 모니터notify
메소드가 불려갑니다. 그러나 의미가있는 조건을 위해 두 스레드에 보이는 힙 객체를 포함해야합니다.가변 객체의 상태 변경이 통지가있는 메소드를 호출 한 메소드에서 일어난지도 모르기 때문에이 버그가 오류를 표시하는 것은 아닙니다.
NP : 같은 필드에서의 동기화 및 null 체크 (NP_SYNC_AND_NULL_CHECK_FIELD)
필드는 동기화하기 때문에 아마도 null이 아니라고 생각합니다. null 필드를 동기화하면 NullPointerException이 발생되므로 null 체크는 무의미합니다. 다른 필드에서 동기화하는 것이 좋습니다.
No : notifyAll 메소드가 아닌 notify 메소드를 사용하는 (NO_NOTIFY_NOT_NOTIFYALL)
이 메소드는,
notifyAll
메소드가 아닌notify
메소드를 호출합니다. 모니터가 여러 조건을 위해 종종 사용됩니다.notify
메소드의 호출은 하나의 스레드를 일으키는 것만으로 제기 된 스레드는 호출이 충족 대기 조건 중 하나가 아닐지도 모른다는 것을 의미합니다.RS : readObject 메소드를 동기화하는 클래스 (RS_READOBJECT_SYNC)
이 직렬화 가능 클래스는 동기화하는
readObject
메소드를 정의하고 있습니다 만, 직렬화 복원에 의해 작성된 오브젝트는 하나의 스레드에 의해서만 도달 할 수 있습니다. 따라서,readObject
메소드는 동기화 할 필요가 없습니다.readObject
메소드 자체가 다른 스레드에 보이게되는 객체의 원인이 있다면 매우 의심스러운 코딩 스타일의 예입니다.RV : putIfAbsent의 반환 값은 무시되고 putIfAbsent에 전달 된 값은 재사용 된 (RV_RETURN_VALUE_OF_PUTIFABSENT_IGNORED)
putIfAbsent
메소드는 하나의 값이 주어진 키 (존재가 성공 여부의 첫번째 값)과 관련이 있는지 확인하기 위해 사용됩니다. 반환 값을 무시하고 중이며 전달되는 값에 대한 참조를 유지한다면, 맵의 키와 관련된 하나가 아닌 값을 유지하는 위험을 감수합니다. 어느 것을 사용 하느냐가 중요하며, 맵에 포함 할 수없는 것을 사용하면 프로그램이 잘못된 행동을합니다.Ru : 스레드에서 run 메소드를 호출하는 (RU_INVOKE_RUN)
이 메소드는 스레드에서 명시 적으로
run
메소드를 호출합니다. 일반적으로 클래스는 새로운 스레드에서 자기의run
메소드를 호출 해달라고하기 위하여Runnable
인터페이스를 구현합니다. 이 경우Thread.start ()
를 호출하는 것이 맞습니다.SC : Thread.start ()를 호출하는 생성자 (SC_START_IN_CTOR)
생성자가 스레드를 시작합니다. 클래스가 확장되어 서브 클래스가 만들어진다면 잘못 있다고합니다. 왜냐하면, 서브 클래스의 생성자에서 스레드가 시작되기 전에 슈퍼 클래스의 스레드가 시작되어 버리는 것입니다.
SP : 스핀 락을하고있는 메소드 (SP_SPIN_ON_FIELD)
이 메소드는, 필드를 읽는 루프에서 계속 작동합니다. 컴파일러가 필드를 읽을 루프 밖으로 낼 수도 없습니다. 코드를 무한 루프로 변경합니다. 올바른 동기화 (wait / notify를 호출하도록 포함)를 사용하도록 클래스를 변경해야합니다.
STCAL : static Calendar 호출 (STCAL_INVOKE_ON_STATIC_CALENDAR_INSTANCE)
비록 JavaDoc에 이에 대한 단서가 아니더라도 Calendar는 멀티 스레드에서의 사용은 본질적으로 안전하지는 않습니다. 검출기는 static 필드에서 얻은 Calendar 인스턴스의 호출을 발견했습니다. 이것은 의심 보입니다.자세한 내용은 Sun Bug # 6231579 및 Sun Bug # 6178997 를 참조하십시오.
STCAL : static DateFormat 호출 (STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE)
JavaDoc에 쓰여진대로 DateFormat는 멀티 스레드에서의 사용은 본질적으로 안전하지는 않습니다. 검출기는 static 필드에서 얻은 DateFormat 인스턴스의 호출을 발견했습니다. 이것은 의심 보입니다. 자세한 내용은Sun Bug # 6231579 및 Sun Bug # 6178997 를 참조하십시오.
STCAL : static Calendar 필드 (STCAL_STATIC_CALENDAR_INSTANCE)
비록 JavaDoc에 이에 대한 단서가 아니더라도 Calendar는 멀티 스레드에서의 사용은 본질적으로 안전이며 없습니다. 정확한 동기화를하지 스레드 경계 너머에서 하나의 인스턴스를 공유 할 응용 프로그램의 오작동입니다. JDK 5.0에 비해 JDK 1.4 쪽이 문제가 표면화 될 것 같습니다 아마도 sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate ()의 ArrayIndexOutOfBoundsExceptions과 IndexOutOfBoundsExceptions이 무작위로 발생합니다. 직렬화 문제도 경험할지도 모릅니다. 인스턴스 필드를 사용하는 것을 권장합니다.
자세한 내용은 Sun Bug # 6231579 및 Sun Bug # 6178997 를 참조하십시오.STCAL : static DateFormat (STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE)
JavaDoc에 쓰여진대로 DateFormat는 멀티 스레드에서의 사용은 본질적으로 안전하지는 않습니다. 정확한 동기화를하지 스레드 경계 너머에서 하나의 인스턴스를 공유 할 응용 프로그램의 오작동입니다. JDK 5.0에 비해 JDK 1.4 쪽이 문제가 표면화 될 것 같습니다 아마도 sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate ()의 ArrayIndexOutOfBoundsExceptions과 IndexOutOfBoundsExceptions이 무작위로 발생합니다. 직렬화 문제도 경험할지도 모릅니다. 인스턴스 필드를 사용하는 것을 권장합니다.
자세한 내용은 Sun Bug # 6231579 및 Sun Bug # 6178997 를 참조하십시오.SWL : 잠금을 보유하고 Thread.sleep ()를 호출하는 메소드 (SWL_SLEEP_WITH_LOCK_HELD)
이 메소드는 잠금을 보유하고
Thread.sleep ()
를 호출합니다. 다른 스레드가 락을 획득하기 위해 대기하고있는지도 모르기 때문에 심한 성능과 확장 성, 또는 교착 상태의 원인이 될 수도 있습니다. 잠금wait
메소드를 호출하는 것은 매우 좋은 생각 잠금을 해제하고 다른 스레드가 수행하도록 허용합니다.TLW : 두 개 이상의 잠금을 보유하고 wait 메소드를 호출하는 (TLW_TWO_LOCK_WAIT)
두 개 이상의 잠금을 유지하여 모니터에 대기 시키면 교착 상태가 발생할 수 있습니다.
wait
메소드를 호출하면 대기하고있는 객체의 잠금을 해제하면 다른 잠금 해제하지 않습니다. 이것은 반드시 버그는 아니지만 시험하는 가치가 있습니다.UG : 동기화하지 않는 get 메소드 동기화하는 set 메소드 (UG_SYNC_SET_UNSYNC_GET)
이 클래스는 비슷한 이름의 get 메소드 및 set 메소드가있어, set 메소드는 동기화하고, get 메소드는 동기화하지 않습니다. get 메소드 호출자가 개체의 일관된 상태를 반드시 본다는 것은 아니기 때문에, 실행시 잘못된 행동의 원인이 될 수 있습니다. get 메소드는 동기화해야합니다.
UL : 모든 경로에서 잠금이 해제되지 않는 메소드 (UL_UNRELEASED_LOCK)
이 메소드는 JSR-166 (
java.util.concurrent
) 잠금을 획득하고 있습니다 만, 메소드로부터의 모든 경로에서 해제하지 않습니다. 일반적으로 JSR-166의 잠금을 사용하는 올바른 관용구는 다음과 같습니다.Lock l = ...; l.lock (); try { // do something } finally { l.unlock (); }
UL : 모든 예외 경로에서 잠금이 해제되지 않는 메소드 (UL_UNRELEASED_LOCK_EXCEPTION_PATH)
이 메소드는 JSR-166 (
java.util.concurrent
) 잠금을 획득하고 있습니다 만, 메소드에서 모든 예외 경로에서 해제하지 않습니다. 일반적으로 JSR-166의 잠금을 사용하는 올바른 관용구는 다음과 같습니다.Lock l = ...; l.lock (); try { // do something } finally { l.unlock (); }
UW : wait 메소드의 무조건 호출 (UW_UNCOND_WAIT)
이 메소드는 조건 제어 흐름에 의해 가드되지 않는
java.lang.Object.wait ()
의 호출이 있습니다. 이 코드는wait
메소드를 호출하기 전에 대기하는 거라고 조건이 이미 충족되지 않는다는 것을 확인한다. 어떤 이전 고시도 무시됩니다.VO : volatile 필드에 증가 원자는 아니다 (VO_VOLATILE_INCREMENT)
이 코드는 volatile 필드 증가하고 있습니다. volatile 필드의 증가는 원자는 없습니다. 여러 스레드가 동시에 필드를 증가하면 증가가 손실 될 수 있습니다.
VO : 배열에 volatile 참조는 배열 요소를 volatile로 취급하지 않는다 (VO_VOLATILE_REFERENCE_TO_ARRAY)
배열에 volatile 참조를 선언하고 있습니다 만, 당신이 원하는 것은 없을지도 모릅니다. 배열에 volatile 참조는 배열에 대한 참조의 읽기, 쓰기는 volatile로 취급되지만, 배열 요소는 volatile로 간주되지 않습니다. 배열 요소를 volatile로 취급하고자한다면, J2SE 5.0에서 제공된 java.util.concurrent 패키지의 원자 배열 클래스를 사용할 필요가 있습니다.
WL : 클래스 리터럴 대신 getClass에서 동기화하고 (WL_USING_GETCLASS_RATHER_THAN_CLASS_LITERAL)
이 인스턴스 메서드는
this.getClass ()
에서 동기화하고 있습니다. 이 클래스가 상속된다면, 서브 클래스는 아마 의도 한 것은 아니다 서브 클래스에 대한 클래스 개체 동기화합니다. 예를 들어,java.awt.Label
의 다음 코드를 검토하십시오.private static final String base = "label"; private static int nameCounter = 0; String constructComponentName () { synchronized (getClass ()) { return base + nameCounter ++; } }
Label
의 서브 클래스는 같은 서브 클래스에서 동기화하지 않습니다. 데이터 레이스를 초래합니다. 대신,이 코드는Label.class
으로 동기화해야합니다.private static final String base = "label"; private static int nameCounter = 0; String constructComponentName () { synchronized (Label.class) { return base + nameCounter ++; } }
Jason Mehrens 의해 기증 된 버그 패턴
WS : writeObject 메소드는 동기화하고 있지만 다른 방법은 동기화하지 않는 클래스 (WS_WRITEOBJECT_SYNC)
이 클래스는 동기화하는
writeObject
메소드가 있습니다. 그러나 클래스의 다른 메서드는 동기화하지 않습니다.Wa : Condition.await ()이 루프없는 (WA_AWAIT_NOT_IN_LOOP)
이 메서드는 루프없는
java.util.concurrent.await ()
(또는 유사)를 호출합니다. 객체가 복수의 조건을 위해 사용될 경우, 호출자가 대기하는 거라고 조건은 실제로는 발생하지 않을지도 모릅니다.Wa : wait 메소드가 루프없는 (WA_NOT_IN_LOOP)
이 메서드는 루프없는
java.lang.Object.wait ()
를 호출합니다. 모니터가 여러 조건을 위해 사용될 경우, 호출자가 대기하는 거라고 조건은 실제로는 발생하지 않을지도 모릅니다.Bx : 프리미티브 값이 권투되는 즉시 언 박싱 된 (BX_BOXING_IMMEDIATELY_UNBOXED)
프리미티브 값이 권투되는 즉시 언 박싱됩니다. 아마 언 박싱 된 값이 필요한 장소에서 수동으로 권투를하고 있기 때문입니다. 그 결과, 컴파일러 복싱 기능을 취소하도록 강요하고 있습니다.
Bx : 프리미티브 값이 원시적 형의 형태 변환을위한 복싱되어 언 박싱 된 (BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION)
프리미티브 값이 생성자에서 권투되는 즉시 다른 원시적 형에 변환됩니다 (예를 들어
new Double (d) .intValue ()
). 직접 원시적 형의 형태 변환을 실행하십시오 (예를 들어(int) d
).Bx : 프리미티브 값이 3 항 연산자에 대한 언 박싱 된 형식 변환된다 (BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR)
랩 된 기본 값은 3 항 연산자 (
b? e1 : e2
) 평가의 일부로서 다른 원시 형에 언 박싱되어 변환됩니다. Java 언어 사양에서는e1
과e2
가 래핑 된 수치라면 값은 언 박싱 된 일반적인 형태로 변환 / 형식 변환됩니다 (예를 들어,e1
이Integer
에서e2
가Float
이면e1
은 언 박싱 (int
로 변환)되어float
로 변환되고, 권투 (Float
로 변환)됩니다). JLS 섹션 15.25을 참조하십시오.Bx : 복싱 된 값이 언 박싱되어 곧 다시 권투되는 (BX_UNBOXING_IMMEDIATELY_REBOXED)
복싱 된 값이 언 박싱되어 곧 다시 권투됩니다.
Bx : 원시 비교에서 권투되는 (DM_BOXED_PRIMITIVE_FOR_COMPARE)
권투 된 원시적 단순히 compareTo 메소드를 호출하기 위해 만들어져 있습니다. 직접 원시에서 일하는 static compare 메소드 (double과 float는 Java 1.4에서 다른 원시적 형은 Java 1.7에서)를 사용하는 편이 더 효율적입니다.
Bx : 박싱 / 언 박싱은 프리미티브를 분석하는 (DM_BOXED_PRIMITIVE_FOR_PARSING)
박스 화 된 프리미티브는 String에서 생성되어 있고, 제거 박스 화 된 원시적 치를 추출합니다. static parseXXX 메소드를 호출하는 것이 효율적입니다.
Bx : toString 메소드를 호출하는 원시적 형의 래퍼 클래스의 인스턴스를 생성하고 (DM_BOXED_PRIMITIVE_TOSTRING)
toString
메소드를 호출하는 원시적 형의 래퍼 클래스의 인스턴스를 만들고 있습니다. 그것보다 원시적 치를 인수에 static의toString
메소드를 사용하는 편이 효율적입니다.대체 전 교체 후 new Integer (1) .toString () Integer.toString (1) new Long (1) .toString () Long.toString (1) new Float (1.0) .toString () Float.toString (1.0) new Double (1.0) .toString () Double.toString (1.0) new Byte (1) .toString () Byte.toString (1) new Short (1) .toString () Short.toString (1) new Boolean (true) .toString () Boolean.toString (true) Bx : 비효율적 부동 소수점 Number 생성자를 호출하는 메소드 (DM_FP_NUMBER_CTOR)
new Double (double)
의 사용은 항상 새로운 개체가되는 것이 보증되고 있습니다. 이에 대해Double.valueOf (double)
컴파일러 클래스 라이브러리, Java 가상 머신에서 값이 캐시됩니다. 캐시에 저장된 값을 사용하는 것은 인스턴스 생성을 방지하고 코드는 더 빨라집니다.클래스가 J2SE 5.0 이전의 Java 가상 머신과 호환이 필요하지 않다면, 오토 박싱 또는
Double
,Float
의valueOf
메소드를 사용하십시오.Bx : 비효율적 Number 생성자를 호출하는 메소드 (DM_NUMBER_CTOR)
new Integer (int)
의 사용은 항상 새로운 개체가되는 것이 보증되고 있습니다. 이에 대해Integer.valueOf (int)
컴파일러 클래스 라이브러리, Java 가상 머신에서 값이 캐시됩니다. 캐시에 저장된 값을 사용하는 것은 인스턴스의 생성을 방지하고 코드는 더 빨라집니다.-128에서 127까지의 값은 대응하는 캐시 된 인스턴스를 갖게되고 있습니다. 그리고
valueOf
메소드의 사용은 생성자를 사용하는 것보다 약 3.5 배 빠릅니다. 상수 범위를 벗어난 값은 두 스타일의 성능은 동일합니다.클래스가 J2SE 5.0 이전의 Java 가상 머신과 호환이 필요하지 않다면,
Long
,Integer
,Short
,Character
,Byte
인스턴스를 만들 때 자동 권투 또는valueOf
메소드를 사용하십시오.Dm : URL의 equals 메소드와 hashCode 메소드는 차단 (DMI_BLOCKING_METHODS_ON_URL)
URL의
equals
메소드와hashCode
메소드는 도메인 이름 확인을 수행하므로 심한 성능이 될 수 있습니다.
자세한 내용은 http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html 를 참조하십시오.
대신java.net.URI
를 사용하는 것을 고려하십시오.Dm : URL의 Map과 Set 끔찍한 성능된다 (DMI_COLLECTION_OF_URLS)
이 메소드 또는 필드는 URL의
Map
또는Set
를 사용하고 있습니다. URL의equals
및hashCode
는 도메인 이름 확인을 수행하므로 심한 성능입니다.
자세한 내용은 http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html 를 참조하십시오.
대신java.net.URI
를 사용하는 것을 고려하십시오.Dm : 비효율적 Boolean 생성자를 호출하는 메소드 (DM_BOOLEAN_CTOR)
java.lang.Boolean
의 새로운 인스턴스를 생성하면 메모리를 낭비합니다.Boolean
객체는 불변 두 개의 유용한 값 (Boolean.TRUE
와Boolean.FALSE
)이 있습니다. 대신Boolean.valueOf
메소드 (또는 J2SE 5.0 오토 박싱)를 사용하여Boolean
객체를 생성합니다.Dm : 명시적인 가비지 컬렉션 (DM_GC)
명시 적으로 가베지 컬렉션을 호출하고 있습니다. 벤치 마크의 특정 용도를 제외하고 매우 의심입니다.
과거에
close
메소드 나finalize
메소드 가비지 컬렉터를 명시 적으로 호출했던 상황은 큰 성능 블랙홀의 원인이되었습니다. 가비지 컬렉션은 많이 듭니다. 수백 수천의 가비지 수집을 강제하는 상황은 시스템의 정체를 가져올 것이다.Dm : 클래스 객체를 얻기 위해서만 인스턴스를 작성하는 방법 (DM_NEW_FOR_GETCLASS)
메소드는 클래스 객체를 얻기 위해 인스턴스를 생성하고
getClass
메소드를 호출합니다. 클래스 리터럴 (Foo.class
)를 사용하는 편이 간단합니다.Dm : 정수 난수를 생성하기 위해서는 nextDouble 메소드 대신 nextInt 메소드를 사용하면 (DM_NEXTINT_VIA_NEXTDOUBLE)
java.util.Random
의 인스턴스r
에서0
부터n-1
의 난수를 생성하고자한다면(int) (r.nextDouble () * n)
대신r.nextInt (n)
를 사용합니다.nextInt
메소드의 인수는 정수 여야합니다. 예를 들어, -99에서 0까지의 난수를 생성하고 싶다면,-r.nextInt (100)
를 사용하십시오.Dm : 비효율적 new String (String) 생성자를 호출하는 메소드 (DM_STRING_CTOR)
new String (String)
생성자의 사용은 메모리를 낭비합니다. 그렇게 구축 된 객체와 매개 변수로 전달 된String
은 기능적으로 구별이되지 않기 때문입니다. 인수의String
을 그대로 사용하십시오.Dm : String의 toString 메소드를 호출하는 메소드 (DM_STRING_TOSTRING)
String.toString ()
를 호출하는 것은 중복입니다.String
을 사용하십시오.Dm : 비효율적 new String () 생성자를 호출하는 메소드 (DM_STRING_VOID_CTOR)
인수가없는 생성자를 사용하여 새로운
java.lang.String ()
객체를 생성하면 메모리를 낭비합니다. 그렇게하여 생성 된 개체와 빈 문자열 상수""
기능적으로 구별이되지 않기 때문입니다. Java는 동일한 문자열 상수가 같은String
오브젝트에 의해 나타나는 것을 보장합니다. 따라서 직접 빈 문자열 상수를 사용해야합니다.HSC : 여러 클래스 파일에 걸쳐 복제 된 거대한 문자열 상수 (HSC_HUGE_SHARED_STRING_CONSTANT)
거대한 문자열 상수가 여러 클래스 파일에 걸쳐 복제되고 있습니다. final 필드가 문자열 상수로 초기화되어 Java 언어에 따라 다른 클래스에서 final 필드에 대한 모든 참조가 클래스 파일에 인라인되기 때문입니다.
JDK는이 버그를 해결하고 크기를 1MB 줄일 수있었습니다.
자세한 내용은 JDK bug 6447475 를 참조하십시오.SBSC : 루프에서 +를 사용하여 문자열을 연결하는 방법 (SBSC_USE_STRINGBUFFER_CONCATENATION)
이 메서드는 루프에서 +를 사용하여
String
를 구축하고 있다고 생각됩니다. 각 반복에서String
은StringBuffer
/StringBuilder
로 변환 추가되고String
로 변환됩니다. 각 반복에서 문자열을 다시 복사됩니다 증가하는 반복의 숫자로 이차 비용이 발생할 수 있습니다.StringBuffer
(또는 J2SE 5.0의StringBuilder
)을 명시 적으로 사용하면 더 나은 성능을 얻을 수 있습니다.예를 들어,
// This is bad String s = ""; for (int i = 0; i <field.length; ++ i) { s = s + field [i]; } // This is better StringBuffer buf = new StringBuffer (); for (int i = 0; i <field.length; ++ i) { buf.append (field [i]); } String s = buf.toString ();
SIC : static 내부 클래스에해야 (SIC_INNER_SHOULD_BE_STATIC)
이 클래스는 내부 클래스인데 그것을 만든 개체에 포함 된 참조를 사용하지 않습니다. 이 참조는 더 큰 클래스의 인스턴스를 생성하여 필요 이상으로 생성 객체에 대한 참조를 존속하는 것이 있습니다. 있다면 클래스는 static으로해야합니다.
SIC : 명명 된 static 내부 클래스로 리팩토링 할 수 있을지도 모른다 (SIC_INNER_SHOULD_BE_STATIC_ANON)
이 클래스는 내부 클래스인데 그것을 만든 개체에 포함 된 참조를 사용하지 않습니다. 이 참조는 더 큰 클래스의 인스턴스를 생성하여 필요 이상으로 생성 객체에 대한 참조를 존속하는 것이 있습니다. 있다면 클래스는 static 내부 클래스해야합니다. 이름 내부 클래스는 static으로 할 수 없기 때문에 명명 된 내부 클래스 리팩토링해야합니다.
SIC : static 내부 클래스로 리팩토링 할 수 있을지도 모른다 (SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS)
이 클래스는 내부 클래스인데 그것을 만든 개체에 포함 된 참조를 사용하지 않습니다. 이 참조는 더 큰 클래스의 인스턴스를 생성하여 필요 이상으로 생성 객체에 대한 참조를 존속 해 둘 수도 없습니다. 있다면 클래스는 static 내부 클래스해야합니다. 외부 객체에 대한 참조를 내부 클래스의 인스턴스를 구축하는 동안 필요한 때문에 내부 클래스의 생성자에 외부 인스턴스에 대한 참조를 전달하도록 리팩토링해야합니다.
SS : 판독되지 않는 필드 (SS_SHOULD_BE_STATIC)
이 클래스는 컴파일시에 정적 인 값으로 초기화되는 인스턴스 final 필드가 있습니다. static 필드 것을 고려하십시오.
UM : 상수 값에서 Math 클래스의 static 메소드를 호출하는 메소드 (UM_UNNECESSARY_MATH)
이 메소드는 상수 값으로
java.lang.Math
의 static 메소드를 호출합니다. 이 메소드의 결과는 정적으로 판정 할 수있어보다 빠르고, 때로는 상수를 사용하는 편이 더 정확합니다.
감지되는 방법은 다음과 같습니다.메소드 매개 변수 abs -any- acos 0.0 or 1.0 asin 0.0 or 1.0 atan 0.0 or 1.0 atan2 0.0 cbrt 0.0 or 1.0 ceil -any- cos 0.0 cosh 0.0 exp 0.0 or 1.0 expm1 0.0 floor -any- log 0.0 or 1.0 log10 0.0 or 1.0 rint -any- round -any- sin 0.0 sinh 0.0 sqrt 0.0 or 1.0 tan 0.0 tanh 0.0 toDegrees 0.0 or 1.0 toRadians 0.0 UPM : private 메소드는 결코 호출되지 않는 (UPM_UNCALLED_PRIVATE_METHOD)
이 private 메소드는 결코 호출되지 않습니다. 메소드가 반사에 의해 호출 될지도 모르지만, 결코 사용되지 않을 경우 제거해야합니다.
UrF : 판독되지 않는 필드 (URF_UNREAD_FIELD)
이 필드는 결코 읽 없습니다. 클래스에서 제거하는 것을 고려하십시오.
UuF : 미사용 필드 (UUF_UNUSED_FIELD)
이 필드는 결코 사용되지 않습니다. 클래스에서 제거하는 것을 고려하십시오.
WMI : entrySet 반복자가 아니라 비효율적 keySet 반복자를 사용하는 (WMI_WRONG_MAP_ITERATOR)
이 방법은 keySet 이터레이터에서 추출 된 키를 사용하여 맵 항목의 값에 액세스하고 있습니다. Map의 entrySet 반복자를 사용하는 편이
Map.get (key)
조회를 방지하기 때문에 더 효율적입니다.Dm : 하드 코드 된 상수 데이터베이스 암호 (DMI_CONSTANT_DB_PASSWORD)
이 코드는 하드 코드 된 상수 암호를 사용하여 데이터베이스 연결을 만들고 있습니다. 소스 코드 또는 컴파일 된 코드에 액세스 할 수있는 사람이라면 누구나 쉽게 암호를 알 수 버립니다.
Dm : 빈 데이터베이스 암호 (DMI_EMPTY_DB_PASSWORD)
이 코드는 공백 또는 빈 암호를 사용하여 데이터베이스 연결을 만들고 있습니다. 이것은 데이터베이스가 암호로 보호되지 않은 것을 보여줍니다.
HRS : 신뢰할 수없는 입력에서 형성된 HTTP cookie (HRS_REQUEST_PARAMETER_TO_COOKIE)
이 코드는 신뢰할 수없는 HTTP 매개 변수를 사용하여 HTTP 쿠키를 구축하고 있습니다. 이 쿠키가 HTTP 응답에 추가된다면 HRS (HTTP 응답 스뿌릿팅구) 취약점을 가능하게합니다.
자세한 내용은 http://en.wikipedia.org/wiki/HTTP_response_splitting 를 참조하십시오.FindBugs는 HRS의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. HRS를 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
HRS : HTTP 응답 스뿌릿팅구 취약점 (HRS_REQUEST_PARAMETER_TO_HTTP_HEADER)
이 코드는 HTTP 헤더에 HTTP 매개 변수를 직접 쓰입니다. 이것은 HRS (HTTP 응답 스뿌릿팅구) 취약점을 가능하게합니다.
자세한 내용은 http://en.wikipedia.org/wiki/HTTP_response_splitting 를 참조하십시오.FindBugs는 HRS의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. HRS를 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
PT : 서블릿의 절대 경로 탐색 (PT_ABSOLUTE_PATH_TRAVERSAL)
소프트웨어는 제한된 디렉토리에 있어야 경로명을 구축하기 위해 HTTP 요청의 매개 변수를 사용 합니다만, 매개 변수는 그 디렉토리 밖에있는 위치에 해결할 수있는 "/ abs / path"와 같은 절대 경로 순서를 제대로 비활성화하지 않습니다. 자세한 내용은 http://cwe.mitre.org/data/definitions/36.html 를 참조하십시오.
FindBugs는 상대 경로 탐색의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. 상대 경로 탐색을 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
PT : 서블릿의 상대 경로 탐색 (PT_RELATIVE_PATH_TRAVERSAL)
소프트웨어는 제한된 디렉토리에 있어야 경로명을 구축하기 위해 HTTP 요청의 매개 변수를 사용 합니다만, 매개 변수는 그 디렉토리 밖에있는 위치에 해결할 수있는 ".."와 같은 순서를 적절하게 해제하지 않습니다. 자세한 내용은 http://cwe.mitre.org/data/definitions/23.html 를 참조하십시오.
FindBugs는 상대 경로 탐색의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. 상대 경로 탐색을 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
SQL : SQL의 Statement의 execute 또는 addBatch 메소드에 상수가 아닌 문자열을 전달하고있다 (SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE)
이 메소드는 동적으로 생성되는 것으로 보인다 문자열에서 SQL 문장의
execute
또는addBatch
메소드를 호출합니다. 대신PreparedStatement
를 사용하는 것을 고려하십시오. 효율적으로 SQL 주입 공격에 강하다.SQL : PreparedStatement가 정수가 아닌 문자열에서 생성되는 (SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING)
이 코드는 정수가 아닌 문자열에서 SQL의
PreparedStatement
를 생성합니다. 사용자의 체크되지 않은 오염 된 데이터가이 문자열을 만들 때 사용될 경우,PreparedStatement
에서 예상 외로 원하지 않는 무언가를하기 위해 SQL 인젝션이 사용될 가능성이 있습니다.XSS : 반사 형 크로스 사이트 스크립팅 취약점이있는 JSP (XSS_REQUEST_PARAMETER_TO_JSP_WRITER)
이 코드는 JSP의 출력에 HTTP 매개 변수를 직접 쓰입니다. 이것은 XSS (크로스 사이트 스크립팅) 취약점을 가능하게합니다.
자세한 내용은 http://en.wikipedia.org/wiki/Cross-site_scripting 를 참조하십시오.FindBugs는 XSS의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. XSS에 대해 걱정하고 있다면 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
XSS : 반사 형 크로스 사이트 스크립팅 취약점이 오류 페이지에있는 서블릿 (XSS_REQUEST_PARAMETER_TO_SEND_ERROR)
이 코드는 서블릿 오류 페이지에
HttpServletResponse.sendError
를 사용하여 HTTP 매개 변수를 직접 쓰입니다. 신뢰할 수없는 입력을 반환 반사 형 XSS (크로스 사이트 스크립팅) 취약점을 가능하게합니다.
자세한 내용은 http://en.wikipedia.org/wiki/Cross-site_scripting 를 참조하십시오.FindBugs는 XSS의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. XSS를 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
XSS : 반사 형 크로스 사이트 스크립팅 취약점이있는 서블릿 (XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER)
이 코드는 서블릿의 출력에 HTTP 매개 변수를 직접 쓰입니다. 이것은 반사 형 XSS (크로스 사이트 스크립팅) 취약점을 가능하게합니다.
자세한 내용은 http://en.wikipedia.org/wiki/Cross-site_scripting 를 참조하십시오.FindBugs는 XSS의 가장 노골적 자명 한 케이스만을 찾습니다. FindBugs가 뭔가를 발견했다면 틀림없이 FindBugs보고하지 더 취약점이있을 것입니다. XSS를 걱정한다면, 상용 정적 분석 도구 또는 침투 테스트 도구의 사용을 진지하게 검토해야합니다.
BC : 추상 컬렉션에 의심 캐스트 (BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
이 코드는 Collection을 추상 컬렉션에 캐스팅합니다 (예를 들어
List
,Set
,Map
). 개체를 캐스팅하는 형태임을 보장되어 있는지 확인하십시오. 필요로하는 컬렉션의 반복 수 있다면 Set 또는 List에 캐스트 할 필요가 없습니다.BC : 구상 컬렉션에 의심 캐스트 (BC_BAD_CAST_TO_CONCRETE_COLLECTION)
이 코드는 추상 컬렉션 (예를 들어, Collection, List, Set)를 특정의 구상 구현 (예를 들어, ArrayList, HashSet)에 캐스팅 있습니다. 이것은 잘못된지도 모릅니다. 그리고 미래의 시점에서 다른 구상 구현으로 전환을 매우 곤란하기 때문에 취약한 코드가 될지도 모릅니다. 이렇게하는 특별한 이유가없는 한 추상 컬렉션 클래스를 사용하십시오.
BC : 확인되지 않은 / 확인되지 않은 캐스트 (BC_UNCONFIRMED_CAST)
이 캐스트는 확인되지 않습니다. 모든 형태의 인스턴스를 캐스팅하는 형식으로 캐스팅 할 수는 없습니다. 프로그램의 로직이 캐스트가 실패하지 않도록 확실하게 확인하십시오.
BC : 메소드의 반환 값의 체크되지 않은 / 확인되지 않은 캐스트 (BC_UNCONFIRMED_CAST_OF_RETURN_VALUE)
이 코드는 메소드의 반환 미확인 캐스트를 수행하고 있습니다. 코드는 캐스트가 안전하다는 것을 보장하도록 메소드를 호출하고 있을지도 모릅니다 만, FindBugs는 캐스트가 안전하다는 것을 확인할 수 없습니다. 프로그램의 로직이 캐스트가 실패하지 않도록 확실하게 확인하십시오.
BC : 항상 true를 반환 instanceof (BC_VACUOUS_INSTANCEOF)
이 instanceof는 항상 true를 돌려줍니다 (테스트 값이 null가 아닌 한). 이것은 안전하고 오해와 논리적 오류를 지적하고 있지 않은지 확인하십시오. 정말 null 七日 값을 테스트하고 싶다면, 아마, instanceof 대신 null 테스트를하는 것이 좋고, 더 명확 해집니다.
BSHIFT : 부호없는 오른쪽 시프트를 short / byte에 캐스트하는 (ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT)
이 코드는 부호 없음 캐스트의 실행 결과를 short 또는 byte에 캐스트하고 있습니다. 결과의 상위 비트는 버려집니다. 상위 비트가 버려지 때문에 부호와 부호없는 오른쪽 시프트 (시프트의 크기에 따라)의 차이가 없을지도 모릅니다.
CI : final 클래스가 protected 필드를 선언하고있다 (CI_CONFUSED_INHERITANCE)
이 클래스는 final로 선언되어 있지만 필드는 protected로 선언되어 있습니다. 클래스는 fainal이므로 파생 할 수 없습니다. , protected의 사용은 혼란입니다. 필드에 대한 액세스 한정자는 필드의 진정한 용도를 나타내므로 private 또는 public으로 변경해야합니다.
DB : 2 개 분기에 대해 동일한 코드를 사용하는 방법 (DB_DUPLICATE_BRANCHES)
이 메서드는 조건 분기의 두 분기를 구현하기 위해 동일한 코드를 사용하고 있습니다. 이것이 코딩 실수가 없는지 확인하십시오.
DB : switch 문 두 case에 대해 동일한 코드를 사용하는 방법 (DB_DUPLICATE_SWITCH_CLAUSES)
이 메소드는 switch 문 두 case를 구현하기 위해 동일한 코드를 사용하고 있습니다. 복제 코드의 case지도 모르고 코딩 실수 할지도 모릅니다.
DLS : 로컬 변수에 잘못된 대입 (DLS_DEAD_LOCAL_STORE)
이 명령은 로컬 변수에 값을 할당하고 있습니다 만, 값은 읽어 않거나 이후의 명령으로도 사용되지 않습니다. 많은 경우 계산 된 값이 결코 사용되지 않기 때문에,이 오류를 나타냅니다.
Sun의 javac 컴파일러가 final 지역 변수를 위해 종종 잘못된 저장을 생성하는 것에주의하십시오. FindBugs는 바이트 코드 기반 도구이므로 고장을 없애는 간단한 방법이 없습니다.
DLS : return 문에 쓸모 대입이 (DLS_DEAD_LOCAL_STORE_IN_RETURN)
이 문장은 return 문으로 로컬 변수에 할당하고 있습니다. 이 할당은 효과가 없습니다. 이 글이 정확한지 확인하십시오.
DLS : 로컬 변수에 잘못된 null 대입 (DLS_DEAD_LOCAL_STORE_OF_NULL)
이 코드는 로컬 변수에 null을 할당하고 있지만 할당 된 값은 판독되지 않습니다. 이 대입는 가비지 컬렉터를 돕기 위해 도입 된지도 모릅니다 만, Java SE 6에서는 더 이상 필요하지 않거나 유용하지 않습니다.
DLS : 필드를 가로막는 로컬 변수에 잘못된 대입 (DLS_DEAD_LOCAL_STORE_SHADOWS_FIELD)
이 명령은 로컬 변수에 값을 할당하고 있습니다 만, 값은 읽어 않거나 이후의 명령으로도 사용되지 않습니다. 많은 경우 계산 된 값이 결코 사용되지 않기 때문에,이 오류를 나타냅니다. 필드가 로컬 변수와 같은 이름입니다. 그렇지 않고 필드에 대입하려고 했습니까?
DMI : 하드 코드 된 경로 이름에 대한 참조가 (DMI_HARDCODED_ABSOLUTE_FILENAME)
이 코드는 하드 코드 된 절대 경로 이름을 사용하여 File 객체를 구축합니다 (예를 들어
new File ( "/ home / dannyc / workspace / j2ee / src / share / com / sun / enterprise / deployment") ;
).DMI : ObjectOutput에 기입 해지는 비 직렬화 가능 객체 (DMI_NONSERIALIZABLE_OBJECT_WRITTEN)
이 코드는
ObjectOutput.writeObject
에 비 직렬화 가능 객체를 전달하고 있다고 생각됩니다. 이 객체가 정말 비 직렬화 가능하면 오류를 초래합니다.DMI : substring (0)의 호출은 원래 값을 반환 (DMI_USELESS_SUBSTRING)
이 코드는 문자열
substring (0)
을 호출하고 있습니다 만, 원래 값을 반환합니다.Dm : Thread 객체가 Runnable이 기대되는 곳에 전달되는 (DMI_THREAD_PASSED_WHERE_RUNNABLE_EXPECTED)
Thread 객체가 Runnable이 기대되는 메소드에 파라미터로서 건네 있습니다. 이것은 매우 이상하고 논리적 오류를 나타내거나 의외의 행동의 원인이 될 수 있습니다.
Eq : 슈퍼 클래스의 equals 메소드를 오버라이드 (override)하지 않는 클래스 (EQ_DOESNT_OVERRIDE_EQUALS)
이 클래스는
equals
메소드를 정의하고있는 클래스를 확장하여 필드를 추가하고 있습니다 만,equals
메소드를 정의하지 않습니다. 따라서이 클래스의 인스턴스의 등가성은 서브 클래스로 추가 된 필드의 동일성을 무시합니다. 이것이 의도 한 것으로, 게다가equals
메소드를 오버라이드 할 필요가 없음을 보장합니다. 비록equals
메소드를 오버라이드 할 필요가 없다고해도, 서브 클래스에 대한equals
메소드가super.equals (o)
를 호출하여 결과를 반환 사실을 입증하기 위해 어쨌건간에,equals
메서드를 재정의하는 것을 검토 하십시오.Eq : 비정상적인 equals 메소드 (EQ_UNUSUAL)
이 클래스의
equals
메소드는 인수의 형태가this
객체의 형태와 호환성이 있음을 확인하기 위해 우리가 인식하고있는 패턴으로 아무것도하지 않습니다. 이 코드는 아무것도 잘못하지 않을지도 모릅니다 만 검토 할 가치가 있습니다.FE : 부동 소수점의 등가성을위한 테스트 (FE_FLOATING_POINT_EQUALITY)
이 연산은 등가성을 위해 2 개의 부동 소수점 값을 비교하고 있습니다. 부동 소수점 계산은 반올림을 동반 할지도 모르기 때문에 계산 된 float와 double의 값은 정확하지 않을지도 모릅니다. 통화 같은 정확해야한다 값을 위해
BigDecimal
과 같은 고정 정밀도 형을 사용하는 것을 고려하십시오. 정확할 필요가없는 값에 대한 몇 가지 범위에서 등가성을 위해 비교하는 것을 고려하십시오. 예를 들어if (Math.abs (x - y) <.0000001)
.
자세한 내용은 Java 언어 사양 4.2.4를 참조하십시오.FS : Boolean 형이 아닌 인수를 % b 서식 지시자를 사용하여 포맷하고있다 (VA_FORMAT_STRING_BAD_CONVERSION_TO_BOOLEAN)
Boolean 형이 아닌 인수를 % b 서식 지시자로 포맷되어 있습니다. 이것은 예외를 throw하지 않습니다. 대신 null이 아닌 값으로는 true, null는 false를 출력합니다. 서식 문자열이 기능은 이상한 의도 한 것은 아니다지도 모릅니다.
IA : 잠재적 인 상속 된 메소드인지 외부 메소드인지 모호한 메소드 호출 (IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD)
내부 클래스는 상속 된 메소드 또는 외부 클래스에 정의 된 메소드인지 어느 쪽이라고도 해석 할 수있는 메소드를 호출합니다. 예를 들어,
foo (17)
를 호출합니다. 그것은 슈퍼 클래스와 외부 메소드 모두에 정의되어 있습니다. Java 의미론에서는 상속 된 메서드를 호출하지만, 이것은 당신이 의도 한 것은 아니다지도 모릅니다.정말 상속 된 메소드를 호출하려고한다면 super으로 (예 : super.foo (17)) 호출하십시오. 그러면 외부 클래스의 메소드가 아닌 상속 된 메소드를 호출 싶은 것이이 코드를 읽는 사람과 FindBugs 명확합니다.
this.foo (17)
를 호출하면 상속 된 메소드가 불려갑니다. 그러나 FindBugs는 클래스 파일을 볼 뿐이므로,this.foo (17)
와foo (17)
의 호출의 차이를 말할 수 없습니다. 잠재적 인 모호한 호출에 대해 불평 것입니다.IC : 초기화가 순환하고있다 (IC_INIT_CIRCULARITY)
버그 인스턴스에 의해 참조되는 두 클래스의 정적 이니셜 라이저에서 순환이 감지되었습니다. 다양한 의외의 행동은 그런 순환에 기인 할 수 있습니다.
ICAST : 정수 나누기의 결과를 double 또는 float로 변환하고 (ICAST_IDIV_CAST_TO_DOUBLE)
이 코드는 정수 나누기의 결과를 double 또는 float로 변환합니다. 정수 나누기를하는 것은 제로에 가장 가까운 정수로 결과를 자릅니다. 결과가 double로 캐스팅 된 사실이 정도가 유지되어야 이었다는 것을 시사하고 있습니다. 아마 의미 된 것은 나눗셈을 실행하기 전에 피연산자 중 하나 또는 모두를 double로 캐스팅하는 것이 었습니다.
예를 들면 다음과 같습니다.int x = 2; int y = 5; // Wrong : yields result 0.0 double value1 = x / y; // Right : yields result 0.4 double value2 = x / (double) y;
ICAST : 정수 곱셈의 결과를 long으로 변환하는 (ICAST_INTEGER_MULTIPLY_CAST_TO_LONG)
이 코드는 다음과 같이 정수의 곱셈을 수행하고 결과를 long으로 변환합니다.
long convertDaysToMilliseconds (int days) {return 1000 * 3600 * 24 * days;}
long을 사용하여 곱셈을하면 결과가 오버 플로우 가능성을 피할 수 있습니다.
예를 들어 다음과 같이 수정할 수 있습니다.long convertDaysToMilliseconds (int days) {return 1000L * 3600 * 24 * days;}
또는
static final long MILLISECONDS_PER_DAY = 24L * 3600 * 1000; long convertDaysToMilliseconds (int days) {return days * MILLISECONDS_PER_DAY;}
IM : 평균 계산 오버 플로우가 발생할 가능성이있다 (IM_AVERAGE_COMPUTATION_COULD_OVERFLOW)
이 코드는 나누기 또는 부호 오른쪽 시프트를 사용하여 2 개의 정수의 평균을 계산하여 결과를 배열의 인덱스로 사용하고 있습니다. 평균이 매우 큰 경우 오버 플로우가 발생할 수 있습니다 (결과적으로 부정적인 평균 계산된다). 결과가 음수가 아닌 의도했다면 그 대신 부호없는 오른쪽 시프트를 사용할 수 있습니다. 즉,
(low + high) / 2
가 아닌(low + high) >>> 1
을 사용하십시오.이 버그는 이진 검색과 병합 정렬의 많은 이전의 구현에 존재합니다. Martin Buchholz가 JDK 라이브러리의 버그를 발견하고 수정하고 있습니다 . Joshua Bloch가 버그 패턴으로 발표했다 .
IM : 음수에서 작동하지 않는 이상 체크 (IM_BAD_CHECK_FOR_ODD)
이 코드는
x % 2 == 1
을 사용하여 값이 음수인지 확인하고 있습니다 만, 음수 (예를 들어,(-5) % 2 == -1
)이므로 작동하지 않습니다. 홀수 검사를 의도하고 있다면,x & 1 == 1
또는x % 2! = 0
을 사용하는 것을 고려하십시오.INT : 1을 법으로하는 정수 나머지 (INT_BAD_REM_BY_1)
어떤 식
(exp % 1)
항상 0을 돌려주는 것이 보증되고 있습니다. 그렇지 않고,(exp & 1)
또는(exp & 2)
를 의미하고 있었습니까?INT : 정수 무의미한 비트 마스크 연산 (INT_VACUOUS_BIT_OPERATION)
어떤 유용한 일도 아닌 정수 비트 연산 (AND, OR, XOR) (예 :
v & 0xffffffff
).INT : 정수 무의미한 비교 (INT_VACUOUS_COMPARISON)
항상 같은 값을 반환 정수 비교가 있습니다 (예를 들어
x <= Integer.MAX_VALUE
).MTIA : Servlet 클래스를 확장 한 클래스의 인스턴스 변수 사용 (MTIA_SUSPECT_SERVLET_INSTANCE_FIELD)
Servlet 클래스를 확장 한 클래스에서 인스턴스 변수를 사용하고 있습니다. Servlet 클래스의 하나의 인스턴스 만이 Java EE 프레임 워크에 의해 만들어진 멀티 스레드가 사용되므로,이 패러다임은 매우 문제가있어 권장하지 않습니다. 로컬 변수를 사용하는 것만을 고려하십시오.
MTIA : Struts Action을 확장 한 클래스의 인스턴스 변수 사용 (MTIA_SUSPECT_STRUTS_INSTANCE_FIELD)
Struts Action 클래스를 확장 한 클래스에서 인스턴스 변수를 사용하고 있습니다. Struts Action 클래스의 하나의 인스턴스 만 Struts 프레임 워크에 의해 만들어진 멀티 스레드가 사용되므로,이 패러다임은 매우 문제가있어 권장하지 않습니다. 로컬 변수를 사용하는 것만을 고려하십시오. 모니터를 제외하고 작성된 인스턴스 필드 만보고됩니다.
NP : readLine 메소드의 결과가 null인지 확인하지 값을 이용하고있다 (NP_DEREFERENCE_OF_READLINE_VALUE)
readLine
메소드의 결과가 null인지 확인하지 값을 이용하고 있습니다.readLine
메소드는 더 이상 읽을 텍스트 행이 없으면 null을 반환하기 때문에 NullPointerException이 발생합니다.NP : readLine 메소드의 결과를 바로 이용하고있다 (NP_IMMEDIATE_DEREFERENCE_OF_READLINE)
readLine
메소드의 결과를 즉시 사용할 수 있습니다.readLine
메소드는 더 이상 읽을 텍스트 행이 없으면 null을 반환하기 때문에 NullPointerException이 발생합니다.NP : null 것으로 알려진 값로드 (NP_LOAD_OF_KNOWN_NULL_VALUE)
여기에서 참조되는 변수는 이전에 null인지 체크하고 있기 때문에 null 인 것을 알 수 있습니다. 이것은 유효하지만 실수 할지도 모릅니다 (아마 다른 변수를 참조하는 것을 목적으로했다, 또는 이전의 null 체크에서 null이 아닌지 확인해야했다).
NP : 메소드는 매개 변수 nullness 주석을 강화하고있다 (NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION)
메소드는 오버라이드 (override)하는 메소드의 계약을 항상 구현해야합니다. 따라서, 메소드가 @Nullable로 표시되는 매개 변수를 가지고 있다면, 서브 클래스에서 매개 변수를 @Nonnull하고 메서드를 재정의해야하며 없습니다. 그러면 메소드가 null 매개 변수를 처리해야 계약을 깨고 있습니다.
NP : 메소드는 반환 nullness 주석을 완화하고있다 (NP_METHOD_RETURN_RELAXING_ANNOTATION)
메소드는 오버라이드 (override)하는 메소드의 계약을 항상 구현해야합니다. 따라서, 메소드가 @Nonnull 값을 반환하도록 주석하고 있다면, 서브 클래스에서 메소드가 @Nullable 또는 @CheckForNull 값을 반환하도록 주석하고 메서드를 재정의해야하며 없습니다. 그러면 메소드가 null를 돌려 종 수는없는 계약을 깨고 있습니다.
NP : null되어있을 가능성이있는 메소드의 반환 값을 이용하고있다 (NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE)
메소드의 반환 값을 null 체크하지 않고 이용하고 있습니다. 메소드의 반환 값은 null인지 체크해야합니다. 코드가 실행될 때 NullPointerException이 발생할 수 있습니다.
NP : null 값을 실행 불가능할지도 모른다 분기에서 이용하고있는 가능성이있다 (NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE)
분기 또는 문장이 실행된다면 null 값이 이용되고 NullPointerException이 발생합니다. 물론 문제는 분기 또는 문장이 실행 불가능하고, NullPointerException가 결코 발생할 수 없다는 것일지도 모릅니다. 그것을 결정하는 것은 FindBugs의 능력을 초과하고 있습니다. 이 값이 이미 null임을 검사했다는 사실에서 이것은 명확한 가능성입니다.
NP : 매개 변수는 비 null이어야하지만 null 허용으로 주석되는 (NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE)
이 매개 변수는 항상 비 null로 할 것을 요구하는 방법으로 사용되고 있지만 매개 변수는 명시 적으로 null 허용으로 주석되어 있습니다. 파라미터 나 주석 중 하나의 방법이 잘못된 것입니다.
NP : 기록되지 않은 public 또는 protected 필드의 읽기 (NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD)
프로그램은 결코 null 값이 아닌 값을 쓸 생각되지 않는다 public 또는 protected 필드의 null 값을 이용하고 있습니다. 필드가 분석에 의해 볼 수없는 기능을 통해 초기화되지 않는 한,이 값을 이용하면 NullPointerException이 발생합니다.
NS : 잠재적 인 비 단락 논리의 위험한 사용 (NS_DANGEROUS_NON_SHORT_CIRCUIT)
이 코드는 단락 논리 (&&와 ||) 대신 비 단락 논리 (&와 |)를 사용하고 있다고 생각됩니다. 또한 좌변 값이 우변을 평가하고 싶지 않아 (예외의 발생이나 연산이 많이 드는 부작용이 있기 때문에) 생각하고 있을지도 모릅니다. 비 단락 논리는 좌변을 알면 결과를 추론 할 수 있었다고해도 양쪽의 표현식이 평가됩니다. 이것은 비효율적 우변의 평가에서 오류가 발생하는 경우를 왼쪽에서 가드하고 있다면, 결과적으로 오류가 발생할 수 있습니다.
자세한 내용은 the Java Language Specification 을 참조하십시오.
NS : 비 단락 논리 의심 사용 (NS_NON_SHORT_CIRCUIT)
이 코드는 단락 논리 (&&와 ||) 대신 비 단락 논리 (&와 |)를 사용하고 있다고 생각됩니다. 비 단락 논리는 좌변을 알면 결과를 추론 할 수 있었다고해도 양쪽의 표현식이 평가됩니다. 이것은 비효율적 우변의 평가에서 오류가 발생하는 경우를 왼쪽에서 가드하고 있다면, 결과적으로 오류가 발생할 수 있습니다.
자세한 내용은 the Java Language Specification 을 참조하십시오.
PZLA : null가 아닌 길이가 0의 배열을 돌려주는 것을 검토 (PZLA_PREFER_ZERO_LENGTH_ARRAYS)
결과가 없음 (즉, 결과 빈 목록)을 나타 내기 위해 null 참조가 아닌 길이가 0의 배열을 반환하는 것은 많은 경우 더 나은 디자인입니다.
한편으로는 "이 질문에 대한 응답이 없다 '는 것을 보여주기 위해 null을 사용하는 것은 아마 적절합니다. 예를 들어,
File.listFiles ()
는 파일이없는 디렉토리를 주어진 경우는 하늘의리스트를 돌려 파일이 디렉토리가 아닌 경우 null을 반환합니다.QF : 복잡하거나 성공하거나 틀린 증가 for 루프 (QF_QUESTIONABLE_FOR_LOOP)
정말이 for 루프가 올바른 변수를 증가하고 있습니까? 다른 변수가 for 루프가 초기화되어 확인되는 것처럼 보입니다.
RCN : 비 null 값과 null 값과 중복 비교 (RCN_REDUNDANT_COMPARISON_OF_NULL_AND_NONNULL_VALUE)
이 메소드는 null가 아닌 것을 알고있는 참조와 null 것으로 알려진 다른 참조와 비교합니다.
RCN : 2 개의 null 값의 중복 비교 (RCN_REDUNDANT_COMPARISON_TWO_NULL_VALUES)
이 메소드는 둘 다 분명히 null 것으로 알려진 2 개의 참조 중복 비교합니다.
RCN : null가 아닌 것을 알고있는 값의 중복 null 체크 (RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE)
이 메소드는 null가 아닌 것을 알고있는 값의 중복 null 체크가 있습니다.
RCN : null 것으로 알려진 값의 중복 null 체크 (RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE)
이 메소드는 null 것으로 알려진 값의 중복 null 체크가 있습니다.
REC : 예외가 발생되지 않더라도 예외를 포착하고있다 (REC_CATCH_EXCEPTION)
이 메소드는 예외 객체를 잡을 try-catch 블록을 사용하고 있습니다 만, 예외는 try 블록에서 throw되지 않습니다. 또한 실행시 예외는 명시 적으로 캐치되지 않습니다. 각각의 catch 블록이 동일한 많은 예외 형을 잡을 수의 단축형으로
try {...} catch (Exception e) {something}
을 사용할 수 일반적인 버그 패턴입니다. 그러나이 구문은 잘못 실행시 예외도 포착하기 때문에 잠재적 인 버그를 숨 깁니다.더 좋은 방법은 명시 적으로 캐치하는 것보다 발생되는 특정 예외를 throw합니다. 또는 다음과 같이 명시 적으로 RuntimeException을 잡아 다시 발생하여 비 실행시 예외를 캐치합니다.
try { ... } catch (RuntimeException e) { throw e; } catch (Exception e) { ... deal with all non-runtime exceptions ... }
RI : 슈퍼 클래스와 동일한 인터페이스를 구현하고있는 클래스 (RI_REDUNDANT_INTERFACES)
이 클래스는 슈퍼 클래스에 의해 구현되는 인터페이스를 구현하는 것을 선언하고 있습니다. 슈퍼 클래스가 인터페이스를 구현하기 때문에, 이것은 중복입니다. 기본적으로 모든 서브 클래스도이 인터페이스를 구현합니다.이 클래스가 생성 된 후 상속 계층 구조가 바뀐 것을 지적 할지도 모릅니다. 인터페이스의 구현의 소유권을 고려해야합니다.
RV : String.indexOf의 결과가 긍정적 있는지 확인하고있다 (RV_CHECK_FOR_POSITIVE_INDEXOF)
이 메소드는
String.indexOf
를 호출 해 결과가 긍정적인지 확인합니다. 결과가 부의 있는지 확인이 훨씬 전형적인입니다. 체크되는 부분 문자열이 선두 이외의 장소에서 출현하는 경우에만 바로됩니다.RV : readLine 메소드의 결과를 null이 아닌지 확인 후 버리고있다 (RV_DONT_JUST_NULL_CHECK_READLINE)
readLine
메소드의 반환 값을 null이 아닌지 확인 후 버리고 있습니다. 거의 모든 상황에서 결과가 null가 아닌 경우 반환 값을 사용하고자하는 것입니다. 다시readLine
메소드를 호출하면 다른 행을 얻을 수 있습니다.RV : 해시 코드의 나머지는 부의지도 모른다 (RV_REM_OF_HASHCODE)
이 코드는 해시 코드를 계산하여 다른 값을 법으로하는 잉여를 계산합니다. 해시 코드는 음수가 잉여 연산의 결과도 부정적인됩니다.
계산 결과가 음수가 아닌 것을 확인하고 싶다면 코드를 변경할 필요가 있을지도 모릅니다. 제수가 2의 거듭 제곱 인 것을 알고 있다면, 대신에 비트 연산을 사용할 수 있습니다 (즉,
x.hashCode () % n
대신x.hashCode () & (n-1)
를 사용하여 하십시오). 이것은 아마도 나머지를 계산하는 것보다 빠릅니다. 제수가 2의 거듭 제곱이라는 것을 알고 있지 않다면, 나머지 연산 결과의 절대 값을 가져하십시오 (즉Math.abs (x.hashCode () % n)
).RV : 부호있는 32 비트 정수 난수의 잉여 (RV_REM_OF_RANDOM_INT)
이 코드는 부호있는 정수 난수를 생성하여 다른 값을 법으로하는 잉여를 계산합니다. 난수는 음이되고, 나머지 연산의 결과도 음수가됩니다. 이것이 의도 한다는 것을 확실히하십시오. 대신
Random.nextInt (int)
를 사용하는 것이 좋습니다.RV : 메소드가 값을 무시하고, 이것은 실수가 아닌가요? (RV_RETURN_VALUE_IGNORED_INFERRED)
이 코드는 메소드를 호출하여 반환 값을 무시하고 있습니다. 반환 값은 메소드가 호출되는 형태와 같은 형태입니다. 그리고 우리의 분석에서 반환 값이 중요하다지도 모른다 것 같습니다 (예를 들어,
String.toLowerCase ()
의 반환 값을 무시하는 것 같은).우리는 반환 값을 무시할 수 메서드 본문의 간단한 분석에서 나쁜 생각지도 모른다고 추측하고 있습니다. 이 메소드의 반환 값을 무시하는 것이 중요한가? 허용 여부에 대해 FindBugs에 지시하는 @CheckReturnValue 주석 사용할 수 있습니다.
반환 값을 무시하는 실수가 아닐까 결정하기 위해 엄격하게 조사하십시오.
RV : 부작용이없는 메소드의 반환 값은 무시된다 (RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT)
이 코드는 메서드를 호출하여 반환 값을 무시하고 있습니다. 그러나 분석 방법 (있는 경우 서브 클래스의 구현도 포함)이 반환 값 이외 효력이 없다는 것을 보여줍니다. 이 호출은 제거 할 수 있습니다.
우리는 가능한 한 고장을 줄이려고하고 있습니다 만, 어떤 경우에서는이 경고가 틀릴 수도 있습니다. 자주 묻는 가양입니다.
- 메소드는 오버라이드 된 해석 대상 외 다른 프로젝트에서 부작용이 초래 될 수 있도록 설계되어있다
- 방법은 부작용이 있을지도 모른다 클래스 로더를 트리거하도록 호출되는
- 메서드는 예외를 얻기 위해 호출되는
우리의 가정이 정확하지 않다고 느낀다면 FindBugs이 메소드의 반환 값이 무시되는 것을 허용하도록 지시하는 @CheckReturnValue 주석을 사용 할 수 있습니다.
SA : 필드의 이중 할당 (SA_FIELD_DOUBLE_ASSIGNMENT)
이 메소드는 필드의 이중 대입 있습니다.
예를 들어 다음과 같은 코드입니다.int x, y; public void foo () { x = x = 17; }
필드에 2 회 대입하는 것은 도움이되지 않기 때문에 논리적 오류 또는 오타지도 모릅니다.
SA : 로컬 변수의 이중 할당 (SA_LOCAL_DOUBLE_ASSIGNMENT)
이 메소드는 로컬 변수의 이중 대입 있습니다.
예를 들어 다음과 같은 코드입니다.public void foo () { int x, y; x = x = 17; }
변수에 동일한 값을 2 회 대입하는 것은 도움이되지 않기 때문에 논리적 오류 또는 오타지도 모릅니다.
SA : 로컬 변수의 자기 대입 (SA_LOCAL_SELF_ASSIGNMENT)
이 메소드는 로컬 변수의 자기 대입 있습니다.
예를 들어 다음과 같은 코드입니다.public void foo () { int x = 3; x = x; }
그런 대입 쓸모 없기 때문에, 논리적 오류 또는 오타지도 모릅니다.
SF : 하나의 case가 다음 case로 통과 switch 문장을 발견했다 (SF_SWITCH_FALLTHROUGH)
이 메소드는 하나의 case가 다음 case로 통과 switch 문이 있습니다. 일반적으로 break 또는 return이 case를 종료해야합니다.
SF : default가없는 switch 문을 발견했다 (SF_SWITCH_NO_DEFAULT)
이 메소드는 default가없는 switch 문이 있습니다. 일반적으로 default를 준비해야합니다.
분석은 생성 된 바이트 코드를 볼 뿐이므로 default가 switch 문장의 끝에 있고, 다른 경우에 break 문이 포함되어 있지 않으면 오류 검출 트리거됩니다.
ST : 인스턴스 메소드에서 static 필드에 기록 (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)
이 인스턴스 메서드는 static 필드에 기록하고 있습니다. 여러 인스턴스가 조작되어 있다면 제대로시키는 것은 어렵습니다. 일반적으로 나쁜 좋습니다.
Se : 서브 클래스에서 상속 할 수없는 private 한 readResolve 메소드 (SE_PRIVATE_READ_RESOLVE_NOT_INHERITED)
이 클래스는 private 인
readResolve
메소드를 정의하고 있습니다. 따라서이 메소드는 서브 클래스에서 상속 할 수 없습니다. 이것이 의도 한 것이라면 잘못 할지도 모르지만 확인하기 위해 검토해야합니다.Se : Serializable하지 않은 클래스의 transient 필드 (SE_TRANSIENT_FIELD_OF_NONSERIALIZABLE_CLASS)
필드는 transient로 선언하고 있습니다 만, 클래스는 직렬화 가능하지 않기 때문에 전혀 효과가 없습니다. 클래스가 transient 일 때의 흔적일지도 모릅니다 또는 직렬화기구를 오해하고 있는지도 모릅니다.
TQ : 값 형식 한정자를 필요로하고 있지만, 알 수 없음으로 표시되는 (TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_ALWAYS_SINK)
값은 항상 형태 수식 자에 의해 표시된 값임을 필요로하는 방법으로 사용되고 있습니다. 그러나 값은 어디에서 그 형태 한정자가 필요한지 모르겠다 고 말했다 명시적인 주석이 있습니다. 사용법 또는 주석 중 하나가 잘못된 것입니다.
TQ : 값 형식 한정자를 필요로하지 않지만, 알 수 없음으로 표시되는 (TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_NEVER_SINK)
값은 형태 수식 자에 의해 표시된 값이 아닌 것을 필요로하는 방법으로 사용되고 있습니다. 그러나 값은 어디에서 그 형태 수식자가 있느냐 금지되어기도하는지 모른다고 말했다 명시적인 주석이 있습니다. 사용법 또는 주석 중 하나가 잘못된 것입니다.
UC : 조건은 효과가 없다 (UC_USELESS_CONDITION)
이 조건은 항상 관계하고있는 변수의 값이 이전에 짜진 것과 같은 결과를 만들어냅니다. 아마도 뭔가 다른 것을 의미하고 있었는지, 혹은 조건을 제거 할 수 있습니다.
UC : 조건 변수 유형에 대한 효과가 없다 (UC_USELESS_CONDITION_TYPE)
이 조건은 관계하고있는 변수 유형 범위를 위해 항상 같은 결과를 만들어냅니다. 아마도 뭔가 다른 것을 의미하고 있었는지, 혹은 조건을 제거 할 수 있습니다.
UC : 쓸모없는 객체를 만든 (UC_USELESS_OBJECT)
우리의 분석에서 객체가 쓸모없는 것을 보여줍니다. 작성된 변경되어 있습니다 만, 값은 메소드 밖에 나지 않고 부작용이 없습니다. 과실 또는 객체가 사용되는 것을 의도하고 있던 가지 중 하나 또는 제거 할 수 있습니다.
이 분석은 거의 오 검출하는 것은 아닙니다. 자주 오진 사례입니다.
- 암시 적으로 애매한 예외를 throw 한
- 코드를 일반화하여 스텁으로 사용 된
- 약점 / 소프트 참조 객체에 대한 강한 참조를했다
UC : 쓸모없는 객체를 스택에서 만든 (UC_USELESS_OBJECT_STACK)
이 개체는 부작용이없는 수정을 위해 작성되어 있습니다. 아마도 뭔가 다른 것을 의미하고 있었는지 또는 개체를 제거 할 수 있습니다.
UC : 쓸모없는 비어 있지 않은 void 메소드 (UC_USELESS_VOID_METHOD)
우리의 분석이 비어 있지 않은 void 메소드가 실제로 유용한 일을하지 않는 것을 보여줍니다. 확인하십시오.아마 그 코드가 잘못되었거나 몸을 완전히 제거 할 수 있습니다.
우리는 가능한 한 고장을 줄이려고 노력하고 있지만, 어떤 경우에서는 경고 틀릴 수도 있습니다. 자주 묻는 가양 예입니다.
- 방법은 부작용이 있을지도 모른다 클래스의로드를 트리거하는 것을 의도하고있다
- 메서드는 암시를 알기 어려운 예외를 던질 예정되어있다
UCF : 쓸모 제어 흐름 (UCF_USELESS_CONTROL_FLOW)
이 메소드는 분기하는지 여부에 관계없이 제어 흐름이 동일한 위치로 이어지는 쓸모없는 제어 흐름 문이 있습니다.
예를 들어, 이것은 빈if
문이 원인이됩니다.if (argv.length == 0) { // TODO : handle this case }
UCF : 다음 줄에 계속 그냥 쓸모 제어 흐름 (UCF_USELESS_CONTROL_FLOW_NEXT_LINE)
이 메소드는 분기하는지 여부에 관계없이 제어 흐름이 같은가 다음 행으로 이어지는 쓸모없는 제어 흐름 문이 있습니다.
종종 실수로if
문장의 본체를 공문을 사용한 것이 원인입니다.if (argv.length == 1); System.out.println ( "Hello"+ argv [0]);
UrF : 읽은없는 public 또는 protected 필드 (URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD)
이 필드는 결코 읽 없습니다. 필드는 public 또는 protected이므로, 아마, 그것은 해석의 일부로 보이지 않는 클래스에서 사용되는 것을 의도하고 있습니다. 그렇지 않으면 클래스에서 제거하는 것을 고려하십시오.
UuF : 사용하지 않는 public 또는 protected 필드 (UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD)
이 필드는 결코 사용되지 않습니다. 필드는 public 또는 protected이므로, 아마, 그것은 해석의 일부로 보이지 않는 클래스에서 사용되는 것을 의도하고 있습니다. 그렇지 않으면 클래스에서 제거하는 것을 고려하십시오.
UwF : 생성자에서 초기화되지 않은 필드를 null 체크없이 null 값을 이용하고있다 (UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)
이 필드는 어떤 생성자 중에서도 결코 초기화되지 않습니다. 따라서 개체가 구축 된 후 null 일 가능성이 있습니다. 어딘가 다른 곳에서 값이로드되어 null 체크없이 null 값이 사용됩니다. 필드가 초기화되기 전에 이용하면 NullPointerException이 발생하므로 부정확 또는 의심 설계지도 모릅니다.
UwF : 기록 있지되고 있지 않은 public 또는 protected 필드 (UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD)
이 public 또는 protected 필드는 기록되지 않습니다. 이 필드에서의 읽기는 기본값을 반환합니다. 오류를 확인하십시오 (필드는 초기화해야 했습니까?). 쓸모 있다면 제거하십시오.
XFB : XML 인터페이스의 특정 구현의 인스턴스를 작성하는 방법 (XFB_XML_FACTORY_BYPASS)
이 메서드는 XML 인터페이스의 특정 구현의 인스턴스를 만들고 있습니다. 제공된 팩토리 클래스를 사용하여 객체를 생성하고 실행시에 구현을 변경할 수 있도록하는 것이 바람직합니다.
자세한 내용은 다음을 참조하십시오.- javax.xml.parsers.DocumentBuilderFactory
- javax.xml.parsers.SAXParserFactory
- javax.xml.transform.TransformerFactory
- org.w3c.dom.Document.create XXXX
Last updated 03/07/2015 03:06:03.
Send Comments to findbugs@cs.umd.edu
반응형'JAVA' 카테고리의 다른 글
Apache Struts2 보안취약점 (0) 2016.04.27 node.js 및 python 등의 서버 스크립트 언어의 eval 취약점 (0) 2015.04.15 가비지 컬렉션... (0) 2014.10.30 Ubuntu 에 Grails 설치하기 (0) 2014.09.25 공공데이터를 사용하려면 자바버전을 강제 하는군요. (0) 2014.09.23