Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java generics in Android

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?

like image 338
Chris Muench Avatar asked Dec 06 '22 09:12

Chris Muench


2 Answers

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.



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

like image 81
shuangwhywhy Avatar answered Jan 03 '23 07:01

shuangwhywhy


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.

like image 21
CodeShane Avatar answered Jan 03 '23 07:01

CodeShane