Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't Java call the (List<Object>) method, if I have an (Object...) one?

I have the following class which stores a list of object arrays.

public class Test {
    private List<Object[]> list = new ArrayList<Object[]>();

    public void addList(Object... obj) {
        list.add(obj);
    }

    public void addList(List<Object> lst) {
        list.add(lst.toArray());
    }
}

When I call the following, the overloaded method addList(Object... obj) is called but I want the addList(List<Object> lst) to be called. How can I do this?

public class Main {
    public static void main(String[] args) {
        Test testObj = new Test();
        List<String> myStrings = new ArrayList<String>();
        myStrings.add("string 1");
        myStrings.add("string 2");
        myStrings.add("string 3");

        // The variable argument method is called but this is a list!
        testObj.addList(myStrings);

    }    
}
like image 563
Will Avatar asked Aug 15 '11 12:08

Will


5 Answers

Change List<Object> to List<?> to capture lists of any type of object. I tried this and it printed "in List":

import java.util.ArrayList;
import java.util.List;

public class Test {
    private List<Object[]> list = new ArrayList<Object[]>();

    public void addList(Object... obj) {
        System.out.println("in object");
        list.add(obj);
    }

    public void addList(List<?> lst) {
        System.out.println("in List<?>");
        list.add(lst.toArray());
    }

    public static void main(String[] args) {
        Test testObj = new Test();
        List<String> myStrings = new ArrayList<String>();
        myStrings.add("string 1");
        myStrings.add("string 2");
        myStrings.add("string 3");

        // The variable argument method is called but this is a list!
        testObj.addList(myStrings);

    } 
}
like image 192
Datajam Avatar answered Oct 19 '22 22:10

Datajam


It's problem of Java Generic. You cannot assign List<String> to List<Object>.

See also: Java Reference assignment with generic lists

like image 33
user802421 Avatar answered Oct 19 '22 23:10

user802421


Rewrite the type of you non-variadic method to use a wildcard:

public void addList(List<?> lst) {
    list.add(lst.toArray());
}

Then List<String> will be a subtype of the parameter type.

like image 35
hmakholm left over Monica Avatar answered Oct 19 '22 22:10

hmakholm left over Monica


List<String> is not a subclass of List<Object>. So that overload will never be called, even if you remove the ... variant.

like image 22
Oliver Charlesworth Avatar answered Oct 20 '22 00:10

Oliver Charlesworth


Change your method to

public void addList(List<?> lst) {
    list.add(lst.toArray());
}
like image 33
Garrett Hall Avatar answered Oct 19 '22 22:10

Garrett Hall