这是我的代码。
我有一个通用接口
public interface ClientServerComparator<T> {
public boolean compare(T entity,T obj);
}
我正在尝试实现另一个泛型类
public class EntityTest<T> {
public void testPutObject(Client client, T obj ) throws UnExpectedStatusException
{
log.debug("PUT: " + location);
T entity = testGetObject(client,entityLocation,l);
if(entity instanceof ClientServerComparator<?> )
{
if( false == ((ClientServerComparator<?>) entity).compare(entity,obj) )
{
log.error("Object fetched back does not match object put");
throw new UnExpectedStatusException();
}
}
}
我收到以下编译错误:
The method compare(capture#1-of ?, capture#1-of ?) in the type
ClientServerComparator<capture#1-of ?> is not applicable for the arguments (T, T)
如何让EntityTest
泛型类在实现ClientServerComparator
泛型接口的对象上调用方法?
答案 0 :(得分:1)
我认为问题在于您使用的通配符告诉编译器,该实体是任何ClientServerComparator,不一定与T相关。
但是,您已经知道实体是T类型(您已通过实例化实体的类型注释定义)。此外,您正在检查实体是否是ClientServerComparator的实例。我假设,您始终期望实体成为ClientServerComparator的实例。如果是这种情况,那么您可以将EntityTest的泛型类型更改为<T extends ClientServerComparator<T>>
并删除实例检查和类型转换:
public class EntityTest<T extends ClientServerComparator<T>> {
public void testPutObject(Client client, T obj) {
T entity = testGetObject(client);
if (entity.compare(entity, obj)) {
throw new UnExpectedStatusException();
}
}
}
现在T是ClientServerComparator<T>
,因此您可以在实体上调用compare。
答案 1 :(得分:0)
T
是您的班级EntityTest
和ClientServerComparator
中的类型变量。但它是变量,这意味着它并不表示两个类中的相同类型。您可以在T
中使用Z
之类的其他名称调用ClientServerComparator
,但这不会改变您的代码含义。
因此,要在两个类型为变量compare
的对象上调用T
方法,首先需要将对象转换为ClientServerComparator<T>
而不是ClientServerComparator<?>
。在后一种情况下,它不知道类型是什么(<?>
),因此您不能使用泛型类型的参数调用任何方法[您只能调用返回泛型类型的方法]
如果你转向(ClientServerComparator<T>)
,你会收到编辑关于&#34;未经检查的演员&#34;的警告。这是因为在Java中,泛型只是编译时类型安全的。在运行时,类型变量T
的实际值不再为人所知。
从技术上讲,你可能有一个实现Foo
的类ClientServerComparator<Bar>
。如果您知道代码中没有此代码,则可以使用@SuppressWarnings("unchecked")
注释来禁止编译器警告。
像这样:
@SuppressWarnings("unchecked")
public void testPutObject(Client client, T obj) throws UnExpectedStatusException {
T entity = testGetObject(client, entityLocation, l);
if (entity instanceof ClientServerComparator) {
if (false == ((ClientServerComparator<T>) entity).compare(entity, obj)) {
throw new UnExpectedStatusException();
}
}
}