检测器

qianmoQqianmoQ· 更新于 2026-09-30· 阅读 196 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

本文档列出了 SpotBugs 中的所有检测器。

标准检测器

以下检测器默认启用:

OverridingMethodsMustInvokeSuperDetector

查找必须调用 super 的重写方法。

FindRoughConstants

查找与 Math.PI 等已知值大致(但并不精确)相等的常量。

SynchronizeAndNullCheckField

该检测器查找先进行同步、随后进行空值检查的字段。

InitializeNonnullFieldsInConstructor

查找在构造方法中未被赋值的非空字段。

BooleanReturnNull

查找返回类型为 Boolean 但显式返回 null 值的方法。

OptionalReturnNull

查找返回类型为 Optional 但显式返回 null 值的方法。

ConfusionBetweenInheritedAndOuterMethod

查找继承方法与外部类方法之间可能产生的混淆。

SynchronizationOnSharedBuiltinConstant

该检测器查找针对共享内置常量(例如 String)的同步操作。

NoteUnconditionalParamDerefs

分析应用程序中的所有方法,以确定哪些方法会无条件地解引用参数。该信息会在后续的分析阶段中使用,用于查找可能向这些方法传递 null 值的调用点。

这是一个较慢的检测器。

SynchronizeOnClassLiteralNotGetClass

查找对 getClass 的返回结果进行同步,而不是对类字面量进行同步的代码。

InfiniteRecursiveLoop

查找无限递归循环。

InfiniteLoop

查找无限循环。

VolatileUsage

查找 volatile 字段使用中的缺陷模式。

InheritanceUnsafeGetResource

查找对 this.getClass().getResource(...) 的使用,如果该类被另一个包中的类继承,可能产生意外结果。

DoInsideDoPrivileged

查找应当在 doPrivileged 块内执行的代码。

HugeSharedStringConstants

此检测器查找在多个类文件中重复出现的字符串常量。

FinalizerNullsFields

此检测器查找将类字段置为 null 的终结器。这无助于垃圾收集器,将字段置为 null 没有任何效果。

MutableEnum

查找并警告可变的枚举字段。

InconsistentAnnotations

此检测器发现直接应用于方法参数的类型限定符与这些方法参数的使用之间的不一致之处。

RepeatedConditionals

此检测器查找包含重复条件测试的代码,例如 (x == 5 || x == 5)。

RedundantConditions

此检测器查找包含无效条件的代码,例如表达式 (x >= 10 && x >= 5) 中的第二个条件。

FormatStringChecker

检查不正确的格式字符串。

LostLoggerDueToWeakReference

该检测器会找出在 OpenJDK 6 下行为不同的代码,因为 OpenJDK 6 使用弱引用来持有 Logger。

EqualsOperandShouldHaveClassCompatibleWithThis

检查 equals 方法是否对其操作数是否为某个类的实例进行判断,而该类与定义该 equals 方法的类不兼容。

CheckImmutableAnnotation

查找违反标注为 net.jcip.annotations.Immutable 或 javax.annotation.concurrent.Immutable 的类相关规则的情况。

DontCatchIllegalMonitorStateException

该检测器会查找捕获 IllegalMonitorStateException 的 try-catch 块。

CloneIdiom

该检测器会查找编写可克隆类时违反惯用写法的情况。

ComparatorIdiom

该检测器会查找编写实现 Comparator 的类时违反惯用写法的情况。

FindFieldSelfAssignment

该检测器会查找通过读取同一字段的值来为该字段赋值的位置。

FindSelfComparison

该检测器会查找将值与自身进行比较的位置。

FindSelfComparison2

该检测器会查找将值与自身进行比较的位置。

DroppedException

该检测器会查找捕获了异常但未对该异常做任何处理的代码。

LoadOfKnownNullValue

查找对已知为 null 的值的加载操作。

DumbMethodInvocations

该检测器用于查找传递给方法的错误参数(例如 substring(0))。

URLProblems

java.net.URL 上的 equals 和 hashCode 方法会解析域名。因此,这些操作的开销可能非常大,该检测器用于查找可能调用这些方法的地方。

DumbMethods

该检测器用于查找对无意义方法的调用,例如无参的 String 构造函数。

NumberConstructor

查找以基本类型为参数调用 Number 构造函数的情况。

FindSqlInjection

该检测器使用数据流分析来查找对 SQL 语句的 execute 方法的调用,其中作为参数传递的并非常量字符串。

FindDoubleCheck

该检测器用于查找双重检查锁定的实例。

FindFinalizeInvocations

