Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

java - Can't add a ModuleInfo object to ArrayList<? extends ModuleInfo>

I'm not sure if I am using generics correctly, but basically I created an Arraylist<? extends ModuleInfo> moduleList and ModuleInfo m objects, and tried to call moduleList.add(m). However it won't compile and I am getting an error message that seems a bit cryptic to me. The error message and code are below. Anyone else know what is wrong?

void load() {
    ArrayList<? extends ModuleInfo> moduleList = new ArrayList();
    Iterator<? extends ModuleInfo> iter_m;
    ModuleInfo m;

    //get modules that depend on this module
    //retrieve list of all modules and iterate trough each one
    iter_m = Lookup.getDefault().lookupAll(ModuleInfo.class).iterator();
    while(iter_m.hasNext()) {
        m = iter_m.next();
        //loop through modules dependencies and check for a dependency on this module
        for(Dependency d : m.getDependencies()) {
            //if found, the module to the list
            if(d.getName().equals(GmailAuthManager.class.getPackage().getName())) {
                moduleList.add(m);
                break;
            }
        }
    }
}

Error is a follows:

error: no suitable method found for add(ModuleInfo)
                    moduleList.add(m);
    method ArrayList.add(int,CAP#1) is not applicable
      (actual and formal argument lists differ in length)
    method ArrayList.add(CAP#1) is not applicable
      (actual argument ModuleInfo cannot be converted to CAP#1 by method invocation conversion)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends ModuleInfo from capture of ? extends ModuleInfo
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Suppose you create an arraylist as: -

List<? extends Animal> list = new ArrayList<Dog>();

Now that list reference can point to an ArrayList<Dog> or an ArrayList<Cat> or whatever. So, when you try to add an Animal reference to that list, compiler is not sure that, that reference is actually pointing the same implementation that is used in actual Concrete type of ArrayList.

For e.g.: - You might add an Animal reference pointing to Cat into the above ArrayList, which is a disaster. That's why Compiler does not allow it.

Animal cat = new Cat();
list.add(cat);  // OOps.. You just put a Cat in a list of Dog

You can rather just create a List<Animal>, and you can add any subtype to it: -

List<Animal> newList = new ArrayList<Animal>();
newList.add(new Cat());  // Ok. Can add a `Cat` to an `Animal` list.

The above code works because, a List<Animal> reference can only point to an ArrayList<Animal>.


So, in your example, you can use: -

List<ModuleInfo> list = new ArrayList<ModuloInfo>();

As a side note, you should always program to interface rather than implementation. So, always have your reference types of interface, in this case List rather than ArrayList.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...