Intellij Idea - 模糊方法调用

问题描述:

我遇到了一个与使用Intellij Idea的Java相关的奇怪错误。Intellij Idea - 模糊方法调用

所以有这样的接口:

<T> void save(T aEntity, DbTransaction dbTransaction, Class<T> clazz); 
<T> void save(Collection<T> aEntities, DbTransaction dbTransaction, Class<T> clazz); 

当我尝试编译下面的代码:

@SuppressWarnings("unchecked") 
@Override 
public void save(Collection<T> aEntities, DbTransaction aDbTransaction) { 
    baseDao.save(aEntities, aDbTransaction, getClass((T) aEntities.toArray()[0])); 
} 

我收到的下一个编译错误:

reference to save is ambiguous, both method <T>save(T,DbEntityHelper.DbTransaction,java.lang.Class<T>) in xzc.dao.IBaseDao and method <T>save(java.util.Collection<T>,DbEntityHelper.DbTransaction,java.lang.Class<T>) in xzc.dao.IBaseDao match 

你有有任何想法吗 ? 感谢您的帮助。

+0

什么是'的getClass()'签名? – Saintali 2012-08-06 12:37:26

+0

如何声明baseDao?它是否参数化? – 2012-08-06 12:37:53

+0

Nope,正如你从方法签名中看到的,T在方法签名中是“声明的”。该接口根本没有参数化。 – StKiller 2012-08-06 12:39:03

你有两种类型,称为T,它不能认为它们是相同的。第二种方法中的T可以是Collection<T>,或者可以是第一种中的T

您可以使用

baseDao.<T>save(.... 

baseDao.<Collection<T>>save(.... 

,使其应明确哪一个。使它们成为T同名无助于编译器,可能只是令人困惑。

单击文本颜色不同的位置,然后选择导入save()的特定类(使用快捷键 - Mac是Alt-Enter)。或者,您可以使用完全限定的类名来消除两种不同的save()方法之间的歧义。

由于type erasure,这两种方法具有相同的签名。

简单地说,在运行时的所有类型的信息将被删除,所以你的两个方法有效地成为:

Object void save(Object aEntity, DbTransaction dbTransaction, Class clazz); 
Object void save(Collection aEntities, DbTransaction dbTransaction, Class clazz); 

因为你的参数是Collection,但收集的T不一定相同T为另一种方法,所以两种方法都可以匹配。

尝试显式转换为CollectionObject

+0

真的吗? T(对象)如何能相当于Collection (Collection)? – StKiller 2012-08-06 12:40:27

+0

@AndreiPodoprigora - 我相信集合也是一个对象。 – Vic 2012-08-06 12:42:59

+0

@Vic - 但不应该编译器选择最具体的方法? – StKiller 2012-08-06 12:44:32

两者的擦除签名保存方法是

(Object, DBTransaction, Class) 
(Collection, DBTransaction, Class) 

,编译器不能决定你打算调用哪一个。一个明确的演员应该帮助这里:

baseDao.save((Collection)aEntities, aDbTransaction, getClass((T) aEntities.toArray()[0])); 
+0

它没有帮助。用baseDao解决方案。>保存工作正常。 – StKiller 2012-08-06 12:45:04

通常我得到这种类型的错误,因为类型擦除。

检查代码中的其他方法,以确保在删除任何类型信息时它们都是不同的。如果有两个或更多的相同,那么这可能是你的问题。

擦除看到这对Java线索 http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

您可以发布类的休息吗?

尝试指定类型<T>明确地如以下:

baseDao.<Collection<T>>save(aEntities, aDbTransaction, getClass((T) aEntities.toArray()[0]));