Intellij Idea - 模糊的方法调用

时间:2012-08-06 12:31:56

标签: java generics intellij-idea

我使用Intellij Idea遇到了与Java相关的奇怪错误。

所以有这样的界面:

<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

你有什么想法吗? 提前感谢您的帮助。

6 个答案:

答案 0 :(得分:6)

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

您可以使用

baseDao.<T>save(....

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

明确应该是哪一个。使它们成为T相同的名称对编译器没有帮助,可能会让人感到困惑。

答案 1 :(得分:2)

两种保存方法的已删除签名是

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

并且编译器无法决定您打算调用哪一个。明确的演员阵容应该有所帮助:

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

答案 2 :(得分:1)

通常我会因为类型擦除而遇到这种错误。

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

对于擦除,请参阅java跟踪 http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

你可以发布课程的其余部分吗?

答案 3 :(得分:1)

尝试明确指定类型<T>,如下所示:

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

简而言之,在运行时,所有类型信息都将被删除,因此您的两种方法将有效地成为:

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

因为您的参数是Collection,但该集合的T不一定与其他方法的相同 T,因此这两种方法都可以匹配。

尝试对CollectionObject进行明确投射。