6

I have an interface A:

interface A {
}

Then I have a class B:

class B implements A {
}

Then I have a method that uses a list of A:

void process(ArrayList<A> myList) {
}

I want to pass it a list of B:

ArrayList<B> items = new ArrayList<B>();
items.add(new B());
process(items);

But then there is an error that types do not match. I understand why. ArrayList is a type itself and it has not function to convert from ArrayList<B> to ArrayList<A>. Is there a quick and resource-wise light way to form a new array that is suitable to be passed to my process method?

2 Answers 2

10

I think the easiest solution is to change one of the methods to:

void process(ArrayList<? extends A> myList) {
}

However, be aware that with this solution the entire list needs to be of the same type. That is, if you would have a class C that also would implement A, you can't mix the items in the array so that parts of it are of type B and parts of it are of type C.

Also, as pointed out in the comments below, you will not be able to add an object to the list from within this method.

Sign up to request clarification or add additional context in comments.

4 Comments

It may be worth pointing out that when using this method, you will not be able to add items into myList from inside the process method
@monkybonk05 I was not aware of that, but my guess is that process is meant to process the items that's already there and not add new ones. :) Could you explain why that would not be possible? I guess it's because the array is of a generic type.
@Simon André Forsberg Inside the method you don't know which exact A implementation the list is declared to contain, so the compiler cannot determine if what you want to put into the list is indeed allowed to be there.
@Simon André Forsberg To answer your question, consider the following. If you have a list of type B, List<B> list, you cannot add objects of type A. i.e, list.add(a) is a compile error because A is NOT a B. So in the case of a generic list type method parameter, you can pass lists of type A or anything that extends (or in this case implements) A. So the only way to ensure you don't add the wrong type of object into the list is to not allow you to add any objects at all!
4

Another alternative is to just create an ArrayList of A instead of B

ArrayList<A> items = new ArrayList<A>();
items.add(new B());
process(items);

It is perfectly acceptable to add classes (such as B) which implement the interface in the declared list.

As an aside: I would use List and only use ArrayList when instantiating the list. Also including Simon's answer, this could become

void process(List<? extends A> myList) {
}

List<A> items = new ArrayList<A>();
items.add(new B());
process(items);

1 Comment

This could be an option but that would require making generalized methods in one of my VERY specialized objects. I don't like mixing abstraction levels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.