仿制药:编译器似乎无法认识到传递给参数的类型与返回的类型相同 - 为什么?

StackOverflow https://stackoverflow.com/questions/3120428

  •  30-09-2019
  •  | 
  •  

假设我有几个pojos,都扩展了一个普通的超级构想, BaseObject.

我有一个 GenericDao 被宣布为 public interface GenericDao<T>.

对于每个特定类型的DAO,我都有一个接口,该接口扩展了通用类型并将其限制为混凝土类型(public interface UserDao extends GenericDao<User>),然后是特定类型的DAO的实现。

在试图使用许多的课程中 GenericDao 实现,我有一种看起来像

public <T extends BaseObject> long create(T object) {
    return getDao(object.getClass()).save(object);
}

如果我实施 getDao() 这样它是一个参数 Class 对象,例如

private <T extends BaseObject> GenericDao<T> getDao(Class<T> clazz) { ... }

然后打电话给 getDao(object.getClass() 在里面 create() 方法无法编译 - 编译器似乎解释了返回类型 getDao() 作为

GenericDao<? extends BaseContractObject>

而不是认识到 getDao(Class<T>) 要把我归还给我 GenericDao 相同类型 T.

有人可以解释为什么这是吗?我知道,相同类型或通配符的重复出现并不必需地参考相同类型。但是,编译器似乎应该从签名中认识到 getDao(Class<T>) 传递的t应该是相同的t(显然它无法识别这一点) 为什么 是我无法掌握的部分。

如果我定义 getDao的签名是

private <T extends BaseContractObject> GenericDao<T> getDao(T obj) { ... }

那么编译没有问题 create() 看起来像

public <T extends BaseContractObject> long create(T object) {
    return getDao(object).save(object);
}

那么,为什么在这种情况下,编译器能够识别 T 论点传递给 getDao(T) 是一样的 T 在返回类型中,而当论点是 Class<T>?

有帮助吗?

解决方案

表达方式 object.getClass(), ,对象是类型的 T extends BaseObject, ,返回a Class<? extends BaseObject>, ,不是 Class<T> 正如人们可能期望的那样。所以, getDao() 正在返回与收到相同类型的DAO;只是没有收到预期类型。

其他提示

这是一个经典的擦除问题。 getClass() 具有以下签名:

public final native Class<? extends Object> getClass();

如果你有 String 并做一个 getClass() 在上面,你得到的课是 Class<? extends String>. 。 Javadocs阅读:

 * @return The <code>java.lang.Class</code> object that represents
 *         the runtime class of the object.  The result is of type
 *         {@code Class<? extends X>} where X is the
 *         erasure of the static type of the expression on which
 *         <code>getClass</code> is called.

您将需要强迫以下演员阵容使它起作用:

@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>)object.getClass();
return getDao(clazz).save(object);

这对我行得通。

我认为这应该解释为什么约束没有做您期望的事情:

http://www.angelikalanger.com/genericsfaq/faqsections/typeparameters.html#faq206

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top