1

I get the error...

The return type is incompatible with 'Set<Map.Entry<K,T>>' returned from Map<K,T>.entrySet() (mismatching null constraints)

...when implementing a Map and overriding Map.entrySet like this:

package org.abego.util;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
...    
public abstract class MyMap<K, T> implements Map<K, T> {
    private Map<K, T> map = new LinkedHashMap<>();

    @Override
    public Set<java.util.Map.Entry<K, T>> entrySet() {
        return map.entrySet();
    }
    ...
}

The package org.abego.util defines the default nullness to be @NonNull:

@org.eclipse.jdt.annotation.NonNullByDefault
package org.abego.util;

The only way I found to get rid of the error was to 'remove the default nullness annotation' for entrySet using an @NonNullByDefault({}) annotation:

package org.abego.util;
...
import org.eclipse.jdt.annotation.NonNullByDefault;

public abstract class MyMap<K, T> implements Map<K, T> {
    ...
    @Override
    @NonNullByDefault({})
    public Set<java.util.Map.Entry<K, T>> entrySet() {
        return map.entrySet();
    }
    ...
}

While this does work I am wondering if this is the correct way to fix the error.

(I am using Eclipse 4.5 (Mars) and jdk1.8.0_60.)

4

1 回答 1

0

您正在尝试覆盖此方法:

Set<Map.Entry<K, V>> entrySet();

使用有效签名为的方法

@NonNull Set<@NonNull Map.Entry<K, V>> entrySet();

这是一个不兼容的覆盖,可以通过这个调用者证明:

Set<Map.Entry<Foo,Bar>> entries = someMap.entrySet();
entries.add(null);

如果someMap有类型MyMap,那么元素类型entries@NonNull,但是java.util.Map.entrySet()承诺的契约 aSet元素null是可以容忍的(集合没有指定其元素的空值)。@NonNull在同一个对象上混合两个合约(有和未指定)entries将破坏假定非空元素的客户端。

查看 的 Javadoc entrySet(),但是可以安全地假设Map.entrySet()它将始终返回Set带有非空元素的 a。因此,问题的根源在于java.util.Map.entrySet()没有空注释。

从 Eclipse Mars 开始,这可以通过外部空注释来克服。您可以通过在 IDE 中应用Annotate 命令或将以下代码段放入已配置为JRE的外部注释位置的目录中的文件中,告诉编译器返回类型Map.entrySet()是 in fact :@NonNull Set<@NonNull Map.Entry<K,V>>java/util/Map.eea

class java/util/Map

entrySet
 ()Ljava/util/Set<Ljava/util/Map$Entry<TK;TV;>;>;
 ()L1java/util/Set<L1java/util/Map$Entry<TK;TV;>;>;

有了这样的外部注释,您的程序将被 JDT 的 null 分析接受。

于 2015-09-13T11:52:37.253 回答