Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java using Generics

Tags:

java

generics

I have an interface A like this:

public interface A{
    void myFirstMethod();
    void mySecondMethod();
}

And then I have this class:

public class MyClass{
    private List<? extends A> elements;

    public MyClass(){
        A obj = new A(){
            @Override
            public void myFirstMethod(){
              //SOME CODE
            }
            @Override
            public void mySecondMethod(){
              //SOME CODE
            }
        };
        elements.add(obj);
    }
}

I haven't use generics before (only things like List<String>...) so I can't see why this code doesn't compile. To be more precise, I get an error on the line elements.add(obj); that the method add is not applicable for these parameters.

EDIT: I've changed the code and now the elements.add(obj) compiles fine, but I have another problem.

public class MyClass{
    private List<A> elements;

    public MyClass(List<A> elements){
        this.elements = elements;
        elements.add(obj);
    }
}

When I try to do this, it doesn't compile.

//A1 implements A
List<A1> list = new ArrayList<A1>();
MyClass(list);

How could I fix this?

like image 453
mario595 Avatar asked Mar 03 '14 15:03

mario595


Video Answer


1 Answers

Imagine that you have two subclasses:

class A1 implements A {...}
class A2 implements A {...}

Then you could write:

List<? extends A> elements = new ArrayList<A1>(); // a list of A1

But then this should not compile:

elements.add(new A2()); //oops: an A2 is not an A1

For that reason, you can't add anything but null to a List<? extends A> because you don't know what actual generic type it is. In other words, ? extends A means a specific, but unknown, subtype of A (or A itself).

In your case, a List<A> would probably do what you expect - you would be able to add some A1s and some A2s to it.

like image 130
assylias Avatar answered Oct 08 '22 05:10

assylias