简体   繁体   English

泛型-不能转换为T,其中T是类型变量

[英]Generics - cannot be converted to T where T is a type variable

I know this question has been asked ad nauseam; 我知道这个问题曾被恶心地问过; I think I have an understanding of the error, but still can't see why I am (attempting to) violate the erasure limitations. 我认为我对错误有所了解,但仍然看不到为什么我(尝试)违反了擦除限制。 I also think I am using generics in the correct way, if not, feel free to let me know. 我还认为我以正确的方式使用了泛型,如果没有,请随时告诉我。

I have an AbstractService class (for both my Neo4j OGM and Hibernate implementations), each extended by a few classes which house a few methods that reflect the individual Entity objects. 我有一个AbstractService类(用于我的Neo4j OGM和Hibernate实现),每个类都由几个类扩展,这些类包含一些反映单个Entity对象的方法。 The individual entity objects all extend DomainEntity and are all both Hibernate ORM and Neo4j OGM entities. 各个实体对象都扩展了DomainEntity,并且都是Hibernate ORM和Neo4j OGM实体。

I have two snippets of code (one working with Hibernate and the other working with Neo4j OGM). 我有两个代码段(一个使用Hibernate,另一个使用Neo4j OGM)。 Both method calls (to the 3rd party library) have (almost) the same signature and my methods have the same signature, but my OGM-code throws the above compile-time error while my Hibernate-code does not. (对第3方库的)两个方法调用都具有(几乎)相同的签名,而我的方法具有相同的签名,但是我的OGM代码抛出上述编译时错误,而我的Hibernate代码则没有。

OGM OGM

import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.transaction.Transaction;

public abstract class AbstractService<T extends DomainEntity> implements Service<T> {

    private Session session;

    @Override
    public abstract Class<T> getEntityType();

    public abstract String getUniqueProperty();

    public abstract String getLabel();

    public T getEntity(String property) {
        String query = "MATCH (x:" + getLabel() + ") WHERE x." + getUniqueProperty() + " = \"" + property + "\" RETURN x";
        return session.queryForObject(getEntityType(), query, Collections.EMPTY_MAP);
    }
}

Here is the signature for the queryForObject method call: 这是queryForObject方法调用的签名:

public < T > T queryForObject(Class< T > objectType, String cypher, Map< String,? > parameters) public <T> T queryForObject(Class <T> objectType,String cypher,Map <String,?>参数)

I get the following compile-time error on the return session.queryForObject(...) line: 我在return session.queryForObject(...)行上收到以下编译时错误:

incompatible types: DomainEntity cannot be converted to T where T is a type-variable: T extends DomainEntity declared in class AbstractService 不兼容的类型:DomainEntity不能转换为T,其中T是类型变量:T扩展了在类AbstractService中声明的DomainEntity

However, if I cast the response to T before returning it, it works and I don't understand why. 但是,如果我在返回之前将响应强制转换为T ,则它可以正常工作,我也不知道为什么。 The queryForObject method returns T , which is what I am trying to return, so I don't understand why it would need to be casted to T before returning. queryForObject方法返回T ,这是我要返回的内容,因此我不明白为什么在返回之前需要将其强制转换为T

EDIT I have tried adding the generic type to the method-call: 编辑我尝试将泛型添加到方法调用中:

return session.<T>queryForObject(getEntityType(), query, Collections.EMPTY_MAP);

And that does not change anything. 那并没有改变任何东西。


HIBERNATE HIBERNATE

import org.hibernate.Session;

public abstract class AbstractService<T extends DomainEntity> implements Service<T> {

    private Session session;

    public T getEntity(String property) {
        String query = "SELECT * FROM " + getLabel() + " WHERE " + getUniqueProperty() + " = \'" + property + "\'";
        return getSession().createNativeQuery(query, getEntityType()).getSingleResult();
    }

    @Override
    public abstract Class<T> getEntityType();

    public abstract String getUniqueProperty();

    public abstract String getLabel();
}

Here are the signatures for the createNativeQuery and getSingleResult method calls. 这是createNativeQuery和getSingleResult方法调用的签名。

public < R > NativeQuery< R > createNativeQuery(String sqlString, Class< R > resultClass) public <R> NativeQuery <R> createNativeQuery(String sqlString,Class <R> resultClass)

public R getSingleResult() 公共R getSingleResult()

The only difference between the getSingleResult() and queryForObject(...) method signatures is the queryForObject(...) method signature has the additional < T >, which I didn't think made a difference in the return type...? getSingleResult()和queryForObject(...)方法签名之间的唯一区别是queryForObject(...)方法签名具有附加的<T>,我不认为返回类型有所不同... ?

I can reproduce your error. 我可以重现您的错误。 And I can eliminate it: 我可以消除它:

    return session.queryForObject(getEntityType(), query, Collections.emptyMap());

I cannot exactly tell why this solves it. 我不能确切地说出为什么能解决这个问题。 But it must have something to with the fact that queryForObject() wants a generic map ( Map<String, ?> ) while Collections.EMPTY_MAP is declared a raw (non-generic) Map . 但是它必须与以下事实有关:当Collections.EMPTY_MAP被声明为原始(非通用) MapqueryForObject()需要通用映射( Map<String, ?> )。

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

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