Object.requireNonNull 跳过可为空的字符串

Object.requireNonNull skip nullable String

我的桌面客户端通过 Hessian 与服务器通信。

客户端调用搜索 API 方法通过传递的字符串 teamId.

查找成员
public Member findMemberByTeamId(FeedProvider provider, String teamId)
{
    Objects.requireNonNull(provider, "Provider can't be a null");
    Objects.requireNonNull(teamId, "Team id can't be a null");

    long starttime = System.currentTimeMillis();

    logger.debug("Started searching member: provider={}, teamId={}", provider, teamId);

    return dao.findMemberByTeamId(provider, teamdId);
}

但是我遇到了异常:

[WEB-68] [Service] ERROR Error occurred while downloading member: provider = Hedgehog, teamId = null org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT * FROM TEAM WHERE ID = ?]; ORA-01722: invalid number ; nested exception is java.sql.SQLSyntaxErrorException:

在日志中我发现了以下行:
[WEB-34] [Service] DEBUG Started searching member: provider=Hedgehog, teamId=null

如果我直接连接到我的服务器并使用 teamId = null 调用搜索 API 方法,我得到 NPE:

Exception in thread "main" java.lang.NullPointerException: Team id can't be a null
    at java.util.Objects.requireNonNull(Objects.java:228)

像这样的问题通常是由于对您所看到的报告的误解造成的:

[WEB-34] [Service] DEBUG Started searching member: provider=Hedgehog, teamId=null

这意味着 teamId 要么真的是 null,要么是包含单词 "null" 的 String 对象。不幸的是,输出中没有任何可见的东西可以区分。但是,如果您已经在代码中检查 null 而没有捕获它,则意味着您的代码有问题或变量设置为字符串 "null"。事实证明,它确实是字符串 "null"。 (其他可能性可能是您在 IDE 中看到的代码不是您实际 运行 中的代码,这有时可能由于配置问题等原因发生。)

但到底为什么要向您的方法传递一个包含 "null" 的字符串对象?一个常见的原因是调用者正在从整数转换(例如,它可能是来自 JDBC 连接的整数列,其中该列中允许空值)。然后它获取 Integer 对象并在将其传递给您的方法之前使用 String.valueOf(Object) 对其进行转换。如果 Integer 对象包含一个实际的 int,那将导致该 int 的字符串表示形式。如果它包含 null,它将导致字符串 "null".

因此,一个可能的解决方法是查看 findMemberByTeamId 的调用者并在空值转换为字符串之前捕获它们。