Эта статья участвует в "Месяце тем Java - Заметки по отладке Java", подробности см.Ссылка на мероприятие
вопрос
Как использовать необязательные параметры в Java? Есть ли спецификация для необязательных параметров?
отвечать
Ответ 1
В некоторой степени,varargs
(т. е. аргументы переменной длины) могут это сделать. В дополнение к этому должны быть указаны все переменные в объявлении метода. Если вы хотите, чтобы переменная была необязательной, вы можете ее перегрузить, а перегруженный метод не принимает никаких параметров.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}
Ответ 2
Необязательные параметры в Java можно эмулировать несколькими способами:
- перегрузка метода
void foo(String a, Integer b) {
//...
}
void foo(String a) {
foo(a, 0); // b 的默认值为 0
}
foo("a", 2);
foo("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");
Недостаток этого метода: если типы необязательных параметров различны, проверка статического типа будет недействительной. Кроме того, если каждый параметр имеет разное значение, то существуют и другие способы их различения.
- нулевой
Из-за ограничений вышеуказанных методов вы можете использовать нулевое значение (null
), а затем продолжить анализ каждого параметра в теле метода;
void foo(String a, Integer b, Integer c) {
b = b != null ? b : 0;
c = c != null ? c : 0;
//...
}
foo("a", null, 2);
На этом этапе должны быть указаны все значения параметров, но их значения по умолчанию могут бытьnull
.
- необязательный класс
Этот метод аналогичен методу с использованием null, но в Java 8 разрешены необязательные классы в качестве значений параметров по умолчанию;
void foo(String a, Optional<Integer> bOpt) {
Integer b = bOpt.isPresent() ? bOpt.get() : 0;
//...
}
foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());
- Шаблон конструктора
С помощью конструктора, вводя при этом отдельный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();
- Maps
Когда параметров слишком много и обычно используется большинство значений по умолчанию, параметры метода могут быть переданы им как их карта имени/значения;
void foo(Map<String, Object> 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.<String, Object>of(
"a", "a",
"b", 2,
"d", "value"));
В Java 9 это можно упростить, используя:
@SuppressWarnings("unchecked")
static <T> T getParm(Map<String, Object> map, String key, T defaultValue)
{
return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
}
void foo(Map<String, Object> parameters) {
String a = getParm(parameters, "a", "");
int b = getParm(parameters, "b", 0);
// d = ...
}
foo(Map.of("a","a", "b",2, "d","value"));
Выше приведены некоторые из 6 способов использования необязательных параметров, вы можете добиться желаемых результатов, органично комбинируя их.
Ответ 3
Поскольку в Java 1.5 есть необязательные параметры, вы можете объявить свой метод следующим образом:
public void doSomething(boolean... optionalFlag) {
// 默认为 "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
Тогда вы можете либо позвонитьdoSomething()
, вы также можете позвонитьdoSomething(true)
.
происхождение
Статья переведена с Stack Overflow:Java optional parameters