2012-08-06 112 views
4

我遇到了一個與使用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

回答

6

你有兩種類型,稱爲T,它不能認爲它們是相同的。第二種方法中的T可以是Collection<T>,或者可以是第一種中的T

您可以使用

baseDao.<T>save(.... 

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

,使其應明確哪一個。使它們成爲T同名無助於編譯器,可能只是令人困惑。

0

單擊文本顏色不同的位置,然後選擇導入save()的特定類(使用快捷鍵 - Mac是Alt-Enter)。或者,您可以使用完全限定的類名來消除兩種不同的save()方法之間的歧義。

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

+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

2

兩者的擦除簽名保存方法是

(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

1

通常我得到這種類型的錯誤,因爲類型擦除。

檢查代碼中的其他方法,以確保在刪除任何類型信息時它們都是不同的。如果有兩個或更多的相同,那麼這可能是你的問題。

擦除看到這對Java線索 http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

您可以發佈類的休息嗎?

1

嘗試指定類型<T>明確地如以下:

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