该检测器用于查找对 finalize() 的调用以及其他与终结器相关的问题。

FindHEmismatch

该检测器用于查找 hashCode() 和 equals() 方法定义中的问题。

OverridingEqualsNotSymmetrical

查找重写超类中 equals 方法、且其等价关系可能不对称的 equals 方法。

FindNakedNotify

该检测器查找看起来不会修改可变对象状态的 notify() 调用。

FindReturnRef

该检测器查找返回可变静态数据的方法。

FindRunInvocations

该检测器查找对 Thread.run() 的调用。它是一个快速检测器。

SwitchFallthrough

该检测器查找包含贯穿(fall through)的 switch 语句。

FindSpinLoop

该检测器查找通过不断读取某个字段来自旋的循环。

FindNonShortCircuit

该检测器查找可疑的非短路布尔运算符用法(使用了 | 和 & 而不是 || 和 &&)。

FindTwoLockWait

该检测器用于查找在持有两个(或更多)锁的情况下调用 wait() 的情况。这是一个较慢的检测器。

FindUnconditionalWait

该检测器用于查找不在条件语句或循环中的 wait() 调用。

FindUninitializedGet

该检测器用于查找构造函数中对未初始化字段的读取。

DontUseEnum

检查字段和方法是否未使用 assert 或 enum 作为名称,因为它们在 Java 5 中是关键字。

FindUnsyncGet

该检测器用于查找 getter 和 setter 方法中 getter 未加同步而 setter 已加同步的情况。

InitializationChain

该检测器用于查找可能存在的循环类初始化依赖关系。

IteratorIdioms

该检测器用于查找 Iterator 类定义方式中存在的问题。

PreferZeroLengthArrays

该检测器用于查找既返回数组又返回显式 null 引用的方法。在这种情况下,通常返回零长度数组比返回 null 引用更可取。

SynchronizingOnContentsOfFieldToProtectField

该检测器用于查找似乎为了保护对某个字段的更新而在该字段上进行同步的代码。

MutableLock

该检测器用于查找在从被修改字段中读取的对象上进行同步的情况。

FindUselessObjects

查找无用的对象。

MutableStaticFields

该检测器用于查找可能被恶意代码修改的静态字段。

命名

该检测器用于查找可疑的命名方法。

ReadReturnShouldBeChecked

该检测器用于查找调用了 InputStream.read() 或 InputStream.skip() 却忽略其返回值的情况。

SerializableIdiom

该检测器用于查找 Serializable 类实现中潜在的问题。

StartInConstructor

该检测器查找会启动线程的构造函数。

FindBadForLoop

该检测器查找不正确的 for 循环。

ExplicitSerialization

查找通过 readObject 和 writeObject 进行的显式序列化,作为该类确实被序列化的证据。

  • ``

UnreadFields

此检测器用于查找其值从未被读取的字段。

WaitInLoop

此检测器用于查找未处于循环中的 wait() 调用。

FindComparatorProblems

此检测器用于查找 Comparator.compare 或 Comparable.compareTo 实现中的问题。

FindNullDeref

此检测器用于查找可能发生空指针异常的地方,同时也查找引用值与 null 的冗余比较。这是一个较慢的检测器。

FindNullDerefsInvolvingNonShortCircuitEvaluation

该检测器用于查找可能发生空指针异常的位置,在这些位置上使用了非短路求值,导致常用的技术手段失效。

FindOpenStream

该检测器用于查找未逸出方法、且在方法的所有退出路径上似乎都未被关闭的 IO 流对象。它是一个较慢的检测器。

FindUselessControlFlow

该检测器用于查找没有任何作用的控制流语句。

FindUnreleasedLock

此检测器用于查找已被获取、但在方法的所有退出路径上均未释放的 JSR-166(java.util.concurrent)锁。它是一个中等速度的检测器。注意,要使用此检测器,需要在辅助类路径中包含 java.util.concurrent 包(或者正在分析该包本身)。

FindRefComparison

此检测器用于查找使用 == 或 != 运算符比较两个引用值的位置,且该类属于某种类型(例如 java.lang.String),比较引用值通常是一种错误。它是一个较慢的检测器。

FindMismatchedWaitOrNotify

此检测器用于查找看似未在当前被锁定的对象上调用 wait()、notify() 或 notifyAll() 的情况。它是一个中等速度的检测器。该检测器已被禁用,因为它仍在开发中,并且会产生过多的误报。

FindEmptySynchronizedBlock

此检测器用于查找空的 synchronized 块。

FindInconsistentSync2

此检测器用于查找在加锁方面访问方式不一致的字段。它是一个较慢的检测器。

