3

I have a class B which extends A. A stores a list of AItem and B stores a list of BItem

In 'A' I have an ArrayList which uses [? extends AItem] .

I assume this means that I can use this ArrayList for objects of any type that extends AItem.

So in my B class I have a method add(..) which adds a BItem to the items.

I assumed this would work because the items arrayList can hold a list of any object that extends from AItem.

import java.util.ArrayList;

class A {
    public ArrayList<? extends AItem> items;
}

public class B extends A{

    public void add(BItem i) {

        this.items.add(i); //compile error here
    } 
}

//items :
class AItem {}
class BItem extends AItem{}

How would I get this to work?

My compile error looks like this :

The method add(capture#2-of ? extends AItem) in the type ArrayList is not applicable for the arguments (BItem)

4
  • You can't add items to an list of unknown type Commented Apr 25, 2016 at 13:43
  • 1
    Possible duplicate of How can I add to List<? extends Number> data structures? Commented Apr 25, 2016 at 13:46
  • Very good question. I stay tunned for answers but I think that you need to initialize the arrayList with some class. Commented Apr 25, 2016 at 13:46
  • You need to use ArrayList<? super AItem> read this for more information. Commented Apr 25, 2016 at 13:48

3 Answers 3

6

You probably don't need to use generics here. Having the list of type AItem in class A should be fine (I would also declare it of type List instead of ArrayList for best practices):

class A {
    public List<AItem> items;
}

class B extends A {

    public void add(BItem i) {

        this.items.add(i);
    } 
}

The problem with ? extends AItem is that the compiler cannot guarantee that the actual type of the elements is AItem or BItem. It could be another subclass CItem in which case the type safety is broken.

There is another approach to designing the class hierarchy with generics, in which you set the type parameter in the parent class and set it to the appropriate subclass (BItem) in the extended class B:

class A<T extends AItem> {
    public ArrayList<T> items;
}

class B extends A<BItem>{

    public void add(BItem i) {

        this.items.add(i);
    } 
}
Sign up to request clarification or add additional context in comments.

Comments

2

Try replacing extends with super

import java.util.ArrayList;

class A {
    public ArrayList<? super AItem> items;
}

public class B extends A{

    public void add(BItem i) {

        this.items.add(i); //compile error here
    } 
}

//items :
class AItem {}
class BItem extends AItem{}

You may find more details about the reason behind this behavior, here

Comments

1

you can use

public ArrayList<? super AItem> items; 

and you can add to the list now

but you will not be able to do

public class B extends A{
 .....

   public BItem getOne(int idx) {
     return this.items.get(idx);

   }
}

jvm doesn't know what will be actually in the list.

you can generify the A class

class  A<T> {
    public ArrayList<T> items;
}

then define your B class as

public class B extends A<BItem>{

    public void add(BItem i) {

        this.items.add(i); 
    } 
}

Comments

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.