I have the following class & interface defined:
public interface A {
}
public class B implements A {
}
I have a List
of <
List<A> listA = (List<A>)(List<?>) listB;
not recommended.
I'm sure you need make the whole list List< A >(weird parsing there) and when adding new B objects cast them with (A)
listA.add( (A) new B()); // dummy data
It is just a matter of declarations. Don't declare listB as List but as List or List.
List<A> listB = new List<B>();
listB.add(new B()); // dummy data
listB.add(new B()); // dummy data
listB.add(new B()); // dummy data
List<A> listA = listB;
As simple as that. If you want to force listB to be List (avoiding the addition of any non-B element) you will be forced to use:
List<A> listA = new ArrayList<A>(listB);
But as they already pointed out, if you are forced to do that it is not a good sign.
We can achieve this using Generics and Wildcards. You might not be able to create List<A>
but create something like List<? extends A>
which will call all the methods of the interface which is enough for most I think.
Creating a new collection is expensive and not advisable. Since the references of the same objects will be passed on into the new collection, the additional list creation step is just an overhead.
List<B> bList = new ArrayList<B>();
List<? extends A> aList = bList;
You cannot cast it like that. Create a new one:
List<A> listA = new ArrayList<A>(listB);
The constructor takes Collection<? extends A>
. It will point to the same references anyway.
Rather than fighting against a language feature, you should learn to use it properly.
Rather than asking how to use unsafe casts to work around the error, it is instructive to first understand why there's an error; why what you're asking to do is unsafe (because you can add an A
to the list using listA
and then take it out of the list as a B
using listB
).
Then, you should explain why you think that your use case does not run into the unsafe scenario. Because the answer to this will give a hint for how to change your code to make it work correctly with generics.
listA
, then you should change the type of listA
to List<? extends A>
. That way, you can assign listB
to it directly without any casts, and you won't be able to add anything to it using listA
(except null
).listB
, then why not change the type of listB
to List<A>
in the first place?