FindLocalSelfAssignment2

此检测器用于查找局部变量的自赋值。

IncompatMask

该检测器用于查找可疑的按位逻辑表达式。

LazyInit

该检测器用于查找字段不是 volatile 的延迟字段初始化。这是一个中等速度的检测器。

FindJSR166LockMonitorenter

该检测器用于查找在 JSR166 锁上执行的普通同步。这是一个中等速度的检测器。

FindUncalledPrivateMethods

该检测器用于查找从未被调用的私有方法。

UncallableMethodOfAnonymousClass

该检测器用于查找匿名内部类,这些类定义了可能本意是重写、但实际上并未重写父类中方法的方法。

StringConcatenation

该检测器用于查找在循环中使用 + 进行的字符串拼接。

InvalidJUnitTest

该检测器用于查找格式不正确的 JUnit 测试。

BadlyOverriddenAdapter

该检测器用于查找扩展 Adapter 类却以错误的签名重写 Listener 方法的代码。

BadResultSetAccess

该检测器用于查找对结果集的 getXXX 或 setXXX 方法的调用,其中字段索引为 0。由于 ResultSet 的字段索引从 1 开始,因此这始终是一个错误。

SuperfluousInstanceOf

此检测器查找使用 instanceof 运算符进行的类型检查,其中判断可以静态完成。

SuspiciousThreadInterrupted

此检测器查找在非静态上下文中对 Thread.interrupted() 的调用。如果它是通过 Thread.currentThread().interrupted() 调用的,那只是无用的操作,直接使用 Thread.interrupted() 即可。但是,如果它是在任意线程对象上调用的,那么这很可能是一个错误,因为 interrupted() 总是在当前线程上调用。

FindDeadLocalStores

此检测器查找对局部变量的赋值,这些赋值随后从未被读取。它是一个中等速度的检测器。

FindMaskedFields

此检测器查找被方法中定义的局部字段所遮蔽的类级别字段。

WrongMapIterator

此检测器查找使用从 keySet 迭代器获取的键来访问 Map 条目的值的情况。

InstantiateStaticClass

此检测器查找基于仅定义静态方法的类来创建对象的代码。

RuntimeExceptionCapture

此检测器查找捕获 Exception 的 catch 子句,而该代码块中没有任何代码会抛出 Exception。

DontCatchNullPointerException

不应捕获空指针异常。

FindFloatEquality

查找浮点数相等性表达式。一个快速的检测器。

FindUnsatisfiedObligation

此检测器用于查找在方法的所有退出路径上均未被清理的 I/O 流和数据库资源。这是一个运行较慢的检测器。

UnnecessaryMath

此检测器用于查找对常量值调用 java.lang.Math 静态方法的代码,而其结果值在静态分析中是已知常量。直接使用该常量不仅更快,有时也更准确。

RedundantInterfaces

此检测器用于查找声明实现了与其父类相同接口的类。这是多余的:如果父类实现了某个接口,子类自然也实现了该接口。

MultithreadedInstanceAccess

此检测器用于查找实现 Struts 框架时的潜在问题。

BadUseOfReturnValue

查找在检查返回值非空之后又将其丢弃的情况。

MethodReturnCheck

此检测器用于查找对方法返回值被可疑地忽略的调用。

IDivResultCastToDouble

此检测器用于查找整数除法结果被转换为 double 的位置。通常,本意是先把整数操作数转换为 double,再进行除法运算。

FindBadCast2

该检测器使用数据流分析查找对象引用的错误转换。

FindUseOfNonSerializableValue

该检测器查找在要求可序列化的上下文中使用了不可序列化对象的情况。

BadSyntaxForRegularExpression

该检测器查找语法无效的正则表达式。

VarArgsProblems

查找由 Java 5 可变参数引起的问题。

FindPuzzlers

该检测器查找 Joshua Bloch 和 Neal Gafter 在其著作《Programming Puzzlers》中提到的各种小错误。

IntCast2LongAsInstant

查找使用 32 位值来表示自纪元以来毫秒数的代码。

FindSleepWithLockHeld

该检测器查找在持有锁的情况下调用 Thread.sleep() 的代码。这是一个运行较慢的检测器。

DuplicateBranches

该检测器查找 if/else 或 switch 语句中两个分支包含相同代码的情况,从而使判断失去意义。这通常是由于复制粘贴了两个分支,导致其中一个分支的逻辑不正确。

XMLFactoryBypass

该检测器查找对 XML 接口实现类的直接实例化。这样会使代码与特定实现绑定,而不是使用所提供的工厂模式来创建这些对象。

