2010-07-13 120 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