繁体   English   中英

为什么 com.fasterxml.jackson.core.type.TypeReference 实现 Comparable 接口?

[英]why com.fasterxml.jackson.core.type.TypeReference implements Comparable interface?

为什么 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 ^^^
}

这是源代码描述,但我仍然无法理解。

TL;DR:它什么都不做,是一个错误。

读过源代码吗? 因为它很好地解释了它。

具体来说,它链接到Neal Gafter 关于 Super Type Tokens 的帖子,并明确解释 Comparable 的东西是“受评论启发”的。 所以,打开那个链接,向下滚动到评论,果然:

Brian Oxley 说...与其在构造函数中检查类型参数,不如将其设为语法错误而忽略:

 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

看? 编译良好。 如果你运行它,你会得到“健全性检查”异常。 比较器的东西什么都不做。


编辑:

我在 jackson 提交了一个关于问题 #697的错误。

试图解释这一切背后的想法是什么(即使它不起作用):

原始类型具有传染性,与它相关的所有方面也是原始的。 原始类型以独特的方式行为,但通常这些方式与所有类型变量的Object非常相似,即使存在下限。

因此, new TypeReference() {}是原始的,意味着它实现的Comparable也是原始的,就像 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);

请注意 class 文件中有两个compareTo方法,即使我们在源代码中只写了一个。 因此,任何extends TypeReference的类都将始终包含一个用于compareTo(Object)的 impl,无论您尝试使用其中的 generics 部分来破解什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM