我使用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
你有什么想法吗? 提前感谢您的帮助。
答案 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
,因此这两种方法都可以匹配。
尝试对Collection
或Object
进行明确投射。