2010-07-13 172 views
1

好的,我想我很瞭解泛型,但出於某種原因,我無法理解爲什麼這種方法無效。我有兩個類,或者我應該說Google有兩個類(我試圖實現他們的Contacts API)。他們有一個ContactEntry類(以下略):Java泛型問題

package com.google.gdata.data.contacts; 

public class ContactEntry extends BasePersonEntry<ContactEntry> { 

    public ContactEntry() { 
    super(); 
    getCategories().add(CATEGORY); 
    } 

    public ContactEntry(BaseEntry<?> sourceEntry) { 
    super(sourceEntry); 
    } 

} 

我離開的一個或兩個方法,但沒有什麼重要的是,它真的只是它的父類BasePersonEntry的實現具有大部分是涉及一個人的重要的東西下面進入縮寫代碼:

package com.google.gdata.data.contacts; 

public abstract class BasePersonEntry<E extends BasePersonEntry> extends 
    BaseEntry<E> { 

    public BasePersonEntry() { 
    super(); 
    } 

    public BasePersonEntry(BaseEntry<?> sourceEntry) { 
    super(sourceEntry); 
    } 

    public List<CalendarLink> getCalendarLinks() { 
    return getRepeatingExtension(CalendarLink.class); 
    } 

    public void addCalendarLink(CalendarLink calendarLink) { 
    getCalendarLinks().add(calendarLink); 
    } 

    public boolean hasCalendarLinks() { 
    return hasRepeatingExtension(CalendarLink.class); 
    } 

} 

現在...我不是很明白的是,如果我這樣做了以下內容:

public void method1(StringBuilder sb, ContactEntry contact) { 
if (contact.hasCalendarLinks()) { 
    for (CalendarLink calendarLink : contact.getCalendarLinks()) { 
    ... 
    } 
} 
} 

一切工作網絡東北。它能夠解釋getCalendarLinks返回一個CalendarLink類型的列表。但是,如果我想抽象這種方法,並有我的方法使用BasePersonEntry,如下所示:

public void method1(StringBuilder sb, BasePersonEntry entry) { 
if (entry.hasCalendarLinks()) { 
    for (CalendarLink calendarLink : entry.getCalendarLinks()) { 
    ... 
    } 
} 
} 

我得到一個編譯錯誤:

incompatible types 
found : java.lang.Object 
required: com.google.gdata.data.contacts.CalendarLink 

對於我的生活我做不到理解爲什麼?對getCalendarLinks的調用是EXACT相同的方法(通過繼承),它返回EXACT相同的東西。也許它與BasePersonEntry是一個抽象類有關?

如果有人可以對此有所瞭解,我會非常感激。如果有幫助,您可以在這裏找到由Google託管的源代碼的完整版本:Link To Google Library Download。我正在嘗試使用gdata-java庫的1.41.3版本。

+0

getRepeatingExtension是做什麼的?它取決於E嗎? – samitgaur 2010-07-13 20:28:37

回答

2

您的新定義的問題是,它使用的是原始類型不是通用類型。 BasePersonEntry後

public void method1(StringBuilder sb, BasePersonEntry<?> entry) 

<?>

結果類型是從一切刪除,包括getCalendarLinks及其簽名被減少到List<Object> getCalendarLinks()

相當於修復它,改變聲明。這種方式是通用類型。

此外,你可能想在類通用聲明改爲

public abstract class BasePersonEntry<E extends BasePersonEntry<E> > 

沒有<E>你的編譯器(或IDE)會產生unchecked警告。

+0

從Shadowcat的第一篇文章中,它聽起來像BasePersonEntry是Google類,而不是ShadowCat。 – Powerlord 2010-07-13 19:37:01

+0

的確,我不能影響BasePersonEntry上的更改,但是,您提到的所有其他內容都是正確的。我對它進行了測試,它對您建議的method1進行了修改,效果很好。 我以前只知道泛型適用於集合,並且缺少很多其他應用程序。非常感謝您的回覆! 我正在閱讀Angelika Langer的泛型常見問題解答,現在看起來我有很多東西需要學習。 =) – Shadowcat 2010-07-13 21:37:50

+0

@Shadowcat。我沒有注意到BasePersonEntry是第三方類,但是當設計泛型基類時,儘量不要在'extends'語句中使用Raw類型的例子(它仍然會產生'unchecked'警告)。用泛型玩得開心! – 2010-07-14 11:38:34