Поддерживает ли Java значения параметров по умолчанию?

Я столкнулся с некоторым Java-кодом, который имел следующую структуру:

public MyParameterizedFunction(String param1, int param2)
{
    this(param1, param2, false);
}

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    //use all three parameters here
}

Я знаю, что в C++ я могу присвоить параметру значение по умолчанию. Например:

void MyParameterizedFunction(String param1, int param2, bool param3=false);

Поддерживает ли Java такой синтаксис? Есть ли причины, по которым этот двухшаговый синтаксис предпочтительнее?

Комментарии к вопросу (7)
Решение

Нет, найденная вами структура - это то, как Java обрабатывает это (то есть, с перегрузкой вместо параметров по умолчанию).

Для конструкторов, См. эффективное руководство по языку программирования Java: Руководство по программированию Совет по пункту 1 (Рассмотрите статические фабричные методы вместо конструкторов), если перегрузка становится сложной. Для других методов может помочь переименование некоторых случаев или использование объекта-параметра. Это происходит, когда у вас достаточно сложностей, чтобы их было трудно различать. Определенный случай - это когда нужно различать по порядку параметров, а не только по количеству и типу.

Комментарии (7)

Нет, но вы можете использовать в <а href="и http://en.wikipedia.org/wiki/Builder_pattern">Строитель узором</а>, как описано в <а href="https://stackoverflow.com/questions/222214/managing-constructors-with-many-parameters-in-java-1-4/222295#222295">это переполнение стека ответ</а>.

Как описано в связанном ответ, шаблон Builder позволяет писать код как

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

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

Комментарии (8)

Существует несколько способов имитации параметров по умолчанию в Java:

  1. Перегрузка метода.

