代码之家  ›  专栏  ›  技术社区  ›  matt b

泛型:编译器似乎无法识别传递给参数的类型与返回的类型相同-为什么?

  •  1
  • matt b  · 技术社区  · 14 年前

    假设我有几个pojo,它们都扩展了一个公共超类型, BaseObject

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

    对于每个特定于类型的DAO,我都有一个扩展泛型类型并将其限制为具体类型的接口( public interface UserDao extends GenericDao<User>

    在试图使用 将军刀 我有一个方法

    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() 方法无法编译-编译器似乎在解释

    GenericDao<? extends BaseContractObject>
    

    而不是认识到这一点 getDao(Class<T>) 会还给我一个 将军刀 T .

    有人能解释这是为什么吗?我知道相同类型绑定或通配符的重复出现并不一定指同一类型;然而,编译器似乎应该从 传入的T应该与返回的T相同(但显然它无法识别这一点 是我无法理解的部分)。

    如果我来定义 getDao 的签名

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

    那么编译一个 实现看起来像

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

    那么为什么编译器能够在这种情况下识别 T getDao(T) 是一样的 Class<T> ?

    3 回复  |  直到 14 年前
        1
  •  5
  •   erickson    14 年前

    表达式 object.getClass() T extends BaseObject ,返回 Class<? extends BaseObject> Class<T> 正如人们所料。所以, getDao() 返回与接收到的类型相同的刀;只是没有收到预期的类型。

        2
  •  2
  •   Gray droiddeveloper    14 年前

    这是一个典型的类型擦除问题。 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);
    

        3
  •  0
  •   Tetsujin no Oni    14 年前

    我认为这应该解释为什么约束没有达到您期望的效果:

    http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ206