7

Why does the following

public class ListBox {
    private Random random = new Random();
    private List<? extends Collection<Object>> box;

public ListBox() {
    box = new ArrayList<>();
}

public void addTwoForks() {
    int sizeOne = random.nextInt(1000);
    int sizeTwo = random.nextInt(1000);

    ArrayList<Object> one = new ArrayList<>(sizeOne);
    ArrayList<Object> two = new ArrayList<>(sizeTwo);

    box.add(one);
    box.add(two);
}

public static void main(String[] args) {
    new ListBox().addTwoForks();
}
}

Not work? Just toying around with generics for the purpose of learning and I expected that I would be able to insert anything that extends Collection in there but I get this error:

The method add(capture#2-of ? extends Collection<Object>) in the type List<capture#2-of ? extends Collection<Object>> is not applicable for the arguments (ArrayList<Object>)
The method add(capture#3-of ? extends Collection<Object>) in the type List<capture#3-of ? extends Collection<Object>> is not applicable for the arguments (ArrayList<Object>)

at ListBox.addTwoForks(ListBox.java:23)
at ListBox.main(ListBox.java:28)
1

1 Answer 1

13

You've declared box to be a List of something that extends Collection of Object. But according to the Java compiler, it could be anything that extends Collection, i.e. List<Vector<Object>>. So it must disallow add operations that take the generic type parameter for this reason. It can't let you add an ArrayList<Object> to a List that could be List<Vector<Object>>.

Try removing the wildcard:

private List<Collection<Object>> box;

This should work because you can certainly add an ArrayList<Object> to a List of Collection<Object>.

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

3 Comments

This makes sense, but if I wanted to add a vector and an arraylist? Edit, link in first comment explains the use of super ;)
@arynaq both of those implement List, so you could do List<List<Object>> box. Then you can add both Vectors and ArrayLists, though you can only get them out as List<Object>. If you need specific methods on ArrayList or Vector, you'll have to test-and-downcast or come up with something else -- but first make sure you really need that!
Alternately, List<Collection<Object>> as suggested would already work for vectors and arraylists, as well as e.g. sets.

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.