пустота и Foo(строку, целое число b) { //... }

пустота и Foo(строка a) { фу(а, 0); // здесь 0 является значением по умолчанию для B }

фу("А", 2); ФОО("А");

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

  1. С varargs.

а) все необязательные параметры имеют одинаковый тип:

пустота и Foo(строку, целое число... б) { Число Б1 = б.длина и gt; 0 ? б[0] : 0; Число Б2 = б.длина > 1 ? Б[1] : 0; //... }

ФОО("А"); фу("А", 1, 2);

б) типы необязательных параметров может быть различным:

пустота и Foo(string значение объекта... б) { Целое число В1 = 0; Строка В2 = " по себе"; если (б.длина и gt; 0) { если (!(б[0] оператор instanceof целое)) { бросить новый IllegalArgumentException(" и..." - а); } Б1 = (целое число)б[0]; } если (б.длина > 1) { если (!(Б[1] оператор instanceof строка)) { бросить новый IllegalArgumentException(" и..." - а); } Б2 = (строка)Б[1]; //... } //... }

ФОО("А"); ФОО("А", 1); фу("А", 1, что "Б2" по);

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

  1. Нули. Чтобы устранить недостатки предыдущих подходов можно разрешить значения NULL, а затем проанализировать каждый параметр в методе тела:

пустота и Foo(строку, целое число b, целое число c) { б = б != значение null ? б : 0; с = с != значение null ? с : 0; //... }

фу("А", нуль, 2);

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

  1. Дополнительный класс. Этот подход близок к нулей, но использует Java 8 дополнительный класс для параметров, которые имеют значение по умолчанию:

пустота и Foo(строка, опционально в<число> bOpt) { Целое число b = bOpt.извращенц() ? bOpt.сделать() : 0; //... }

фу("А", необязательно.из(2)); ФОО("А", дополнительно.<целое>отсутствует());

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

  1. Шаблон строителя. Шаблон Builder используется для конструкторов и реализуется путем введения отдельного класса застройщика:

класс Foo { частная итоговой строки; частная окончательной целое число b;

Фу(строку, целое число b) { это.а = а; это.б = б; }

//... }

FooBuilder класса { частная строку a = назальный;; частная целое число b = 0;

Сэта FooBuilder(строка a) { это.а = а; возвращение этого; }

FooBuilder setB(число b) { это.б = б; возвращение этого; }

Фу сборки() { возврат новый фу(А, Б); } }

Фу фу = новый FooBuilder().сэта("А").создать();

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

пустота фу(карта в<строка, объект и gt; Параметры) { Строка a = назальный;; Целое число b = 0; если (параметры.containsKey("А")) { если (!(параметры.сделать("А") оператор instanceof целое)) { бросить новый IllegalArgumentException(" и..." - а); } а = (строка)параметры.получить("А"); } остальное, если (параметры.containsKey (на"Б" - а)) { //... } //... }

ФОО(ImmutableMap.<строку, объект>о( "А", "А", на "Б" в, 2, на "Д" В, С "значение" с));

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

Комментарии (8)

К сожалению, нет.

Комментарии (13)

К сожалению, да.

void MyParameterizedFunction(String param1, int param2, bool param3=false) {}

может быть написан на Java 1.5, как:

void MyParameterizedFunction(String param1, int param2, Boolean... params) {
    assert params.length  0 ? params[0].booleanValue() : false;
}

Но Ли или не вы должны зависеть от того, как вы относитесь к компилятору генерировать

new Boolean[]{}

для каждого вызова.

Для нескольких параметров defaultable:

void MyParameterizedFunction(String param1, int param2, bool param3=false, int param4=42) {}

может быть написан на Java 1.5, как:

void MyParameterizedFunction(String param1, int param2, Object... p) {
    int l = p.length;
    assert l  0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue() : 42;
}

Это соответствует синтаксису C++, которая позволяет только дефолтных параметров в конце списка параметров.

Вне синтаксиса, есть разница, где это запуска типа проверка передаваемых параметров defaultable и типа C++ проверяет их во время компиляции.

Комментарии (9)

Нет, но вы можете очень легко подражать им. Что в C++ был:

public: void myFunction(int a, int b=5, string c="test") { ... }

В Java, это будет перегруженная функция:

public void myFunction(int a, int b, string c) { ... }

public void myFunction(int a, int b) {
    myFunction(a, b, "test");
}

public void myFunction(int a) {
    myFunction(a, 5);
}

Ранее упоминалось, что параметры по умолчанию вызвал неоднозначные случаи в перегрузке функций. Это просто не соответствует действительности, мы можем видеть в случае с++: Да, может быть, это может создать неоднозначных случаях, но эти проблемы можно легко решить. Он просто не'т разработан в Java, наверное, потому что создатели хотели, гораздо проще язык как C++ был - если бы они имели право, это другой вопрос. Но большинство из нас Дон'т думаю, что он использует Java из-за своей простоты.

Комментарии (6)

Вы можете сделать это в Scala, который работает на JVM и совместима с Java-программы. http://www.scala-lang.org/

т. е.

class Foo(var prime: Boolean = false, val rib: String)  {}
Комментарии (4)

Ни но самый простой способ реализации этой является:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    param3 = param3 == null ? false : param3;
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

или вместо тернарный оператор, вы можете использовать если:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    if (param3 == null) {
        param3 = false;
    }
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}
Комментарии (0)

Возможно, я говорю очевидные вещи, но почему бы просто не реализовать "по умолчанию" и сам параметр?

public class Foo() {
        public void func(String s){
                func(s, true);
        }
        public void func(String s, boolean b){
                //your code here
        }
}

по умолчанию, вы бы либо использовать

func("my string");

и если вы не'т хотите использовать по умолчанию, вы бы использовать

func("my string", false);
Комментарии (4)

Как скала упоминается, Котлин тоже стоит упомянуть. В параметрах функции Котлин могут иметь значения по умолчанию, и они могут даже ссылаться на другие параметры:

fun read(b: Array, off: Int = 0, len: Int = b.size) {
    ...
}

Как скала, Котлин работает на JVM и может быть легко интегрирован в существующие Java-проектов.

Комментарии (0)

Нет. Вообще Ява не'т иметь много (каких-либо) синтаксический сахар, так как они пытались сделать простым языком.

Комментарии (4)

Нет.

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

Комментарии (0)

Это не поддерживается, но есть несколько вариантов, как используя шаблон объекта параметра с некоторым синтаксис сахара:

public class Foo() {
    private static class ParameterObject {
        int param1 = 1;
        String param2 = "";
    }

    public static void main(String[] args) {
        new Foo().myMethod(new ParameterObject() {{ param1 = 10; param2 = "bar";}});
    }

    private void myMethod(ParameterObject po) {
    }
}

В этом примере мы построим ParameterObject со значениями по умолчанию, и переопределить их в секции инициализации экземпляра класса { параметр1 = 10; параметр2 = то "баре";}

Комментарии (0)

Попробуйте это решение:

public int getScore(int score, Integer... bonus)
{
    if(bonus.length > 0)
    {
        return score + bonus[0];
    }

    return score;
}
Комментарии (0)

Подобный подход к https://stackoverflow.com/a/13864910/2323964 которая работает на Java 8, чтобы использовать интерфейс с добытчиками по умолчанию. Это будет более пробельных многословен, но из, и это'ы очень удобно, если у вас есть куча случаев, когда вы действительно хотите обратить внимание на параметры.

public class Foo() {
    public interface Parameters {
        String getRequired();
        default int getOptionalInt(){ return 23; }
        default String getOptionalString(){ return "Skidoo"; }
    }

    public Foo(Parameters parameters){
        //...
    }

    public static void baz() {
        final Foo foo = new Foo(new Person() {
            @Override public String getRequired(){ return "blahblahblah"; }
            @Override public int getOptionalInt(){ return 43; }
        });
    }
}
Комментарии (0)

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

`` инт фу(тип int а) { // что-то с собой возврата; }

инт фу() { возврата из Foo(0); // здесь 0 является значением по умолчанию для } ``

Комментарии (0)

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

Просто добавить @GenerateMethodInvocationBuilder на класс или интерфейс, и @по умолчанию для параметров в методах, где вы хотите, чтобы значения по умолчанию. Строитель будет сгенерирован во время компиляции, используя значения по умолчанию, которые вы указали в комментарии.

@GenerateMethodInvocationBuilder
public class CarService {
 public CarService() {
 }

 public String getCarsByFilter(//
   @Default("Color.BLUE") Color color, //
   @Default("new ProductionYear(2001)") ProductionYear productionYear,//
   @Default("Tomas") String owner//
 ) {
  return "Filtering... " + color + productionYear + owner;
 }
}

И затем вы можете вызывать методы.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .invoke(instance);

Или установить какое-либо из значений по умолчанию на что-то другое.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);
Комментарии (0)

Есть полдюжины или лучше такие вопросы, как этот, в конечном итоге, вы прибудете в статический шаблон фабрики ... см. крипто API для этого. Рода трудно объяснить, но думать об этом этот путь: Если у вас есть конструктор по умолчанию или иначе, единственный способ распространить государства вне фигурных скобок либо иметь логическое метода IsValid; ( вместе с нулем по умолчанию значение V не конструктор), или сгенерировать исключение, что не информативно при получении его обратно из поля пользователей.

Код правильный побери, я пишу тыс. конструкторов линию и делать то, что мне нужно. Я нахожу с помощью метода IsValid на строительном объекте - другими словами, Две он-лайн конструкторы - но по какой-то причине, я переход на статический шаблон фабрики. Мне просто кажется, что вы можете сделать много, если вы в вызове метода, есть еще синхронизация() вопросы, но по умолчанию может быть 'подставляться' лучше ( безопаснее )

Я думаю, что нам нужно сделать здесь-это решить проблему null как значение по умолчанию визави что-то одной строкой=новая строка (на" глаз"); в качестве переменной-члена, затем делаю проверку на null перед тем, как присвоить строку передается конструктору.

Очень замечательное количество сырья, стратосферный информатика сделано в Java.

C++ и так далее либы поставщика, да. Java может обогнать их в больших масштабах сервера из-за его'ы массивных элементов. Исследование статический инициализатор блоков, оставайтесь с нами.

Комментарии (0)

Это, как я это сделал ... это's не так удобно, возможно, что 'необязательный аргумент' против определенного параметра, но он получает работу:

public void postUserMessage(String s,boolean wipeClean)
{
    if(wipeClean)
    {
        userInformation.setText(s + "\n");
    }
    else
    {
        postUserMessage(s);
    }
}

public void postUserMessage(String s)
{
    userInformation.appendText(s + "\n");
}

Заметьте, я могу ссылаться на то же самое имя метода либо просто строку или я могу вызвать его с помощью строки и логические значения. В этом случае установка wipeClean истина будет заменить весь текст в моем textarea с указанной строкой. Установка wipeClean false или оставляя его все вместе просто добавляет текст в текстовой области.

Также обратите внимание, я не повторяющийся код в этих двух методах, я всего лишь добавляя функциональные возможности, чтобы сбросить текстовое поле Создать новый метод с тем же именем только с дополнительным логическим.

Я думаю, что это немного чище, чем если Java представила 'необязательный аргумент' для наших параметров, так как мы должны затем код для значения по умолчанию и т. д. В этом примере, я не'т нужно беспокоиться об этом. Да, я добавил еще один метод в моем классе, но это'ы легче читать в долгосрочной перспективе, по моему скромному мнению.

Комментарии (0)

Нет, но у нас есть альтернатива в виде перегружая функции.

вызывается, когда параметр передается

void operation(){

int a = 0;
int b = 0;

} 

вызывается, когда "А" параметр был принят

void operation(int a){

int b = 0;
//code

} 

вызывается, когда параметр B прошла

void operation(int a , int b){
//code
} 
Комментарии (0)