3

次のコードで問題が発生しています。

public ArrayList<? extends IEvent> getEventsByDateRange(DateTime minStartTime,  DateTime minEndTime) 
{
    ArrayList<? extends IEvent> returnedEvents = new ArrayList<GoogleEvent>();
    returnedEvents.add(new GoogleEvent());
    return (returnedEvents);
}

これにより、「returnedEvents.add(new GoogleEvent()); コード行」に対して次のコンパイル エラーが返されます。

ArrayList 型のメソッド add(capture#1-of ? extends IEvent) は、引数 (GoogleEvent) には適用されません。

クラスの宣言は次のGoogleEventとおりです。

public class GoogleEvent implements IEvent {...}

Java でジェネリックを使用すると、いくつかのトリッキーな部分があることはわかっています。したがって、ワイルドカードですが、これを理解できないようです。

ありがとう。

4

6 に答える 6

5

なぜあなたは書いてみませんか:

public List<IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime)
{
    List<IEvent> returnedEvents = new ArrayList<IEvent>();
    returnedEvents.add(new GoogleEvent());
    return returnedEvents;
}
于 2011-10-19T12:13:39.443 に答える
2

これは許可されていません。returnedEventsオブジェクトのリストが含まれており、GoogleEventオブジェクトではないGoogleEventオブジェクトを受け入れることを許可してはなりません。

あなたの例ではたまたまを渡していますが、を実装するものを受け入れるGoogleEventバージョンを呼び出すことによってそうしています。このメソッドを呼び出すことは許可されていません。これは、リストに。以外のものが格納される可能性があるためです。addIEventaddGoogleEvent

Javaワイルドカードは、この方法でルールを破るメソッドを「編集」します。

そのワイルドカードリストタイプを返す必要がある場合は、それでArrayList<GoogleEvent>問題ありません。

これはエラーなしでコンパイルされる完全なソースファイルであることに注意してください。

import java.util.*;

interface IEvent { }

class GoogleEvent implements IEvent { }

public class Foo {
    public ArrayList<? extends IEvent> getEventsByDateRange()  {
        ArrayList<GoogleEvent> returnedEvents = new ArrayList<GoogleEvent>();
        returnedEvents.add(new GoogleEvent());
        return (returnedEvents);
    }
}
于 2011-10-19T12:14:24.030 に答える
2

? extends IEventを使用するだけで、JavaはクラスIEventを動的にバインドするため、使用する必要はありません。GoogleEventそれはポリモーフィズムです。

于 2011-10-19T12:14:34.907 に答える
2

ソリューション:

ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();

エラーの理由は、コンパイラがキャプチャ変換を実行しようとしているためです。

あなたのケースでは、拡張する未知のもの(つまり、拡張/実装するもの)をreturnedEventsキャプチャし、それをパラメータ化されたタイプに割り当てています。IEventIEventGoogleEvent

コンパイラはこれを認識しますが、キャプチャプレースホルダーがに設定されているためreturnedEvents.add(? extends IEvent)、の署名では検証されません。returnedEvents.add(GoogleEvent)returnedEvents

于 2011-10-19T12:15:25.620 に答える
0

で宣言された変数に書き込むことはできません? extends ...。使用時のみ書き込み可? super ...

これは、次の例で説明できます。

List<GoogleEvent> googleEvents = new ArrayList<GoogleEvent>();
ArrayList<? extends IEvent> returnedEvents = googleEvents;

// Would be OK
returnedEvents.add(new GooleEvent());

// Would be OK to the definition of returnedEvents, 
// but breaks the googleEvents.
returnedEvents.add(new OtherEvent());

短い解決策は、returnedEvents を として宣言することですList<GoogleEvent>

于 2011-10-19T12:20:10.490 に答える
0
public ArrayList<IEvent> getEventsByDateRange(DateTime minStartTime,
        DateTime minEndTime)
{
    ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();
    returnedEvents.add(new GoogleEvent());
    return (returnedEvents);
}
于 2011-10-19T12:17:21.797 に答える