Java 不可理解;空类型不匹配“;

Java 不可理解;空类型不匹配“;,java,Java,有人能解释为什么循环中的print语句会产生错误吗 (空类型不匹配:必需'@NonNull SortedSet',但提供的值指定为@Null-able),而循环外部的值不匹配 我认为这是一个Java错误。是否有不涉及禁用nullchecks的解决方案?(代码毫无意义,它只是重现了问题) 公共类测试 { 静态无效打印(打印流ps,@Nullable SortedSet状态) { 如果(状态!=null) { ps.print(Utility.getElt(0,states)); } 对于(int

有人能解释为什么循环中的print语句会产生错误吗 (空类型不匹配:必需'@NonNull SortedSet',但提供的值指定为@Null-able),而循环外部的值不匹配

我认为这是一个Java错误。是否有不涉及禁用nullchecks的解决方案?(代码毫无意义,它只是重现了问题)

公共类测试
{
静态无效打印(打印流ps,@Nullable SortedSet状态)
{
如果(状态!=null)
{
ps.print(Utility.getElt(0,states));
}
对于(int q=0;q<1;q++)
{
如果(状态!=null)
{
ps.print(Utility.getElt(0,states));
}
}
}
}
Utility.getElt具有以下签名:

public static <@Nullable T> T getElt(int idx, @NonNull SortedSet<T> set);
public static T getElt(int idx,@NonNull SortedSet set);
如果我删除getElt的@NonNull注释,问题就会消失,但我确实希望这里有一个非null的“set”

实际上,注释取自org.eclipse.jdt.annotation。

根据,在空分析期间

根据此选项,每当检测到以下情况之一时,编译器将发出错误或警告:

使用非null注释声明的方法返回可为null的表达式

可为null的表达式作为参数在方法调用中传递,其中被调用方法的相应参数用非null注释声明。

可为null的表达式被分配给使用非null注释声明的局部变量

重写用非null注释声明的继承方法的方法试图通过指定可为null的注释(禁止逆变返回)来放松该约定

重写至少一个参数具有可为null的声明的继承方法的方法,通过为其相应参数指定非null注释(禁止协变参数),尝试收紧该null约定

在上面的示例中,如果静态已知表达式的值为null,或者使用可为null的注释声明表达式,则该表达式被视为可为null


(重点补充)。在您的情况下,您正试图将
null
值传递给
NonNull
参数。

将注释jar更新为最新的(?)版本后,我需要将getElt的签名从

public static <@Nullable T> T getElt(int idx, @NonNull SortedSet<T> set);
public static T getElt(int idx,@NonNull SortedSet set);

public static@Nullable T getElt(int idx,@NonNull SortedSet set set);
前面的语法不再有效

这并没有解决问题,但至少现在有了一个显式强制转换的解决方法(仍然只对循环中的版本要求!):

ps.print(Utility.getElt(q,(@NonNull SortedSet)状态));
虽然这导致了美妙的警告 “从SortedSet到SortedSet的不必要的强制转换”,现在只是一个警告,而不是错误

Eclipse中的这种空检查似乎仍然是“正在进行的工作”。
我以前版本的注释jar不是很旧。

请同时发布Utility.getElt()的代码。该方法的返回类型是什么?如果这些注释来自
org.eclipse.jdt.annotation
包,我认为这不是Java bug。
Utility#getElt
的签名是什么?@PhuongNguyen返回类型在这里没有争议;这是对
getElt()
的第二个形式参数的注释,它是
@NonNull SortedSet
@scriptin:question用请求的信息编辑解释一个调用上出现的错误的不一致性,而不是另一个调用上出现的错误-这是实际的问题。另外,您最后引用的一句话:
如果静态已知表达式的计算值为null,则认为该表达式可为null
——已知当前表达式的计算值不为null。这将使它成为一个不可为null的表达式。也许编译器通过额外运行循环来优化循环内外的代码重复?编译后的字节码是什么样子的?@Jules编译器不允许优化消除形式错误。从实用的角度来看,几乎没有在字节码级别进行优化;这是JIT编译器关心的问题。
public static <@Nullable T> T getElt(int idx, @NonNull SortedSet<T> set);
public static @Nullable <T> T getElt(int idx, @NonNull SortedSet<T> set);
    ps.print(Utility.getElt(q, (@NonNull SortedSet<IState>)states));