Конфликт переменных параметров конструктора Java при передаче строки

#java #constructor #conflict #variadic-functions

#java #конструктор #конфликт #переменные-функции

Вопрос:

У меня проблема с одним из моих классов. Я использую конструктор «varargs» для неизвестного количества параметров.

 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());
    }
}
 

Вызывается первый конструктор … это нормально, но возникает конфликт при передаче только ОДНОГО параметра со вторым конструктором. Я хотел бы использовать второй конструктор при передаче только одной строки и первый, если 2 и более параметров.

Я бы хотел обработать эту новую группу («Foo, Bar»);

Вот где я это называю. Я подозреваю, что «ошибка» исходит оттуда

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

Я передаю не строку, а переменные (tab?)…

Ответ №1:

Все должно быть в порядке, с оговоркой, что null может быть преобразовано в либо String[] или 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
    }
}
 

РЕДАКТИРОВАТЬ: теперь, когда вы показали нам вызывающий код, это определенно проблема:

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

Здесь тип nom is String[] — поэтому он всегда будет вызывать первый конструктор. У вас там есть массив строк — при каких обстоятельствах вы хотите вызвать второй конструктор?

Честно говоря, учитывая, что два конструктора действуют существенно по-разному, я бы на самом деле сделал оба конструктора закрытыми и предоставил статические методы:

 public static Groupe fromStringArray(String... nom)

public static Groupe fromCommaSeparatedString(String nom)
 

Тогда будет абсолютно ясно, чего вы ожидаете в каждом конкретном случае.

Комментарии:

1. Я хочу справиться с этим: новый тест («Foo, Bar»);

2. @user1023021: Так в чем проблема? Это вызовет второй конструктор, который затем разделит строку на запятые.

3. Второй никогда не вызывается, потому что «Foo,Bar» также является строкой. Итак, вызывается конструктор varags, который я не хочу.

4. @user1023021: Нет, это не так. Запустите мой пример кода! Я подозреваю, что вы ввели себя в заблуждение с помощью любой используемой вами диагностики. К сожалению, вы не предоставили достаточно кода, чтобы мы могли его увидеть…

5. Вы правы. Но почему мой единственный конструктор не вызывается? Я попытался поместить его выше кратного. Я отредактирую OP и добавлю код, в котором я его вызываю

Ответ №2:

Может быть, это может быть решением:

 public Groupe(String...nom){       
    if (nom.length == 1) {
        add(nom[0].split(","));
    } else {
        add(nom);
    }
}

private void add(String[] list) {
    for(String s : list){           
        this.nom.add(s.toLowerCase());
    }
}
 

Комментарии:

1. На данный момент я использую аналогичное решение. Спасибо tulio

Ответ №3:

Часть varargs может быть пустой. Таким образом, вы можете получить то, что хотите, с помощью

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

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

Вы также могли бы, конечно, использовать один ctor с оператором if для длины входного массива, разделяя случаи 0 (не обработанные с помощью кода выше), 1 и> 1.

Ответ №4:

 public class OverloadVarArgs {

public static void main(String... args){
    OverloadVarArgs a = new OverloadVarArgs("One Argument");
    OverloadVarArgs b = new OverloadVarArgs("Two", "Arguments");
    OverloadVarArgs c = new OverloadVarArgs("One, Argument");

}

public OverloadVarArgs(String a){
    System.out.println("Constructor 1");
}

public OverloadVarArgs(String... a){
    System.out.println("Constructor 2");
}
}
 

Вывод:

Конструктор 1

Конструктор 2

Конструктор 1

Комментарии:

1. Я пробовал это… с одним параметром вызывается конструктор varargs, а не конструктор с одним параметром.

2. Порядок ctors в Java не имеет значения.