Поддерживает ли Java значения параметров по умолчанию?
Я наткнулся на некоторый Java-код, который имел следующую структуру:
publicMyParameterizedFunction(String param1, int param2) { this(param1, param2, false); }
publicMyParameterizedFunction(String param1, int param2, boolean param3) { //use all three parameters here }
Я знаю, что в C ++ я могу присвоить параметру значение по умолчанию. Например:
voidMyParameterizedFunction(String param1, int param2, bool param3=false);
Поддерживает ли Java такой синтаксис? Есть ли какие-либо причины, по которым этот двухэтапный синтаксис предпочтительнее?
Переведено автоматически
Ответ 1
Нет, структура, которую вы нашли, заключается в том, как Java обрабатывает это (то есть с перегрузкой вместо параметров по умолчанию).
Что касается конструкторов, смотрите в разделе "Эффективная Java: руководство по языку программирования" в пункте 1 совета (рассматривайте статические заводские методы вместо конструкторов), если перегрузка становится сложной. Для других методов может помочь переименование некоторых вариантов или использование объекта parameter.
Это когда у вас такая сложность, что дифференцировать сложно. Конкретный случай - это когда вам нужно дифференцировать, используя порядок параметров, а не только количество и тип.
в котором некоторые поля могут иметь значения по умолчанию или иным образом быть необязательными.
Ответ 3
Существует несколько способов имитации параметров по умолчанию в Java:
Перегрузка метода.
void foo(Строка a, целое число b) { //... }
void foo(строка a) { foo(a, 0); // здесь 0 - значение по умолчанию для b }
foo("a", 2); foo("a");
Одним из ограничений этого подхода является то, что он не работает, если у вас есть два необязательных параметра одного типа и любой из них может быть опущен.
Переменные.
a) Все необязательные параметры имеют один и тот же тип:
b) Типы необязательных параметров могут отличаться:
voidfoo(String a, Object... b) { Integerb1=0; Stringb2=""; if (b.length > 0) { if (!(b[0] instanceof Integer)) { thrownewIllegalArgumentException("..."); } b1 = (Integer)b[0]; } if (b.length > 1) { if (!(b[1] instanceof String)) { thrownewIllegalArgumentException("..."); } b2 = (String)b[1]; //... } //... }
foo("a"); foo("a", 1); foo("a", 1, "b2");
Основным недостатком этого подхода является то, что если необязательные параметры имеют разные типы, вы теряете статическую проверку типов. Более того, если каждый параметр имеет разное значение, вам нужен какой-то способ их различать.
Nulls. Чтобы устранить ограничения предыдущих подходов, вы можете разрешить значения null, а затем проанализировать каждый параметр в теле метода:
void foo(Строка a, целое число b, целое число c) { b = b != null? b: 0; c = c != null? c: 0; //... }
foo("a", null, 2);
Теперь должны быть предоставлены значения всех аргументов, но значения по умолчанию могут быть равны null.
Необязательный класс. Этот подход похож на nulls, но использует необязательный класс Java 8 для параметров, имеющих значение по умолчанию:
void foo(строка a, необязательно bOpt) { Целое число b = bOpt.OrElse(0); //... }
FooBuilder setA(String a) { this.a = a; returnthis; }
FooBuilder setB(Integer b) { this.b = b; returnthis; }
Foo build() { returnnewFoo(a, b); } }
Foofoo=newFooBuilder().setA("a").build();
Карты. Когда количество параметров слишком велико и для большинства из них обычно используются значения по умолчанию, вы можете передать аргументы метода в виде сопоставления их имен / значений:
void foo(Map<Строка, объект> параметры) { Строка a = ""; Целое число b = 0; if (parameters.containsKey("a")) { if (!(parameters.get("a") экземпляр целого числа)) { создать новое исключение IllegalArgumentException("..."); } a = (Строка)parameters.get("a"); } else if (parameters.containsKey("b")) { //... } //... }