5

次のコードがわかりません。

public class EventAdapter extends ArrayAdapter<Event> 
{
    public EventAdapter(Context context, int textViewResourceId,
            List<Event> objects) 
    {
        super(context, textViewResourceId, objects);
        this.resource = textViewResourceId;
    }
}

<Event>どちらの場合も、その部分について混乱しています。ジェネリックと関係があることは理解していますが、理解できません。http://docs.oracle.com/javase/tutorial/java/generics/を読みましたが、まだ理解できません。

タイプ のオブジェクトであることobjectsは理解しています。ArrayListEvent

私が理解していない部分は、 Type で ArrayAdapter を拡張することです<Event>。これは何を意味しますか?

4

3 に答える 3

13

extends ArrayAdapter<Event>

ここでの型制限は、クラス内のメソッドの戻り値の型とメソッドの引数の型に影響します。

クラスがある場合の例を次に示します。

class SomeClass<T> {
    protected T value;

    public void setValue (T value) {
        this.value = value;
    }

    public T getValue () {
        return value;
    }
}

そして、別のクラスがある場合:

class SubClass extends SomeClass {

    @Override
    public void setValue (Event value) {    // Fail! It is not overriding the super class' method.
        this.value = value;    // Warning! Unchecked types (maybe inconsistent).
    }
}

@Override注釈を削除すると、実行されます。しかし、extends SomeClassは役に立たず、そのままにしておくと問題が発生する可能性があります。2 つの非常によく似た方法があります:setValue(Event)super.setValue(T). 問題は、サブクラスがメソッドにアクセスできるかどうかです。super.setValue(T)最後に説明します。「欠落している型パラメーター境界の例」を参照してください。

したがって、宣言で型を指定する必要があります。

class SubClass extends SomeClass<Event> {

    @Override
    public void setValue (Event value) {    // Correct now!
        this.value = value;
    }
}

また、一貫性のない型を宣言すると、次のようになります。

class SubClass extends SomeClass<String> {

    @Override
    public void setValue (Event value) {    // Fail! Not overriding.
        this.value = value;    // Fail! Inconsistent types.
    }
}

したがって、型はクラス本体の動作を制限します。



欠落している型パラメーター境界の例:


import java.lang.reflect.*;

class Super<T> {
    public void method (T t) {
        System.out.println("Hello");
    }

    public void method2 () {

    }
}

public class Test extends Super {
    /*public void method (Object t) {
        System.out.println("world");
    }*/

    /*public <T> void method (T t) {

    }*/

    public static void main (String args[]) {
        new Test().method("");
        for (Method m : Test.class.getMethods()) {
            System.out.println(m.toGenericString());
        }
    }
}
  • サブクラスでコメントmethod()すると、警告付きでコンパイルされます: Test.java uses unchecked or unsafe opertations. 実行結果では、ジェネリック型TObject:に変わりましたpublic void Test.method(java.lang.Object)

  • サブクラスの最初のコメントのみを外すmethod()と、警告なしでコンパイルされます。実行結果では、サブクラスは 1 つを所有していpublic void Test.method(java.lang.Object)ます。@Overrideただし、注釈は許可されません。

  • method()サブクラス (ジェネリック型の境界もある)の 2 番目のみをコメント解除すると、コンパイルはエラーで失敗します: name clash. また、@Override注釈を許可しません。これを行うと、別のエラーがスローされます: method does not override.

  • method2()満場一致でサブクラスに継承されます。ただし、次のコードも記述できません。

    スーパークラス:public void method2 (Object obj)およびサブクラス: public <T> void method2 (T obj). また、それらはあいまいであり、コンパイラによって許可されていません。

于 2013-01-18T03:49:55.407 に答える
2

この場合のジェネリックスの単純な見方を次に示します。定義を考えると:

public class EventAdapter extends ArrayAdapter<Event> 

EventAdapter私はそれを「 IS-A ArrayAdapterOFEventオブジェクト」と読みました。

そして、私はオブジェクトList<Event> objectsの a を意味します。ListEvent

コレクションはオブジェクトのコンテナであり、ジェネリックは格納できるものを定義します。

于 2013-01-18T02:41:31.667 に答える
0

これにより、EventAdapter クラスのユーザーから制御を奪う方法で、ArrayAdapter のジェネリック パラメーターに値が割り当てられます。

ここでオーバーライドするメソッドは、T を Event に置き換えることができ、キャストなしで T の代わりに Event を使用できます。

これがジェネリックの一般的な定義です。

この場合にこれが許可されることは、仕様で定義されています。そのセクションでは正確な動作は定義されていませんが、私が見る限り、他のすべての一般的な動作と一致していると思います。

私はここで初めてその構造を見ましたが、いくつかの考えの後、それは本当に珍しいことではありません.

于 2017-01-31T16:04:48.310 に答える