Подтвердить что ты не робот

Техническая причина отсутствия параметров по умолчанию в Java

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

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

Кто-нибудь знает, есть ли твердая техническая причина, которая сделала бы что-то вроде

void myFunc(int a=1, int b=2) {...}

нежелательный или недействительный в новой версии Java?

4b9b3361

Ответ 1

Я не знаю технической причины, кроме того, что она сложна, какие значения опущены, а какие нет.

Например, в вашем примере, если было передано только одно целое, является ли оно a или b, которое должно быть выполнено по умолчанию? Скорее всего, a, но он добавляет этот уровень двусмысленности.

Простым решением было бы

void myFunc(Integer a, Integer b) {
  if (a == null) a = 1;
  if (b == null) b = 2;

}

Да, он более длинный, и да, он скрывает дефолт в коде, а не подпись метода (который затем может быть показан в JavaDoc), но он обеспечивает соблюдение согласованности.

Ответ 2

Это не было в исходной версии Java, потому что они решили, что им это не нужно, возможно, чтобы все было просто.

Добавление его теперь было бы сложным, потому что это нужно сделать с обратной совместимостью. Добавление varargs, autoboxing и generics в Java5 было серьезным делом, и это можно было сделать только с ограниченной функциональностью (например, стиранием стилей) и ценой повышенной сложности (правила разрешения нового метода делают хорошие вопросы об экзамене).

Ваш лучший снимок будет с языком, отличным от Java, на JVM. Возможно, у одного из них уже есть это.

Ответ 3

Чтобы избежать неоднозначности. Поддержка метода поддержки Java.

Предположим, что код ниже:

public int add(int a) {
    // do something
}

public int add(int a, int b = 0) {
    // do something
}

Когда мы вызываем add(12), вы можете сказать мне, какая функция вызывается?

Ответ 4

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

Именованная ассоциация является самодокументирующей. Напротив, ассоциация позиционных аргументов является кратким, но она заставляет вас все время ссылаться на определение метода, чтобы проверить, какой аргумент ожидается в n-й позиции при каждом вызове. Это смешно и мотивирует нас искать решения, такие как шаблон Builder. Builder фактически решает обе проблемы сразу, потому что именованная ассоциация является синонимом необязательных аргументов. Но Builder полезен только для пользователя. Дизайнер API все равно должен тратить пространство/время на создание класса Builder. Шаблоны-фанатики могут не соглашаться, но для каждого метода с именованными/необязательными аргументами можно создать класс Builder. Языковой дизайн должен устранить эту глупую картину. Но я не знаю, насколько они совместимы с списком переменных аргументов.