Search code examples
javaconstructorconflictvariadic-functions

Java constructor varargs conflict when passing string


I have an issue with one of my class. I'm using a "varargs" constructor for unknown number of parameter.

public Groupe(String...nom){        
    for(String item:nom){   
        this.nom.add(item.toLowerCase());
    }
}

public Groupe(String nom){      
    String[] list =nom.split(",");
    for(String s : list){           
        this.nom.add(s.toLowerCase());
    }
}

The first constructor is called...that's fine, but there is a conflict when passing only ONE parameter with the second contructor. I would like to use the second constructor when passing only one string, and the first if 2 and more parameters.

I'd want to handle this new Groupe("Foo,Bar");

This is where I call it. I suspect the "error" comes from there

public void reserver(String...nom){
    Groupe gr = new Groupe(nom);
    passager.add(gr);       
}

I don't pass a String, but a Varargs (tab?)...


Solution

  • It should be fine, with the caveat that null can be converted to either String[] or String:

    public class Test {
    
        public Test(String single) {
            System.out.println("Single");
        }
    
        public Test(String... multiple) {
            System.out.println("Multiple");
        }
    
        public static void main(String[] args) {
            new Test("Foo"); // Single
            new Test("Foo", "Bar"); // Multiple
            new Test(); // Effectively multiple
            // new Test(null); // Doesn't compile - ambiguous
            new Test((String) null); // Single
        }
    }
    

    EDIT: Now that you've shown us the calling code, that's definitely the problem:

    public void reserver(String...nom){
        Groupe gr = new Groupe(nom);
        passager.add(gr);       
    }
    

    Here, the type of nom is String[] - so it will always call the first constructor. You've got an array of strings there - under what circumstances do you want to call the second constructor?

    To be honest, given that the two constructors act significantly differently, I would actually make both constructors private, and provide static methods:

    public static Groupe fromStringArray(String... nom)
    
    public static Groupe fromCommaSeparatedString(String nom)
    

    Then it will be absolutely clear what you're expecting in each case.