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
java generics in Android
提问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 objects
is an ArrayList
of objects of the type Event
.
我明白这objects
是一个ArrayList
of 类型的对象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 @Override
annotation, it will run. But the extends SomeClass
is 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 typeT
intoObject
: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 onepublic void Test.method(java.lang.Object)
. But it doesn't allow@Override
annotation.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@Override
annotation. 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 EventAdapter
IS-A ArrayAdapter
OF Event
objects."
我读它为:“一个EventAdapter
IS-A ArrayAdapter
OFEvent
对象。”
And I take List<Event> objects
to mean a List
of Event
objects.
我需要List<Event> objects
为指List
的Event
对象。
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.
虽然我第一次在这里看到这个构造,但经过一番思考后,这真的没什么不寻常的。