泛型和 getClass() 作为参数

Generics and getClass() as parameters

在下面的示例代码中,我试图传递一个特定类型的对象并将其序列化为 Json。

protected <S> ResponseObject postJson(String url, S object) throws IOException {
    return post(url, getString(object, object.getClass()));
}

private <S> String getString(S object, Class<S> clazz) {
    // some code that relies on object being of type clazz
}

我收到一个编译器错误:

method getString in class PPServerRequestJob<T> cannot be applied to given types;
    return post(url, getString(object, object.getClass()));
                     ^
  required: S#1,Class<S#1>
  found: S#2,Class<CAP#1>
  reason: inferred type does not conform to lower bound(s)
    inferred: CAP#1
    lower bound(s): S#2
  where S#1,S#2,T are type-variables:
    S#1 extends Object declared in method <S#1>getString(S#1,Class<S#1>)
    S#2 extends Object declared in method <S#2>postJson(String,S#2)
    T extends PPBaseResult declared in class PPServerRequestJob
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ? extends Object

我 运行 在 Android,所以使用 Java 7.

我可以通过将 object.getClass() 改成 Class<S> 来消除错误 - 但我不明白为什么有必要这样做。 object.getClass() returns Class<? extends S>,因此 object 应该满足该要求,因为它保证是 S.

的子类

object.getClass() returns Class<? extends S>, so object should meet that requirement as it is guaranteed to be a subclass of S.

这是正确的,但是您的第二个参数是 Class<S> 类型而不是 Class<? extends S> 类型,无法隐式转换。

在您的示例中,编译器会将 S 替换为声明的 class 用于调用函数的任何内容,但它可以是子 class。 getClass() returns 具体 class。例如考虑以下内容:

Animal a = new Cat();
postJson("http://foo.com", a);

这导致以下实施:

protected ResponseObject postJson(String url, Animal object) throws IOException {
    return post(url, getString(object, object.getClass() /* Cat.class */));
}

private String getString(Animal object, Class<Animal> clazz) {
    // some code that relies on object being of type clazz
}

在这里,您会看到对 getString 的调用试图将 Class<Cat> 隐式转换为 Class<Animal> 的问题。要解决此问题,您需要将其更改为以下内容:

private <S> String getString(S object, Class<? extends S> clazz)