好吧,我以为我对泛型非常了解,但是由于某些原因,我无法理解为什么这种方法不起作用。我有两个类,或者我应该说Google有两个类(我正在尝试实现其Contacts API)。它们具有一个ContactEntry类(以下简称):

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的调用是完全相同的方法(通过继承),它返回的是完全相同的东西。也许与BasePersonEntry是抽象类有关?

如果有人可以阐明这一点,我将非常有义务。如果有帮助,您可以在这里找到由Google托管的此源代码的完整版本:Link To Google Library Download。我正尝试使用其gdata-java库的1.41.3版本进行此操作。

最佳答案

新定义的问题在于它使用的是Raw类型而不是Generic类型。

结果,从所有内容(包括getCalendarLinks)中删除了类型,并且其签名减少到与List<Object> getCalendarLinks( )等效

要解决此问题,请将声明更改为:

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


在BasePersonEntry之后记下<?>。这样,它就是通用类型。

另外,您可能希望将类通用声明更改为

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


如果没有<E>,则您的编译器(或IDE)将生成unchecked警告。

10-06 02:38