Java 泛型问题

发布于 2024-09-09 16:14:39 字数 2133 浏览 4 评论 0原文

好吧,我以为我很好地理解了泛型,但出于某种原因,我无法理解为什么这不起作用。我有两个类,或者我应该说 Google 有两个类(我正在尝试实现他们的联系人 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 托管的此源代码的完整版本:Google 图书馆下载链接。我正在尝试使用他们的 gdata-java 库的 1.41.3 版本。

Alright, I thought I understood generics pretty well, but for some reason I can't get my head wrapped around why this doesn't work. I have two classes, or I should say that Google has two classes (I'm trying to implement their Contacts API). They have a ContactEntry class (abbreviated below):

package com.google.gdata.data.contacts;

public class ContactEntry extends BasePersonEntry<ContactEntry> {

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

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

}

I left off one or two methods, but nothing important, its really just an implementation of its parent class BasePersonEntry which has most of the important stuff that concerns a person entry abbreviated code below:

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);
  }

}

Now... what I can't quite understand is if I do something like the following:

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

Everything works fine. It is able to interpret that getCalendarLinks returns a list of type CalendarLink. However, if I want to abstract this method and have my method use BasePersonEntry, like the following:

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

I get a compiler error:

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

For the life of me I just can't understand why? The call to getCalendarLinks is the EXACT same method (via inheritance), its returning the EXACT same thing. Maybe it has to do with BasePersonEntry being an abstract class?

If anyone, can shed some light on this I would be very much obliged. If it helps you can find a full version of this source code hosted by Google here: Link To Google Library Download. I was attempting this with version 1.41.3 of their gdata-java libraries.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

送君千里 2024-09-16 16:14:39

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

结果类型被从所有内容中删除,包括 getCalendarLinks ,并且其签名被简化为与 List等效。 getCalendarLinks( )

要修复此问题,请将声明更改为:

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

注意 BasePersonEntry 之后的 。这样它就是泛型类型。

另外,您可能希望将类泛型声明更改为

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

没有 您的编译器(或 IDE)将生成 unchecked 警告。

The problem with your new definition, is that it's using Raw type not Generic type.

As a result type is erased from everything, including getCalendarLinks and its signature is reduced to equivalent of List<Object> getCalendarLinks( )

To fix it, change declaration to:

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

Note <?> after BasePersonEntry. This way it's generic type.

Also, you probably want to change the class generic declaration to

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

Without <E> your compiler ( or IDE ) will generate an unchecked warning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文