【问题标题】:What is the Eclipse External Annotation Format for Static Inner Classes?静态内部类的 Eclipse 外部注释格式是什么?
【发布时间】:2017-02-03 17:10:25
【问题描述】:

我正在尝试为静态内部类 Map.Entry 编写一个 Eclipse 外部注释文件。我该怎么做?

我在所有外部注释文件所在的文件夹下的java/util 子文件夹中创建了一个名为Map$Entry.eea 的文件。这是该文件的内容。

class java/util/Map$Entry

comparingByKey
 <K::Ljava/lang/Comparable<-TK;>;V:Ljava/lang/Object;>()Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
 <K::Ljava/lang/Comparable<-TK;>;V:Ljava/lang/Object;>()L1java/util/Comparator<L1java/util/Map$Entry<T1K;TV;>;>;

comparingByKey
 <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Comparator<-TK;>;)Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
 <K:Ljava/lang/Object;V:Ljava/lang/Object;>(L1java/util/Comparator<-TK;>;)L1java/util/Comparator<L1java/util/Map$Entry<TK;TV;>;>;

comparingByValue
 <K:Ljava/lang/Object;V::Ljava/lang/Comparable<-TV;>;>()Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
 <K:Ljava/lang/Object;V::Ljava/lang/Comparable<-TV;>;>()L1java/util/Comparator<L1java/util/Map$Entry<TK;T1V;>;>;

comparingByValue
 <K:Ljava/lang/Object;V:Ljava/lang/Object;>(Ljava/util/Comparator<-TV;>;)Ljava/util/Comparator<Ljava/util/Map$Entry<TK;TV;>;>;
 <K:Ljava/lang/Object;V:Ljava/lang/Object;>(L1java/util/Comparator<-TV;>;)L1java/util/Comparator<L1java/util/Map$Entry<TK;TV;>;>;

equals
 (Ljava/lang/Object;)Z
 (L0java/lang/Object;)Z

getKey
 ()TK;
 ()TK;

getValue
 ()TV;
 ()TV;

setValue
 (TV;)TV;
 (TV;)TV;

Eclipse 仍然在以下代码中标记entry.getValue() 上的警告:

Map.Entry<@Nullable String, @NonNull Object> entry;
@NonNull Object value = entry.getValue();

警告是:

Unsafe interpretation of method return type as '@NonNull' based on the receiver type
'Map.<@NonNull Entry<@Nullable String, @NonNull Object>>'. Type Map.Entry<K, V> doesn't seem
to be designed with null type annotations in mind.

【问题讨论】:

    标签: eclipse external-annotations


    【解决方案1】:

    对于@NonNullgetValue 之后的第二行必须是 ()T<strong>1</strong>V; 而不是 ()TV;

    class java/util/Map$Entry
    getValue
     ()TV;
     ()T1V;
    

    对于@Nullable,它将是 ()T<strong>0</strong>V;

    但由于映射条目的值可以为空 ("it's also possible that the map explicitly maps the key to null"),如果 entry 的类型为 Map.Entry&lt;String, <strong>@Nullable</strong> Object&gt; 而不是如果类型是Map.Entry&lt;String, <strong>@NonNull</strong> Object&gt;。要告诉 Eclipse Map.Entry 在设计时考虑到了 null 类型注释 java/util/Map$Entry.eea 文件必须几乎是空的:

    class java/util/Map$Entry
    

    但请注意,如果您对Map 执行相同操作,那么@NonNull Object o = map.get("foo"); 将不会收到警告。您必须显式注释所有@Nullable 类型参数:

    class java/util/Map
    get
     (Ljava/lang/Object;)TV;
     (Ljava/lang/Object;)T0V;
    

    另请参阅:Eclipse 4.6 New and Noteworthy - Improved null analysis with generics

    【讨论】:

    • 如果我有一个Map.Entry&lt;@Nullable String, @NonNull Object&gt; entry1; 和一个Map.Entry&lt;@Nullable String, @Nullable Object&gt; entry2;。在一种情况下,我需要()T1V;,在另一种情况下,我需要()T0V;。我该如何处理这两种情况?
    • 对于某些地图,空值是允许的(即@Nullable V)。对于其他地图,不允许使用空值(即@NonNull V)。在后一种情况下,Map.get() 仍然可以返回 null,但 Map.Entry.getValue() 永远不会返回 null。可惜我们不能指定()TV;,Eclipse 会查看V 的定义来确定它是@NonNull 还是@Nullable。
    • Eclipse查看V的定义判断是@NonNull还是@Nullable,如果有这个类的外部注解文件但是没有这个具体方法的V的外部注解。跨度>
    【解决方案2】:

    升级到 Eclipse Oxygen (4.7.0) build 20170620-1800 解决了这个问题。 Map$Entry.eea 可以保留在问题中,编译器警告会在适当的时候发生。如果Map.EntryV 在代码中是@NonNull,那么getValue() 的返回类型是@NonNull。如果Map.EntryV在代码中是@Nullable,那么getValue()的返回类型是@Nullable

    问题中的代码不再导致编译器警告。下面的代码可以做到(这是预期的和期望的)。

    Map.Entry<@NonNull String, @Nullable Object> entry;
    ...
    entry.getValue().toString();
    

    【讨论】:

      猜你喜欢
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      相关资源
      最近更新 更多