Mark Estrada
Mark Estrada

Reputation: 9191

Returning a Generic Empty List

How do I return a custom object which uses generic as an empty list?

I have extended the List interface and created my own custom type

public interface MyCustomList<T>
  extends List<T>
{

In a class, I have a method which returns a custom list but I always end up with a compiler error. Basically the default implementation of this method should return an empty list but I cant get it to work since I am encountering below error. 'incompatible types'

public MyCustomList<MyCustomBean> getCodes(String code)
{
    return  Collections.<MyCustomList<MyCustomBean>>emptyList();
}

Whats the proper way of sending back a 'generified' empty list implementation?

Upvotes: 1

Views: 3760

Answers (4)

Bohemian
Bohemian

Reputation: 424983

Anything wrong with a perfunctory impl?

class MyCustomListImpl<T> extends ArrayList<T> implements MyCustomList<T> {}

return new MyCustomListImpl<MyCustomBean>();

Upvotes: 3

Paul Bellora
Paul Bellora

Reputation: 55213

Collections.emptyList returns a List<T>, whose implementation is hidden. Since your MyCustomList interface is an extension of List, there's no way that method can be used here.

In order for this to work you will need to make an implementation of an empty MyCustomList, in the same way that the core API's Collections implements an empty List implementation, and then use it instead. For example:

public final class MyEmptyCustomList<T> extends AbstractList<T> implements MyCustomList<T> {

    private static final MyEmptyCustomList<?> INSTANCE = new MyEmptyCustomList<Object>();

    private MyEmptyCustomList() { }

    //implement in same manner as Collections.EmptyList

    public static <T> MyEmptyCustomList<T> create() {

        //the same instance can be used for any T since it will always be empty
        @SuppressWarnings("unchecked")
        MyEmptyCustomList<T> withNarrowedType = (MyEmptyCustomList<T>)INSTANCE;

        return withNarrowedType;
    }
}

Or more accurately, hide the class itself as an implementation detail:

public class MyCustomLists { //just a utility class with factory methods, etc.

    private static final MyEmptyCustomList<?> EMPTY = new MyEmptyCustomList<Object>();

    private MyCustomLists() { }

    private static final class MyEmptyCustomList<T> extends AbstractList<T> implements MyCustomList<T> {
        //implement in same manner as Collections.EmptyList
    }

    public static <T> MyCustomList<T> empty() {
        @SuppressWarnings("unchecked")
        MyCustomList<T> withNarrowedType = (MyCustomList<T>)EMPTY;
        return withNarrowedType;
    }
}

Upvotes: 2

Nrj
Nrj

Reputation: 6831

Can't you use Collections.emptyList() for this purpose. This is type safe and seems to do what you are looking for!

Upvotes: 0

Andremoniy
Andremoniy

Reputation: 34900

In your case this is impossible until you will have proper implementation of your interface MyCustomList.

UPD: Collections.emptyList() returns special implementation of List interface, which of course is not convertible to your MyCustomList.

Upvotes: 0

Related Questions