5

我在使用 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

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

4

6 回答 6

7

You have two types called T and it can't assume they are the same. T could be Collection<T> in the second method or it could be T in the first.

You can use

baseDao.<T>save(....

or

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

to make it clear which one it should be. Making them the T same name doesn't help the compiler and may just be confusing.

于 2012-08-06T12:39:40.557 回答
2

The erased signatures of the two save methods are

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

and the compiler can't decide which one you intended to call. An explicit cast should help here:

baseDao.save((Collection)aEntities, aDbTransaction, getClass((T) aEntities.toArray()[0]));
于 2012-08-06T12:40:24.533 回答
2

Try specifying the type <T> explicitely like in the following:

baseDao.<Collection<T>>save(aEntities, aDbTransaction, getClass((T) aEntities.toArray()[0]));
于 2012-08-06T12:41:09.743 回答
1

Usually I get this sort of error because of type erasure.

Check the other methods in your code to make sure they are all differrent when you remove any of hte type information. If there are two or more the same then this could be your prolem.

For erasure see this on the java trail http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Can you post the rest of the class?

于 2012-08-06T12:40:45.330 回答
0

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

于 2012-08-06T12:34:01.150 回答
0

由于类型擦除,这两个方法具有相同的签名。

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

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

Because your parameter is a Collection, but the T of the collection is not necessarily the same T as the other method, so both methods could match.

Try an explicit cast to either Collection or Object.

于 2012-08-06T12:39:13.550 回答