我想将一个实用程序方法引入Java 8.名为max
的方法定义如下:
@SafeVarargs
public static final <E extends Comparable<E>> E max(final E... elements) {
E result = null; // error
for(final E e : elements) {
if(result == null || result.compareTo(e) < 0) {
result = e;
}
}
return result;
}
现在Eclipse显示错误:
空类型不匹配(类型注释):
null
与自由类型变量E
不兼容。
我原本以为将@Nullable
添加到result
的定义应该会删除错误,但显然并非如此。即使我用@Nullable
另外注释整个方法,错误仍然存在。
顺便说一句,我正在使用FindBugs中的jsr-305.jar并将Eclipse配置为荣誉javax.annotation.Nonnull
以及javax.annotation.Nullable
。编辑:我在Lubuntu上运行Eclipse Luna 4.4.2和Oracle JDK 8 build 1.8.0_25-b17。
现在我的问题:错误来自哪里?如何在保持注释和泛型类型定义的好处的同时摆脱它?
编辑:我刚刚添加了一个示例项目,其中使用了默认的eclipse注释,它似乎有些工作(除了在result == null
生成警告,因为它错误地推断结果只能为null点)。所以这似乎是一个带有非默认注释类的Eclipse问题。我用我自己的Eclipse Nullable
注释副本重新测试了它,并得到了与上面相同的错误。
答案 0 :(得分:2)
中找到了这个错误来自哪里?
对应于无约束类型参数的类型变量 需要悲观检查以确保所有人的安全 法律替代:这种类型既不能被认为可以为空 也不是无聊的。
class C<T extends Number> { int consume(T t) { return t.intValue(); // NOT OK since T could be nullable } T provide() { return null; // NOT OK since T could require nonnull } }
最后一点可能看起来令人惊讶,但请注意,无约束类型参数意味着我们可能不会假设 关于由...表示的类型的null的任何事情 相应的类型变量。更重要的是:我们必须积极支持 可空和非空类型。另一方面,这只是扩展了 现有规则,唯一的类型与无界的兼容 type variable是类型变量本身。解释这种情况 在null分析的上下文中,编译器将引发以下内容 对于provide()中的返回错误:
在实例化泛型类型或调用泛型方法时,必须遵守type参数提出的约束。
如何在保持注释和泛型类型定义的好处的同时摆脱它?
将@Nullable添加到<E extends Comparable<E>>
,就像这样
@SafeVarargs
public static final <@Nullable E extends Comparable<E>> E max(final E... elements) {
E result = null; // no error
for(final E e : elements) {
if(result == null || result.compareTo(e) < 0) {
result = e;
}
}
return result;
}
答案 1 :(得分:1)
Tja,可选。如果varargs数组为空,怎么回事?
public static final <E extends Comparable<E>> Optional<E> max(final E... elements) {
Optional<E> result = Optional.empty();
for(final E e : elements) {
if(!result.isPresent() || result.get().compareTo(e) < 0) {
result.set(e);
}
}
return result;
}
或至少需要一个参数。
public static final <E extends Comparable<E>> E max(final E first, final E... elements) {
E result = first;
for (final E e : elements) {
if (/*result != null ||*/ result.compareTo(e) < 0) {
result = e;
}
}
return result;
}