Необязательные параметры в Java | Заметки об отладке Java

Java

Эта статья участвует в "Месяце тем Java - Заметки по отладке Java", подробности см.Ссылка на мероприятие

вопрос

Как использовать необязательные параметры в Java? Есть ли спецификация для необязательных параметров?

отвечать

Ответ 1

В некоторой степени,varargs(т. е. аргументы переменной длины) могут это сделать. В дополнение к этому должны быть указаны все переменные в объявлении метода. Если вы хотите, чтобы переменная была необязательной, вы можете ее перегрузить, а перегруженный метод не принимает никаких параметров.

private boolean defaultOptionalFlagValue = true;

public void doSomething(boolean optionalFlag) {
    ...
}

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}

Ответ 2

Необязательные параметры в Java можно эмулировать несколькими способами:

  1. перегрузка метода
void foo(String a, Integer b) {
    //...
}

void foo(String a) {
    foo(a, 0); // b 的默认值为 0
}

foo("a", 2);
foo("a");

Ограничение этого метода заключается в том, что он не работает, если есть два необязательных параметра одного типа, любой из которых можно игнорировать.

  1. параметр переменной длины
  • Все необязательные параметры одного типа;
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");

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

  1. нулевой

Из-за ограничений вышеуказанных методов вы можете использовать нулевое значение (null), а затем продолжить анализ каждого параметра в теле метода;

void foo(String a, Integer b, Integer c) {
    b = b != null ? b : 0;
    c = c != null ? c : 0;
    //...
}

foo("a", null, 2);

На этом этапе должны быть указаны все значения параметров, но их значения по умолчанию могут бытьnull.

  1. необязательный класс

Этот метод аналогичен методу с использованием 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());
  1. Шаблон конструктора

С помощью конструктора, вводя при этом отдельный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();
  1. 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