简体   繁体   English

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

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

why com.fasterxml.jackson.core.type.TypeReference implements Comparable interface?为什么 com.fasterxml.jackson.core.type.TypeReference 实现 Comparable 接口? I don't understand the intention of implementing it.我不明白实施它的意图。

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 ^^^
}

Here's the source code description, but I still can't understand it.这是源代码描述,但我仍然无法理解。

TL;DR: It does nothing and is a bug. TL;DR:它什么都不做,是一个错误。

Did you read the source code?读过源代码吗? Because it explains it quite well.因为它很好地解释了它。

Specifically, it links to Neal Gafter's post on Super Type Tokens and explicitly explains that the Comparable stuff is there 'inspired by a comment'.具体来说,它链接到Neal Gafter 关于 Super Type Tokens 的帖子,并明确解释 Comparable 的东西是“受评论启发”的。 So, open that link, scroll down to the comments, and sure enough:所以,打开那个链接,向下滚动到评论,果然:

Brian Oxley said... Rather than check for a type parameter in the constructor, you can make it a syntax error to leave out: 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; } }

Now this is legal:现在这是合法的:

new TypeReference<Object>() { };

But this is a syntax error for not implementing Comparable :但这是未实现Comparable的语法错误:

new TypeReference() { } ; new TypeReference() { }

February 20, 2007 6:12 AM 2007 年 2 月 20 日上午 6 点 12 分

However , that is incorrect .然而这是不正确的

It actually does nothing.它实际上什么也没做。 Here, let's try it:在这里,让我们尝试一下:

> 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

See?看? Compiles fine.编译良好。 If you run it, you get that 'sanity check' exception.如果你运行它,你会得到“健全性检查”异常。 The comparator stuff does nothing.比较器的东西什么都不做。


EDIT:编辑:

I filed a bug over at jackson about it Issue #697 .我在 jackson 提交了一个关于问题 #697的错误。

To try to explain what the thought behind all this was (even though it does not work):试图解释这一切背后的想法是什么(即使它不起作用):

A raw type is infectious, and all aspects related to it are also raw.原始类型具有传染性,与它相关的所有方面也是原始的。 Raw types behaviour in unique ways, but usually those ways are very similar to having Object for all type variables, even if there is a lower bound.原始类型以独特的方式行为,但通常这些方式与所有类型变量的Object非常相似,即使存在下限。

Thus, new TypeReference() {} , being raw, means the Comparable it implements is also raw, which acts as if it's like Object, which means that the impl must have the method public int compareTo(Object o) .因此, new TypeReference() {}是原始的,意味着它实现的Comparable也是原始的,就像 Object 一样,这意味着 impl 必须具有方法public int compareTo(Object o)

The provided implementation of TypeReference does not have int compareTo(Object) , it only has compareTo(TypeReference) , therefore, new TypeReference() {} wouldn't compile.提供的TypeReference实现没有int compareTo(Object) ,它只有compareTo(TypeReference) ,因此new TypeReference() {}不会编译。

A nice story.一个不错的故事。 But that's not how javac works, unfortunately.但不幸的是,这不是 javac 的工作方式。 You can see the logic and it makes some sense, but unfortunately that compareTo , because it matches the lower bound, gets a synthetic additional method.您可以看到逻辑并且它是有道理的,但不幸的是compareTo ,因为它与下限匹配,因此获得了一个合成的附加方法。 You can check this: If you javap TypeReference:你可以检查这个:如果你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);

Note how there are two compareTo methods in the class file even though we wrote only one in the source.请注意 class 文件中有两个compareTo方法,即使我们在源代码中只写了一个。 Thus, any classes that extends TypeReference will always have, baked in, an impl for compareTo(Object) no matter what you try to hack with the generics part of it.因此,任何extends TypeReference的类都将始终包含一个用于compareTo(Object)的 impl,无论您尝试使用其中的 generics 部分来破解什么。

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

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