ConfusedInheritance

该检测器用于查找声明了 protected 成员的 final 类。由于该类无法被继承,对成员使用 protected 访问权限是不正确的。访问权限应改为 public 或 private,以体现该字段的真实意图。这很可能是由于该类的用途发生了变化,但并未将整个类全部改造成新范式所致。

QuestionableBooleanAssignment

该检测器用于查找在条件表达式中将字面布尔值简单赋值给变量的情况。

AppendingToAnObjectOutputStream

查找向对象输出流追加内容的尝试。

StaticCalendarDetector

该检测器会警告类型为 java.util.Calendar 或 java.text.DateFormat(及其子类)的静态字段,因为 Calendar 在本质上不适用于多线程环境。

CheckTypeQualifiers

检查是否违反 JSR-305 类型限定符注解所指定的属性。

CrossSiteScripting

该检测器用于查找明显、突出的跨站脚本漏洞案例。

DontIgnoreResultOfPutIfAbsent

检查在忽略 putIfAbsent 的返回值时,作为第二个参数传入的值没有被重复使用。

ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass

检查从超类的构造方法中调用的方法。

AtomicityProblem

查找在并发抽象上执行的、不会以原子方式执行的操作序列(例如 get/put)。

DefaultEncodingDetector

检查对那些使用用户默认平台编码进行字节与 String(或 String 与字节)转换的方法的调用。这会导致应用程序的行为在不同平台之间存在差异。

CheckReliasingNullnessAnnotation

检查重写的方法是否放宽了返回值上的 @Nonnull(改为 @CheckForNull),或放宽了参数上的 @CheckForNull(改为 @Nonnull)。

DontAssertInstanceofInTests

用于检测 JUnit 测试中通过断言 instanceof 运算符来检查对象类型的模式。

应当避免这种做法,因为不正确的强制类型转换所导致的 ClassCastException,可能比断言 instanceof 运算符结果时产生的 "false is not true" 消息提供更多关于错误原因的信息。

这是一个快速检测器

FindBadEndOfStreamCheck

用于检测在与 -1 比较之前先对 java.io.FileInputStream.read() 或 java.io.FileReader.read() 的返回值进行转换的模式。

两个方法都返回一个 int。如果将该 int 转换为 byte(FileInputStream.read() 的情况),则 -1 与字节 0xFF 将无法区分。如果转换为 char(FileReader.read() 的情况),则 -1 会变为 0xFFFF,即 Character.MAX_VALUE,因为在 Java 中字符是无符号的。

ReflectionIncreaseAccessibility

检测其实例化参数中所传入类的公共方法。

攻击者可能会用一个没有公共构造方法的类来调用此方法。

FindOverridableMethodCall

检测构造方法、clone() 或 readObject() 方法调用可被重写方法的模式。

从构造方法中调用可被重写的方法可能导致使用未初始化的数据。从 clone() 或 readObject() 方法中调用此类方法则不安全。

ConstructorThrow

查找会抛出异常的构造方法。

FindInstanceLockOnSharedStaticData

检测共享静态数据被实例级别的非静态同步方法修改,或在使用非静态锁对象的同步块内被修改的模式。

程序不得使用实例锁来保护静态共享数据,因为当创建两个或多个类的实例时,实例锁将不起作用。因此,若不使用静态锁对象,共享状态将无法免受并发访问的影响。

DontUseFloatsAsLoopCounters

检查循环计数器中的浮点数。

PermissionsSuper

检查实现接口 java.security.SecureClassLoader 的类的 getPermissions() 方法。这些方法必须始终调用 super.getPermissions(),以获取其最终返回对象的初始值。

FindPotentialSecurityCheckBasedOnUntrustedSource

查找在进入 doPrivileged 块之前,基于不可信源进行的潜在安全检查。

FindAssertionsWithSideEffects

查找具有副作用的断言。

FindPublicAttributes

该检测器查找既为 public、又被类的方法写入的属性。

FindVulnerableSecurityCheckMethods

执行安全检查的方法应当防止被覆盖,因此它们必须声明为 private 或 final。否则,当恶意子类覆盖这些方法并跳过检查时,这些方法可能被破坏。

FindArgumentAssertions

查找用于校验 public 方法参数的断言。

UnnecessaryEnvUsage

检查对 System.getenv() 的调用,其中相应变量同样存在等价的 Java 属性。

MultipleInstantiationsOfSingletons

该检测器查找对使用单例设计模式编写类的相关惯用写法的违反情况。

评论

登录后参与评论

正在加载评论…