Java 泛型问题
好吧,我以为我很好地理解了泛型,但出于某种原因,我无法理解为什么这不起作用。我有两个类,或者我应该说 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
新定义的问题在于它使用的是 Raw 类型而不是 Generic 类型。
结果类型被从所有内容中删除,包括 getCalendarLinks ,并且其签名被简化为与 List
要修复此问题,请将声明更改为:
注意 BasePersonEntry 之后的
。这样它就是泛型类型。
另外,您可能希望将类泛型声明更改为
没有
您的编译器(或 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 ofList<Object> getCalendarLinks( )
To fix it, change declaration to:
Note
<?>
after BasePersonEntry. This way it's generic type.Also, you probably want to change the class generic declaration to
Without
<E>
your compiler ( or IDE ) will generate anunchecked
warning.