Действительно ли перегрузка — единственный способ получить значения по умолчанию для параметров метода в Java?

StackOverflow https://stackoverflow.com/questions/618276

  •  03-07-2019
  •  | 
  •  

Вопрос

Я новичок в Java, а также в Python и PHP, я привык к значениям по умолчанию для параметров функции.

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

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

Помню, это меня уже раздражало в некоторых кратких экскурсах по C++ и ActionScript.Есть ли у более опытных Java-разработчиков какой-нибудь ярлык для этого?

Мне кажется, технически на вопрос по сумме всех постов дан ответ: «Да, это так».Я открыл сообщение в вики ниже, чтобы собрать различные альтернативные решения, пожалуйста, внесите свой вклад, если хотите.Я нашел все это очень полезным источником вдохновения и примерами для изучения типичных конструкций Java.

Это было полезно?

Решение 6

Похоже, что "да, это", за исключением:

Подобные эффекты могут быть достигнуты с помощью varargs , как было предложено Полом Уиланом или определением дополнительного типа, несущего параметры в виде полей с правильными значениями по умолчанию, как предложено Джоном Скитом. Борис Павлови & # 263; добавляет, что его тип может быть внутренним статическим классом, чтобы аккуратно хранить вещи в нужном месте.

Минусы (обратите внимание, что весь этот вопрос не о каких-либо серьезных последствиях, а об удобных настройках):

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

Специальный тип, содержащий параметры, кажется наиболее полезным, если результирующий тип может иметь другое использование, а не просто передаваться одному конкретному методу, или когда это более сложный набор параметров. Если есть 2-4 параметра, а некоторые могут иметь значения по умолчанию, перегрузку все же немного удобнее, но это может быть вопросом личного вкуса.

Другие советы

Другой вариант - это вариант шаблона компоновщика - у вас есть тип, который представляет все параметры, создаете экземпляр этого типа (который по умолчанию устанавливается соответственно), задаете нужные свойства и затем передаете результат в исходный метод. или добавьте метод в поле «тип параметра» чтобы вызвать метод для вас.

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

см. varargs

http : //www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html

(обновленный URL; этот комментарий добавлен, потому что для стекопотока требуется > 30 символов)

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

protected void process(
    Processor processor,
    String item,
    @Default("Processor.Size.LARGE") Size size,
    @Default("red") String color,
    @Default("1") int quantity) {
        ...
}

который генерирует (в сгенерированном суперклассе)

protected void process(sample.Processor processor, java.lang.String item)  {
    process(processor, item, Processor.Size.LARGE, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size)  {
    process(processor, item, size, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size, 
                       java.lang.String color)  {
    process(processor, item, size, color, 1);
}
protected abstract void process(sample.Processor processor, 
                                java.lang.String item, 
                                sample.Processor.Size size, 
                                java.lang.String color, 
                                int quantity) ;

См. http://code.google.com/p/javadude/wiki/. Аннотации - Скотт

Может быть очень трудно попытаться перевести ваш процесс хотя бы из одного языка в другой. Вы можете, как уже отмечали другие, сделать некоторые обходные пути, чтобы, возможно, получить то, что вы хотите ... но чем раньше вы "примете" способ, которым Java разработана, чтобы работать лучше, вы будете работать в Java.

Я должен был сделать кое-что из PHP ... досадно меня раздражало, что я не мог заставить его делать то, что хотел ... так что все идет в обе стороны.

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

В первые дни C ++ люди пытались убедить C ++ вести себя как Smalltalk ... не получалось слишком хорошо. В первые дни, когда люди Java пытались взять свои знания C ++ и использовать их в Java ... не получалось слишком хорошо (что вдвойне расстраивает, так как языки очень похожи на поверхности).

Мой совет: научитесь программировать на Java, а не на PHP.

Для вашей непосредственной проблемы, возможно ли, что вы действительно перенастраиваете разные классы из фабрики вместо того, чтобы создавать объект такого же типа с установленными разными переменными?

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

В OO вместо передачи состояния через методы / процедуры состояние уже находится в вызываемом объекте или объектах, которые вы передаете в качестве параметров. Большую часть времени вам нужно не более 1 или 2 параметров в ваших методах.

Если вы хотите сконфигурировать свой объект перед его использованием, вы должны создать его с помощью простого конструктора, а затем вызывать разные установщики. Это делает код намного более читабельным (потому что вы видите имена сеттеров) по сравнению с вызовом конструктора, имеющего много аргументов. А в случае, если новый атрибут появится позже, вы можете добавить его в свой объект без необходимости изменять существующие фабричные методы.

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

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) { }

Но используя varargs

public class DefaultValue
{
 public static void main(String[] args)
  {
       defaultParameter();
       defaultParameter(true);
  }

  public static void defaultParameter(Boolean …gender)
  {
       boolean genderBoolean = false; // It is the default value you want to give
       if(1 == gender.length)
       {
            genderBoolean = gender[0]; // Overrided Value
      }
       System.out.println(genderBoolean);
 }
}

Вывод приведенного выше кода будет

false
true

Для получения более похожих примеров и объяснений посетите значения параметров Java по умолчанию

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top