Let's suppose I'm using a library for which I don't know the source code. It has a method that returns a List, like so:
public List<SomeObj> getObjs() { ... }
I'm wondering if this is a good idea:
ArrayList<SomeObj> objs = (ArrayList<SomeObj>) getObjs();
If, for example, the concrete implementation of the List inside getObjs() is a LinkedList
then wouldn't there be some kind of type discrepancy?
The reason why it returns a
List
is so that you don't have to care what it is underlying that interface.The
List
interface simply declares the contract the object has to satisfy, and how you query it. The library author is at liberty in the future to pick anArrayList
,aLinkedList
, or maybe aLazyDatabasePopulatedList
. In fact you may get a different implementation at runtime depending on how the providing class has been implemented.So long as you have a contract to adhere to, this buys you a lot of freedom. There's a lot to be said for only talking and providing interfaces, and dealing with concrete classes as little as possible.
Cast to the return type defined by the API you are calling.
If it says it returns a
List<SomeObj>
, then that is. Don't try to retrieve the underlying type, because:a) It can vary with new versions (or even between calls)
b) You do not need to know the implementing class for anything.
If you need an ArrayList, then do
new ArrayList<SomeObject)(getObjs());
No, it is not a good idea. You should always use the interface (
List
) to declare your list variable unless you for some reason need specific behaviour fromArrayList
.Also, if you do, you need to be really sure that the list returned is an
ArrayList
. In this case, the promised contract ofgetObjs()
is only that the return type is some kind ofList
, so you shouldn't assume anything else. Even if theList
returned now would beArrayList
, there is nothing preventing the implementer ofgetObjs()
to later change the type ofList
returned, which would then break your code.