java Android中的java泛型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14391027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:06:27  来源:igfitidea点击:

java generics in Android

javaandroidgenerics

提问by Chris Muench

I don't understand the following code:

我不明白以下代码:

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

I am confused about the <Event>part in both cases. I understand it has something to do with Generics, but I don't understand it. I read http://docs.oracle.com/javase/tutorial/java/generics/, but still don't understand.

<Event>对这两种情况下的部分感到困惑。我知道它与泛型有关,但我不明白。我阅读了http://docs.oracle.com/javase/tutorial/java/generics/,但仍然不明白。

I do understand that objectsis an ArrayListof objects of the type Event.

我明白这objects是一个ArrayListof 类型的对象Event

The part I don't understand is extending an ArrayAdapter with the Type <Event>. What does this signify?

我不明白的部分是使用 Type 扩展 ArrayAdapter <Event>。这意味着什么?

回答by shuangwhywhy

extends ArrayAdapter<Event>

extends ArrayAdapter<Event>

The type restriction here will influence on the return types of methods in the class, and the argument types of methods.

这里的类型限制会影响类中方法的返回类型,以及方法的参数类型。

Here is an example, if you have a class:

这是一个例子,如果你有一个类:

class SomeClass<T> {
    protected T value;

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

    public T getValue () {
        return value;
    }
}

And if you have another class:

如果你有另一堂课:

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).
    }
}

If you remove the @Overrideannotation, it will run. But the extends SomeClassis useless and might cause problem if you keep it there -- there will be two very similar methods: setValue(Event)and super.setValue(T). Now the question is will the subclass have access to the super.setValue(T)method?I will explain it in the end, see "A missing type parameter bounding example".

如果删除@Override注释,它将运行。不过extends SomeClass是无用的,如果你把它有可能会造成问题-将有两个非常相似的方法:setValue(Event)super.setValue(T)。现在的问题是子类是否可以访问该super.setValue(T)方法?我会在最后解释它,请参阅“一个缺失的类型参数边界示例”。

So, you need to specify the type in declaration:

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

class SubClass extends SomeClass<Event> {

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

Also, if you declare an inconsistent type:

此外,如果您声明不一致的类型:

class SubClass extends SomeClass<String> {

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

So the type restricts the behavior of class body.

所以类型限制了类体的行为。





A missing type parameter bounding example:

缺少类型参数边界示例:



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());
        }
    }
}
  • If I comment method()in the subclass, it is compiled with a warning: Test.java uses unchecked or unsafe opertations. In the running result, it turned the generic type Tinto Object: public void Test.method(java.lang.Object).

  • If I only uncomment the first method()in the subclass, it is compiled with no warnings. In the running result, the subclass owns one public void Test.method(java.lang.Object). But it doesn't allow @Overrideannotation.

  • If I only uncomment the second method()in the subclass (which also has a generic type bounding), the compile fails with an error: name clash. It also doesn't allow @Overrideannotation. If you do so, it throws a different error: method does not override.

  • method2()is inherited by the subclass unanimously. But you also can't write the following code:

    in superclass: public void method2 (Object obj)and in subclass: public <T> void method2 (T obj). They are also ambiguous and is not allowed by the compiler.

  • 如果我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)。它们也是模棱两可的,并且是编译器不允许的。

回答by CodeShane

Here's my simplistic way of looking at generics in this case. Given the definition:

这是我在这种情况下查看泛型的简单方法。鉴于定义:

public class EventAdapter extends ArrayAdapter<Event> 

I read it as: "An EventAdapterIS-A ArrayAdapterOF Eventobjects."

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

And I take List<Event> objectsto mean a Listof Eventobjects.

我需要List<Event> objects为指ListEvent对象。

Collections are containers for objects, while Generics define what they can contain.

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

回答by HopefullyHelpful

This assigns a value for the generic parameter in ArrayAdapter in a way that takes away control from the user of the EventAdapter class.

这以一种从 EventAdapter 类的用户手中夺走控制权的方式为 ArrayAdapter 中的泛型参数分配一个值。

Any method overriding here can then replace T with Event and Event can be used inplace of T without casts.

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

This is the general definition of generics.

这是泛型的一般定义。

That this is allowed in this case is defined in the spec. While the exact behaviour is not defined in that section I think it is in line with all other generic behaviour as far as I can see.

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

While I see the construct here the first time, after some thinking it really isn't anything unusual.

虽然我第一次在这里看到这个构造,但经过一番思考后,这真的没什么不寻常的。