#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 не имеет значения.