1

さて、私はジェネリックスをかなりよく理解していると思いましたが、なぜかこれがうまくいかない理由に頭を悩ませることができません。私には2つのクラスがあります。つまり、Googleには2つのクラスがあります(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);
  }

}

1つまたは2つのメソッドを省略しましたが、重要なことは何もありません。実際には、親クラス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でこれを試みていました。

4

1 に答える 1

2

新しい定義の問題は、ジェネリック型ではなくRaw型を使用していることです。

その結果、タイプはすべてから消去されgetCalendarLinks、その署名は次のものと同等になります。List<Object> getCalendarLinks( )

これを修正するには、宣言を次のように変更します。

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

<?>BasePersonEntryの後に注意してください。このように、それはジェネリック型です。

また、クラスジェネリック宣言を次のように変更することもできます。

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

<E>コンパイラ(またはIDE)がないと、unchecked警告が生成されます。

于 2010-07-13T19:25:31.703 に答える