Дополнительные параметры Java
Как использовать дополнительные параметры в Java? Какая спецификация поддерживает дополнительные параметры?
- Как обрабатывать нулевые или необязательные параметры структуры dll в C #
- Могу ли я иметь необязательный параметр для веб-службы ASP.NET SOAP
- C # 4.0 необязательные аргументы out / ref
- Как использовать необязательные параметры в хранимой процедуре T-SQL?
- C # 4.0: Можно ли использовать TimeSpan в качестве необязательного параметра со значением по умолчанию?
- C # 4.0, необязательные параметры и параметры не работают вместе
- Дополнительные параметры C # для переопределенных методов
varargs могли это сделать (в некотором смысле). Помимо этого, все переменные в объявлении метода должны быть предоставлены. Если вы хотите, чтобы переменная была необязательной, вы можете перегрузить метод, используя подпись, которая не требует параметра.
private boolean defaultOptionalFlagValue = true; public void doSomething(boolean optionalFlag) { ... } public void doSomething() { doSomething(defaultOptionalFlagValue); }
Существует несколько способов моделирования необязательных параметров в Java:
-
Перегрузка метода.
void foo(String a, Integer b) { //... } void foo(String a) { foo(a, 0); // here, 0 is a default value for b } foo("a", 2); foo("a");
Одним из ограничений этого подхода является то, что он не работает, если у вас есть два необязательных параметра одного типа, и любой из них можно опустить.
-
С переменным числом аргументов.
a) Все необязательные параметры одного типа:
void foo(String a, Integer... b) { Integer b1 = b.length > 0 ? b[0] : 0; Integer b2 = b.length > 1 ? b[1] : 0; //... } foo("a"); foo("a", 1, 2);
б) Типы необязательных параметров могут быть разными:
void foo(String a, Object... b) { Integer b1 = 0; String b2 = ""; if (b.length > 0) { if (!(b[0] instanceof Integer)) { throw new IllegalArgumentException("..."); } b1 = (Integer)b[0]; } if (b.length > 1) { if (!(b[1] instanceof String)) { throw new IllegalArgumentException("..."); } b2 = (String)b[1]; //... } //... } foo("a"); foo("a", 1); foo("a", 1, "b2");
Основным недостатком этого подхода является то, что, если необязательные параметры имеют разные типы, вы теряете контроль статического типа. Кроме того, если каждый параметр имеет различный смысл, вам нужно каким-то образом отличить их.
-
Нулевые. Чтобы устранить ограничения предыдущих подходов, вы можете разрешить нулевые значения и затем проанализировать каждый параметр в теле метода:
void foo(String a, Integer b, Integer c) { b = b != null ? b : 0; c = c != null ? c : 0; //... } foo("a", null, 2);
Теперь должны быть указаны все значения аргументов, но по умолчанию они могут быть пустыми.
-
Необязательный class. Этот подход похож на нуль, но использует Java 8 Необязательный class для параметров, которые имеют значение по умолчанию:
void foo(String a, Optional
bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... } foo("a", Optional.of(2)); foo("a", Optional. absent()); Необязательно делает метод контракт явным для вызывающего, однако, такая подпись может быть слишком многословной.
Обновление: Java 8 включает class
java.util.Optional
из коробки, поэтому нет необходимости использовать guava по этой конкретной причине в java 8. Название метода немного отличается. -
Рисунок Builder. Шаблон построителя используется для конструкторов и реализуется путем введения отдельного classа Builder:
class Foo { private final String a; private final Integer b; Foo(String a, Integer b) { this.a = a; this.b = b; } //... } class FooBuilder { private String a = ""; private Integer b = 0; FooBuilder setA(String a) { this.a = a; return this; } FooBuilder setB(Integer b) { this.b = b; return this; } Foo build() { return new Foo(a, b); } } Foo foo = new FooBuilder().setA("a").build();
-
Карты. Когда количество параметров слишком велико, и для большинства из них обычно используются значения по умолчанию, вы можете передавать аргументы метода как карту их имен / значений:
void foo(Map
parameters) { String a = ""; Integer b = 0; if (parameters.containsKey("a")) { if (!(parameters.get("a") instanceof Integer)) { throw new IllegalArgumentException("..."); } a = (Integer)parameters.get("a"); } if (parameters.containsKey("b")) { //... } //... } foo(ImmutableMap. of( "a", "a", "b", 2, "d", "value"));
Обратите внимание, что вы можете комбинировать любой из этих подходов для достижения желаемого результата.
Вы можете использовать что-то вроде этого:
public void addError(String path, String key, Object... params) { }
Параметр переменной является необязательным. Он рассматривается как нулевой массив объектов.
Как ни странно, я не мог найти ничего об этом в документации, но это работает!
Это «новое» в Java 1.5 и выше (не поддерживается в Java 1.4 или ранее).
Я вижу, что пользователь bhoot упоминал об этом слишком ниже.
Существуют дополнительные параметры с Java 5.0. Просто объявите свою функцию следующим образом:
public void doSomething(boolean... optionalFlag) { //default to "false" //boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false; }
вы можете позвонить с помощью doSomething();
или doSomething(true);
Теперь.
К сожалению, Java напрямую не поддерживает параметры по умолчанию.
Однако я написал набор аннотаций JavaBean, и один из них поддерживает параметры по умолчанию, такие как:
protected void process( Processor processor, String item, @Default("Processor.Size.LARGE") Size size, @Default("red") String color, @Default("1") int quantity) { processor.process(item, size, color, quantity); } public void report(@Default("Hello") String message) { System.out.println("Message: " + message); }
Обработчик annotations генерирует перегрузку метода для правильной поддержки этого метода.
См. http://code.google.com/p/javadude/wiki/Annotations
Полный пример: http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample
На Java нет дополнительных параметров. Что вы можете сделать, это перегрузка функций, а затем передача значений по умолчанию.
void SomeMethod(int age, String name) { // } // Overload void SomeMethod(int age) { SomeMethod(age, "John Doe"); }
Были упомянуты VarArgs и перегрузка. Другим вариантом является шаблон Builder, который будет выглядеть примерно так:
MyObject my = new MyObjectBuilder().setParam1(value) .setParam3(otherValue) .setParam6(thirdValue) .build();
Хотя этот шаблон был бы наиболее подходящим, если вам нужны дополнительные параметры в конструкторе.
В JDK> 1.5 вы можете использовать его так:
public class NewClass1 { public static void main(String[] args) { try { someMethod(18); // Age : 18 someMethod(18, "John Doe"); // Age & Name : 18 & John Doe } catch (Exception e) { e.printStackTrace(); } } static void someMethod(int age, String... names) { if (names.length > 0) { if (names[0] != null) { System.out.println("Age & Name : " + age + " & " + names[0]); } } else { System.out.println("Age : " + age); } } }
Это будет зависеть от того, чего вы хотите достичь, varargs или перегрузки метода должны решить большинство сценариев.
но имейте в виду не перегружать метод перегрузки. это приводит к путанице.
Укороченная версия :
Использование трех точек :
public void foo(Object... x) { String first = x.length > 0 ? (String)x[0] : "Hello"; int duration = x.length > 1 ? Integer.parseInt((String) x[1]) : 888; } foo("Hii", ); foo("Hii", 146);
(на основании ответа Виталия Федоренко)
Вы можете делать вещи, используя перегрузку метода, как это.
public void load(String name){ } public void load(String name,int age){}
Также вы можете использовать @Nullable аннотацию
public void load(@Nullable String name,int age){}
просто передайте null как первый параметр.
Если вы передаете переменную того же типа, вы можете использовать эту
public void load(String name...){}
Перегрузка – это хорошо, но если есть много переменных, которые требуют значения по умолчанию, вы получите:
public void methodA(A arg1) { } public void methodA( B arg2,) { } public void methodA(C arg3) { } public void methodA(A arg1, B arg2) { } public void methodA(A arg1, C arg3) { } public void methodA( B arg2, C arg3) { } public void methodA(A arg1, B arg2, C arg3) { }
Поэтому я бы предложил использовать аргумент Variable Argument, предоставляемый Java. Вот ссылка для объяснения.
Java теперь поддерживает опции в 1.8, я застрял в программировании на Android, поэтому я использую нули, пока не смогу реорганизовать код для использования необязательных типов.
Object canBeNull() { if (blah) { return new Object(); } else { return null; } } Object optionalObject = canBeNull(); if (optionalObject != null) { // new object returned } else { // no new object returned }
Вы можете использовать class, который работает так же, как строитель, чтобы содержать ваши дополнительные значения, подобные этому.
public class Options { private String someString = "default value"; private int someInt= 0; public Options setSomeString(String someString) { this.someString = someString; return this; } public Options setSomeInt(int someInt) { this.someInt = someInt; return this; } } public static void foo(Consumer consumer) { Options options = new Options(); consumer.accept(options); System.out.println("someString = " + options.someString + ", someInt = " + options.someInt); }
Использовать как
foo(o -> o.setSomeString("something").setSomeInt(5));
Выход
someString = something, someInt = 5
Чтобы пропустить все необязательные значения, вы должны называть его как foo(o -> {});
или, если хотите, вы можете создать второй метод foo()
, который не принимает необязательные параметры.
Используя этот подход, вы можете указать необязательные значения в любом порядке без какой-либо двусмысленности. Вы также можете иметь параметры разных classов, в отличие от varargs. Этот подход будет еще лучше, если вы можете использовать annotations и генерации кода для создания classа «Параметры».
Аргументы по умолчанию не могут использоваться в Java и C #. Где в C ++ и Python мы можем их использовать.
В Java нам нужно использовать 2 метода (функции) вместо одного с параметрами по умолчанию.
Пример:
Stash(int size); Stash(int size, int initQuantity);
Мы можем сделать необязательный параметр путем перегрузки метода или использования DataType …
| * | Перегрузка метода:
RetDtaTyp NamFnc(String NamPsgVar) { // |* CodTdo *| return RetVar; } RetDtaTyp NamFnc(String NamPsgVar) { // |* CodTdo *| return RetVar; } RetDtaTyp NamFnc(int NamPsgVar1, String NamPsgVar2) { // |* CodTdo *| return RetVar; }
Самый простой способ
| * | DataType … может быть необязательным параметром
RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar) { if(SrgOpnPsgVar.length == 0) SrgOpnPsgVar = DefSrgVar; // |* CodTdo *| return RetVar; }