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是一个ArrayList类型的对象Event

我不明白的部分是使用 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_ setValue(Event)_ super.setValue(T)现在的问题是子类可以访问该super.setValue(T)方法吗?我会在最后解释,参见“A missing type parameter bounding example”。

因此,您需要在声明中指定类型:

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。在运行结果中,它把泛型类型T变成了Object: public void Test.method(java.lang.Object)

  • 如果我只取消注释method()子类中的第一个,它将被编译而没有警告。在运行结果中,子类拥有一个public void Test.method(java.lang.Object)。但它不允许@Override注释。

  • 如果我只取消注释method()子类中的第二个(它也有一个泛型类型边界),编译将失败并出现错误: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> 

我把它读作:“一个EventAdapterIS-A ArrayAdapterOFEvent对象。”

List<Event> objects的意思是List对象Event

集合是对象的容器,而泛型定义了它们可以包含的内容。

于 2013-01-18T02:41:31.667 回答
0

这会为 ArrayAdapter 中的泛型参数分配一个值,从而从 EventAdapter 类的用户手中夺走控制权。

然后,此处覆盖的任何方法都可以用 Event 替换 T ,并且可以使用 Event 代替 T 而无需强制转换。

这是泛型的一般定义。

在这种情况下允许这样做是在规范中定义的。虽然该部分中没有定义确切的行为,但据我所知,我认为它与所有其他通用行为一致。

虽然我第一次看到这里的构造,但在一些人认为它真的没有什么不寻常之后。

于 2017-01-31T16:04:48.310 回答