为什么Jackson实现Comparable接口?

djp7away  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(95)

为什么com.fasterxml.Jackson.core.type.TypeReference实现了Comparable接口
我不明白实施它的意图。

public abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
    protected final Type _type;
    
    protected TypeReference() {
        Type superClass = getClass().getGenericSuperclass();
        if (superClass instanceof Class<?>) { // sanity check, should never happen
            throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
        }
        /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect
         *   it is possible to make it fail?
         *   But let's deal with specific
         *   case when we know an actual use case, and thereby suitable
         *   workarounds for valid case(s) and/or error to throw
         *   on invalid one(s).
         */
        _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

    public Type getType() { return _type; }
    
    /**
     * The only reason we define this method (and require implementation
     * of <code>Comparable</code>) is to prevent constructing a
     * reference without type information.
     */
    @Override
    public int compareTo(TypeReference<T> o) { return 0; }
    // just need an implementation, not a good one... hence ^^^
}

下面是源代码描述,但我还是看不懂。

8hhllhi2

8hhllhi21#

TL;DR:它什么也不做,是一个bug。
你读过源代码了吗?因为它解释得很好。
具体来说,它链接到Neal Gafter's post on Super Type Tokens,并明确解释了Comparable的内容是“受评论启发”的。所以,打开那个链接,向下滚动到评论,果然:
Brian奥克斯利说。。您可以将其设置为语法错误以忽略,而不是在构造函数中检查类型参数:

public abstract TypeReference<R> implements Comparable<TypeReference<R>> {
  // ...
  
  public int compareTo(TypeReference<R> o) {
    // Need a real implementation.
    // Only saying "return 0" for illustration.
    return 0;
  }
}

这是法律的的:
new TypeReference<Object>() { };
但这是一个没有实现Comparable的语法错误:
new TypeReference() { } ;

  • 2007年2月20日上午6:12 *
  • 但是***,这是不正确的**。

它实际上什么也不做。在这里,让我们尝试一下:

> cat Test.java
import java.lang.reflect.*;
abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
  protected final Type _type;
  protected TypeReference() {
    Type superClass = getClass().getGenericSuperclass();
    if (superClass instanceof Class<?>) { // sanity check, should never happen
      throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
    }
    _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
  }

  @Override public int compareTo(TypeReference<T> o) { return 0; }

  public static void main(String[] args) {
    TypeReference raw = new TypeReference() {};
  }
}

> javac Test.java

看到没编译得很好如果你运行它,你会得到“健全检查”异常。比较器什么都不做。
编辑:
我提交了一个bug在Jackson关于它Issue #697
试着解释这一切背后的想法是什么(尽管它不起作用):
原始类型具有传染性,与之相关的所有方面也都是原始的。原始类型以独特的方式行为,但通常这些方式非常类似于Object用于 all 类型变量,即使存在下限。
因此,new TypeReference() {}是raw,这意味着它实现的Comparable也是raw,这就像它是Object一样,这意味着impl必须有public int compareTo(Object o)方法。
提供的TypeReference * 的实现没有 * int compareTo(Object),它只有compareTo(TypeReference),因此,new TypeReference() {}无法编译。
很不错的故事。但不幸的是,javac不是这样工作的。你可以看到逻辑,它有一定的意义,但不幸的是,compareTo,因为它符合下限,得到一个合成的附加方法。你可以检查这个:如果您javap TypeReference:

> javap TypeReference
javap TypeReference
Compiled from "Test.java"
abstract class TypeReference<T> implements java.lang.Comparable<TypeReference<T>> {
  protected final java.lang.reflect.Type _type;
  protected TypeReference();
  public int compareTo(TypeReference<T>);
  public static void main(java.lang.String[]);
  public int compareTo(java.lang.Object);

请注意类文件中有两个compareTo方法,尽管我们在源代码中只编写了一个。因此,extends TypeReference的任何类都将始终具有compareTo(Object)的impl,无论您尝试如何破解它的泛型部分。

相关问题