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.
I do understand that objects
is an ArrayList
of objects of the type Event
.
The part I don't understand is extending an ArrayAdapter with the Type <Event>
. What does this signify?
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".
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.
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 T
into 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 @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.
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."
And I take List<Event> objects
to mean a List
of Event
objects.
Collections are containers for objects, while Generics define what they can contain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With