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?
Why don't you do this:
And then work with that list. If for some reason you really need a ArrayList, you can always do
And work with that. This is not very efficient though.
You should always use the interface in place of the
Handle
. That is the whole point ofOOP
Languages so that you can switch between any implementation later.If you are casting to any concrete class, the compiler will warn you about a possibility of
Cast
Exception that may occur. You can useSuppressWarning
if you are very much sure about the type.It's not a good idea because you don't know what implementation the method returns; if it's not an
ArrayList
, you'll get aClassCastException
. In fact, you should not be concerned with what exact implementation the method returns. Use theList
interface instead.If, for some reason, you absolutely need an
ArrayList
, then create your ownArrayList
and initialize it with theList
returned by the method:But don't do this, unless you absolutely need an
ArrayList
- because it's inefficient.You're correct. That is not a good idea. You need to use the interface form that it's returning.
It would throw a ClassCastException if you downcasted to ArrayList when in fact it was a LinkedList. Generally its never a good idea to downcast like this especially if you didn't write the code that returns the object you want to downcast. Plus if you are using 3rd party libs like this they might change what they return you as they improve their code. If you put downcasts like this in your code it might work today, but when you upgrade your libs it all of a sudden it breaks. And it breaks at runtime not compile time so you won't know its broken until you run it. This is an issue of you violating the contract the library has with you which only using a List interface.
The whole point of using interfaces (List) is to hide implementation details. Why do you want to cast it to specific implementation?