Reputation: 9191
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
Reputation: 424983
Anything wrong with a perfunctory impl?
class MyCustomListImpl<T> extends ArrayList<T> implements MyCustomList<T> {}
return new MyCustomListImpl<MyCustomBean>();
Upvotes: 3
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
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
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