Is making return type generic with same erasure binary compatible?

I have the following class:

public abstract Foo {
  Foo() {}

  public abstract Foo doSomething();

  public static Foo create() {
    return new SomePrivateSubclassOfFoo();
  }
}

I want to change it to the following definition:

public abstract Foo<T extends Foo<T>> {
  Foo() {}

  public abstract T doSomething();

  public static Foo<?> create() {
    return new SomePrivateSubclassOfFoo();
  }
}

Is this change binary compatible? Ie, will code that is compiled against the old version of the class work with the new version without reocmpilation?

I know that I need to change SomePrivateSubclassOfFoo , this is ok. I also know that this change will trigger warnings about raw types when old client code is compiled, this is also ok for me. I just want to make sure that old client code does not need to be recompiled.

From my understanding, this should be ok because the erasure of T is Foo , and thus the signature of doSomething in the byte code is the same as before. If I look at the internal type signatures printed by javap -s , I indeed see this confirmed (although the "non-internal" type signatures printed without -s do differ). I also did test this, and it worked for me.

However, the Java API Compliance Checker tells me that the two versions are not binary compatible.

So what is correct? Does the JLS guarantee binary compatibility here, or was I just lucky in my tests? (Why could this happen?)


链接地址: http://www.djcxy.com/p/95076.html

上一篇: 为什么NgModule进口的顺序很重要?

下一篇: 使返回类型泛型与相同的擦除二进制兼容?