Чи підтримує Java параметри за замовчуванням?


1661

Я натрапив на якийсь код 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 такий синтаксис? Чи є якісь причини, чому цей синтаксис з двома кроками є кращим?


85
Ні. Однак модель Builder може допомогти.
Дейв Джарвіс

50
Мені дуже не вистачає цієї функції. Це дуже допомагає при зміні існуючого коду, щоб отримати додатковий параметр функції або конструктора
Jatin

4
@Jatin За допомогою рефакторингу Eclipse "Змінити підпис методу" ви можете додати параметр та вказати значення за замовчуванням, яке використовуватимуть існуючі вхідні клієнти.
Ервін Болвідт

2
@ErwinBolwidt Дякую Я використовую Android Studio, і він також має можливість рефакторингу методу та надання значень за замовчуванням. Досить корисно.
Ятін

3
@temporary_user_name public MyParameterizedFunction(String param1, int param2)- це конструктор, а не метод, декларація.
Маріо Ішак

Відповіді:


955

Ні, структура, яку ви знайшли, - це те, як Java обробляє її (тобто з перевантаженням замість параметрів за замовчуванням).

Для конструкторів див. Підказку пункту 1 « Ефективна Java: Посібник з мови програмування» (Розгляньте статичні заводські методи замість конструкторів), якщо перевантаження ускладнюється. Для інших методів перейменування деяких випадків або використання об'єкта параметра може допомогти. Це коли ви маєте достатню складність, що диференціювати важко. Певний випадок, коли вам доведеться розмежовувати, використовуючи порядок параметрів, а не лише число та тип.



135
@JarrodRoberson: Статичні заводські методи не є більш шкідливими, ніж new. Вони використовуються всі час в новому коді. Будівельники об'єктів простого значення часто є результатом надмірної інженерії.
Лій

12
@JarrodRoberson: Цікавий спосіб примусити правильне використання через компілятор, дякую за обмін! Дружня пропозиція щодо майбутніх публікацій: 300 рядків коментованого вихідного коду, мабуть, засвоюються для більшості людей (код читати важче, ніж написати). Знову дякую!
Крістіан Айхінгер

17
@JarrodRoberson: Приємно, з нетерпінням чекаю! Що я хотів спілкуватися: як читач вашого блогу, приклад із 50 рядків з коротким текстовим описом того, що відбувається, допоможе мені більше 300 рядків без контексту.
Крістіан Айхінгер

8
@ user177800 Не погоджуюсь - статичні методи, якщо записані як чисті функції, цілком добре. Це коли статична функція мутує, вони стають проблемою ...
Леві Фуллер

641

Ні, але ви можете використовувати шаблон Builder , як описано у цій відповіді на переповнення стека .

Як описано в пов'язаній відповіді, Шаблон Builder дозволяє писати подібний код

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

у яких деякі поля можуть мати значення за замовчуванням або інакше бути необов’язковими.


141
Нарешті, чудовий приклад шаблону Builder менш ніж на 2 сторінки.
неввермінд

14
Мені цікаво, чому нам потрібен клас будівельника при використанні моделі будівельника. Я думав про Student s1 = new Student (). Name ("Spicolo"). Вік (16) .motto ("Aloha, Mr. Hand);
ivanceras

52
@ivanceras: Це актуально, коли для класів є обов'язкові поля, і ви не хочете мати можливість інстанціювати ці класи в недійсному стані. Тож якщо ви просто сказали Student s1 = new Student().age(16);тоді, це залишить вас зі студентом без імені, що може бути погано. Якщо це непогано, то ваше рішення чудово.
Eli Courtwright

57
@ivanceras: ще одна причина полягає в тому, що ви можете хотіти, щоб ваш клас був непорушним після побудови, тому ви не хочете, щоб у ньому були методи, що змінюють його значення.
Жуль

3
@ivanceras: я використовував Builders для 3-х речей - усунення безлічі аргументів та ініціалізації безперешкодної роботи, незмінності та найголовніше, що я відчуваю, щоб перевірити об'єкт домену методом build (). Навіщо створити об'єкт об'єкта, якщо він недійсний. Ви також можете перевантажити статичну заводські методи, як у наведеному вище випадку buildFreshman (), buildSenior () тощо
Abhijeet Kushe

485

Існує кілька способів моделювання параметрів за замовчуванням на Java:

  1. Метод перевантаження.

    void foo(String a, Integer b) {
        //...
    }
    
    void foo(String a) {
        foo(a, 0); // here, 0 is a default value for b
    }
    
    foo("a", 2);
    foo("a");

    Одне з обмежень цього підходу полягає в тому, що він не працює, якщо у вас є два необов’язкові параметри одного типу і будь-який з них можна опустити.

  2. Вараги.

    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");

    Основний недолік такого підходу полягає в тому, що якщо необов'язкові параметри різного типу, ви втрачаєте статичну перевірку типу. Крім того, якщо кожен параметр має різний зміст, вам потрібен певний спосіб їх розрізнити.

  3. Нулі. Для усунення обмежень попередніх підходів можна дозволити нульові значення та потім проаналізувати кожен параметр у тілі методу:

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

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

  4. Необов’язковий клас. Цей підхід схожий на нулі, але використовує клас 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());

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

  5. Шаблон будівельника. Схема конструктора використовується для конструкторів і реалізується шляхом введення окремого класу 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();
  6. Карти. Коли кількість параметрів занадто велика і для більшості з них зазвичай використовуються значення за замовчуванням, ви можете передати аргументи методу як карту їх імен / значень:

    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 = (String)parameters.get("a");
        } else if (parameters.containsKey("b")) { 
            //... 
        }
        //...
    }
    
    foo(ImmutableMap.<String, Object>of(
        "a", "a",
        "b", 2, 
        "d", "value")); 

Зверніть увагу, що ви можете комбінувати будь-який із цих підходів для досягнення бажаного результату.


1
Гарне пояснення. Я ніколи не бачив таких повернених значень. Для 5) що return thisробити? Крім того, чи не FooBuilder().setA("a").build();оскільки (за визначенням) конструктор викликається першим і FooBuilder()повертає значення, чи це не означає, .setA("a"):що не отримує шанс викликати?
Celeritas

3
@Celeritas return thisповертає той самий об’єкт, щодо якого був викликаний метод (у прикладі FooBuilder). Це дозволяє ланцюжок методів в одному операторі, що діє на один і той же об'єкт: new FooBuilder().setA(..).setB(..).setC(..)і т.д.
ADTC

2
@Celeritas new FooBuilder()повертає FooBuilderоб'єкт, для якого setAвикликається метод. Як setBне називається, this.bзберігає значення за замовчуванням. Нарешті buildметод викликається на цьому FooBuilderоб'єкті. buildМетод створює і повертає Fooоб'єкт , який встановлюється в змінну Foo foo. Зауважте, що FooBuilderоб'єкт не зберігається в жодній змінній.
ADTC

Анотація також може використовуватися для створення параметрів за замовчуванням і є найбільш корисною, коли це потрібно для поліморфних колекцій. docs.oracle.com/javase/tutorial/java/annotations/declaring.html
Martin

1
Понад 900 заявок на одну і ту ж відповідь на два запитання. Я вражений: stackoverflow.com/questions/965690/java-optional-parameters / ...
AdamMc331

256

На жаль, ні.


34
Це так сумно? Це може ввести потенційно неоднозначні підписи функцій.
Трей

69
@Trey: мови з параметрами за замовчуванням часто перевантажують функцію канави, оскільки вони менш вагомі. Тож ніякої двозначності. Крім того, Scala додав цю функцію в 2.8 і якось вирішив питання про неоднозначність (оскільки вони зберігали перевантаження з міркувань сумісності).
PhiLho

32
Я не бачу, як параметри за замовчуванням параметрів запобігають перевантаженню функції. Наприклад, C # дозволяє відміняти, а також дозволяє ініціалізувати за замовчуванням. Схоже, довільний вибір, а не обмеження є причиною.
FlavorScape

51
Так, давайте змусити компілятор зробити додаткову роботу і замість цього змусити всіх нас написати 100000 перевантажень, щоб надати користувачам бібліотеки зручність. Гарна ідея.

28
@ user562566: Щоразу, коли я працюю над проектом Java, у мене виникає враження, що Java-розробники оплачуються / вимірюються кількістю рядків коду, які вони виробляють за день
Марк К Коуан

83

На жаль, так.

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

можна писати на Java 1.5 так:

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

Але від того, чи варто вам, залежати від того, як ви ставитесь до компілятора, що генерує

new Boolean[]{}

для кожного дзвінка.

Для кількох параметрів, які не підлягають замовчуванню:

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 <= 2;
    assert l < 1 || Boolean.class.isInstance(p[0]);
    assert l < 2 || Integer.class.isInstance(p[1]);
    bool param3 = l > 0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue() : 42;
}

Це відповідає синтаксису C ++, який дозволяє лише параметри за замовчуванням у кінці списку параметрів.

Крім синтаксису, є різниця, коли це запустило перевірку типу часу на пройдені параметри, що не підлягають замовчуванню, і тип C ++ перевіряє їх під час компіляції.


14
Розумні, але varargs (...) можна використовувати лише для кінцевого параметра, який є більш обмежуючим, ніж ті мови, які підтримують параметри за замовчуванням.
CurtainDog

6
це розумно, але трохи безладно порівняно з версією C ++
Хтось десь

5
Яві потрібні необов'язкові параметри за замовчуванням, як це дозволяє C # та інші ... синтаксис очевидний, і я припускаю, що вони можуть реалізувати це досить просто, навіть просто склавши всі можливі комбінації ... Я не уявляю, чому вони не додали його до мови ще!
рив

10
Ніколи не слід використовувати assertкоди виробництва. Киньте виняток.
Майкл Дорст

5
-1 Це дійсно не те, для чого вараги. Це злом. - у цьому випадку використання перевантажень стане читабельнішим (що прикро, оскільки три зайві символи читабельніше, ніж 5 зайвих рядків джерела ...). - але Java не підтримує параметри за замовчуванням.
BrainSlugs83

38

Ні, але ви можете дуже легко імітувати їх. Що в 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);
}

Раніше зазначалося, що параметри за замовчуванням викликали неоднозначні випадки перевантаження функцій. Це просто неправда, ми можемо побачити у випадку з C ++: так, можливо, це може створити неоднозначні випадки, але з цією проблемою можна легко впоратися. Він просто не був розроблений на Java, мабуть тому, що творці хотіли набагато простішої мови, як це було C ++ - якщо вони мали рацію, це інше питання. Але більшість з нас не думає, що він використовує Java через її простоту.


8
Основна ідея позначення значень за замовчуванням C # полягає саме в тому, щоб уникнути кодування цього котла та мати лише один конструктор замість багатьох.
Коля Іванков

1
@KolyaIvankov Я не знаю C #, але я знаю C ++, де міркування такі самі. Я не знаю, що кращого, але я думаю, що насправді той самий код котла виробляється компілятором у випадку C ++ / C #, і він переходить до остаточного двійкового.
петерх

5
Кожна мова програмування є (зокрема) засобом уникнути котельної панелі Assembler, я помиляюся? Питання лише в тому, чи дає він зручну функціональність, чи ні.
Коля Іванков

2
Перше речення - риторичне запитання. Слово "питання" у другому реченні не має нічого спільного з риторичним питанням у першому.
Коля Іванків

1
Більш конкретні: мови - це інструменти, які дозволяють нам писати програми таким чином, щоб ми могли мати контроль над написаним, компіляція - це спосіб сказати машині, що ми хочемо від неї. Інструмент є більш корисним, якщо він дозволяє нам уникати котельних плит. Насправді, gnavi запитав, чи можуть вони уникати саме того типу кодової панелі, який ви пропонуєте як відповідь, оскільки C # дозволяє це.
Коля Іванков

24

Зробити це можна в Scala, який працює на JVM і сумісний з програмами Java. http://www.scala-lang.org/

тобто

class Foo(var prime: Boolean = false, val rib: String)  {}

58
Принести цілком нову мову, щоб отримати одну не настільки загальну особливість?
om-nom-nom

8
@ om-nom-nom: Java ніколи не існувала. Якщо сказати, що функція не використовується, це рівнозначно, що нікому не потрібна, це говорить, що Java не була популярною до того, як вона була винайдена, означає, що Gosling не повинен починати її розробляти.
Val

28
@Val просто сказав, що це як зйомка птахів гарматами
om-nom-nom

8
це не має нічого спільного з питанням ОП
дестан

Працює і в Котліні. І Groovy. І C #. І Javascript. І майже всі інші мови, створені для справжніх людей та проблем.
шпигун

17

Ні , але найпростіший спосіб здійснити це :

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

або замість потрійного оператора ви можете використовувати if:

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

2
Так, такий підхід здається найкращим з інших альтернатив. Але все-таки було б добре для Java прийняти значення за замовчуванням; Котлін показав, що це можна зробити, тому я не впевнений, чому Oracle не входить у сучасну епоху, і продовжує розробляти java так, ніби це були 1990-ті. : D
shevy

13

Я можу зазначити очевидне тут, але чому б просто не просто реалізувати параметр "за замовчуванням" самостійно?

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);

11
Плакат запитав, чи можна уникнути цього (досить потворного) шаблону ... ;-) У сучасних мовах (наприклад, c #, Scala) вам не потрібні додаткові перевантаження, які створюють лише більше рядків коду. До певного моменту ви можете тим часом використовувати varargs (static int max (int ... array) {}), але вони є лише дуже потворним вирішенням.
Розпродаж

2
Перевантаження не є негарною і має багато переваг, наприклад, різні дзвінки методів з різними підписами можуть виконувати різні функції. //This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } } //Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }
Ентоні Бут

Добре, якщо хочеться різної поведінки. Якщо єдиною різницею є незначна зміна розрахунків тощо, це безперечно витратити зусилля на створення декількох підписів. Значення за замовчуванням має сенс там, де вони вам потрібні ... і його відсутність не слід класифікувати як "марну" вимогу.
Капіль

Параметри за замовчуванням @Offler не мають нічого спільного з "сучасною мовою". Я використовував їх у Delphi 20 років тому, і вони, ймовірно, вже існували в Turbo Pascal.
Неймовірний січень

Я погоджуюся з Оффлером і не погоджуюся з Ентоні Бутом. Я вважаю це не лише потворним, але й досить неефективним. Такі мови, як рубін або пітон, дозволяють використовувати параметри за замовчуванням тривіально; Я здогадуюсь, що Java вимагає від вас - це знайти (і використовувати) обхідні шляхи. Явна перевірка проти нуля здається найменш негарним вибором, оскільки я можу зателефонувати і в командному рядку (просто нічого не надавати, а потім обробити здоровий варіант); підхід перевантаження оператора здається ... дуже багатослівним (як мінімум +3 рядки, порівняно з нульовою перевіркою, і більше рядків, якщо код складніший).
shevy

8

Як згадувався Скала, Котлін також варто згадати. У функціях Kotlin параметри можуть мати також значення за замовчуванням, і вони навіть можуть посилатися на інші параметри:

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

Як і Scala, Котлін працює на JVM і може бути легко інтегрований у існуючі проекти Java.


6

Ні.

Ви можете домогтися такої ж поведінки, передавши Об'єкт, який має інтелектуальні параметри. Але знову ж таки, залежить, яка у вас справа.


5

Ні. Загалом, у Java мало синтаксичного цукру, оскільки вони намагалися скласти просту мову.


26
Не зовсім. Гірка правда полягає в тому, що команда була за жорстким графіком і не мала часу на синтаксичний цукор. Чому б інакше constі gotoбули зарезервовані ключові слова, які не реалізуються? - Тим більше const, що я гірко сумую - finalце не заміни, і вони це знали. - І якщо ви прийняли чітке рішення ніколи не впроваджувати, gotoвам не потрібно буде резервувати ключове слово. - І пізніше в команді Java обдурили, зробивши Label заснованим breakі continueтаким же потужним, як Pascal goto.
Мартін

"Простий, об'єктно-орієнтований та знайомий" справді був метою дизайну - дивіться oracle.com/technetwork/java/intro-141325.html
mikera

1
tomjen сказав: "Ні. Взагалі, у Java мало синтаксичного цукру, оскільки вони намагалися скласти просту мову". Отже, ви говорите, що видалення багатьох непотрібних функцій з C ++ робить Java простою мовою, то скажіть мені, чому у Java є різні методи? Чому у нього є вараги? Це не потрібно, якщо ви можете просто використовувати масив об'єктів замість цього, я правий? Тож вараги можна видалити з мови, бо це зайве. Це зробить Java простішою, ніж зараз. Чи правий я? Перевантаження також можна зняти, оскільки у вас є нескінченні назви для кожного методу.

1
і тому ми отримали весну та інше, що сприймає просту мову та перетворює будь-який справжній проект Java на скупчення синтаксису та
котла

Примушування розробників до кодового коду та складних способів вирішення не є моїм розумінням слова "легко". myFunction (a, b = false, c = 3), це я називаю легким.
шпигун

5

Замість використання:

void parameterizedMethod(String param1, int param2) {
    this(param1, param2, false);
}

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

Ви можете використовувати додаткову функціональність Java, використовуючи єдиний метод:

void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
    param3 = Optional.ofNullable(param3).orElse(false);
    //use all three parameters here
}

Основна відмінність полягає в тому, що вам потрібно використовувати класи обгортки замість примітивних типів Java, щоб дозволити nullвведення. Booleanзамість boolean, Integerзамість intтощо.


4

Він не підтримується, але є кілька варіантів, як використання шаблону об'єкта параметра з деяким синтаксичним цукром:

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за замовчуванням значення та переосмислюємо їх у розділі ініціалізації екземплярів класу{ param1 = 10; param2 = "bar";}


3

Спробуйте це рішення:

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

    return score;
}

3

Ви можете використовувати Java Method Invocation Builder, щоб автоматично генерувати конструктор із значеннями за замовчуванням.

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

@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);

2

Аналогічний підхід до 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; }
        });
    }
}

2

Зараз я витратив досить багато часу, щоб розібратися, як це використовувати з методами, що повертають значення, і я досі не бачив прикладів, я вважав, що це може бути корисно додати тут:

int foo(int a) {
    // do something with a
    return a;
}

int foo() {
    return foo(0); // here, 0 is a default value for a
}

1

Ось як я це зробив ... це не так зручно, як те, що мати "необов'язковий аргумент" проти вашого визначеного параметра, але це робить роботу:

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 на true замінить весь текст у моєму TextArea наданим рядком. Якщо встановити wipeClean на помилкове або залишити його разом, просто додає наданий текст до TextArea.

Також зауважте, що я не повторюю код у двох методах, я просто додаю функціональність можливості скидання TextArea, створивши новий метод з тим же ім'ям лише з доданим булевим.

Насправді я думаю, що це дещо чіткіше, ніж якби Java подала «необов’язковий аргумент» для наших параметрів, оскільки нам потрібно було б потім кодувати значення за замовчуванням тощо. У цьому прикладі мені не потрібно турбуватися ні про що з цього. Так, я додав ще один метод до свого класу, але його легше читати з часом, на мою скромну думку.


1

НІ, Але у нас є альтернатива у вигляді перевантаження функцій.

викликається, коли жоден параметр не пройшов

void operation(){

int a = 0;
int b = 0;

} 

викликається при передачі параметра "a"

void operation(int a){

int b = 0;
//code

} 

викликається, коли параметр b переданий

void operation(int a , int b){
//code
} 

1

Існує півдесятка або кращих питань, таких як ця, врешті-решт, ви доходите до статичної заводської схеми ... дивіться криптовалютний API для цього. Сортувати важко для пояснення, але подумайте про це так: Якщо у вас є конструктор, за замовчуванням або іншим способом, єдиний спосіб розповсюдження стану поза фігурними дужками - або мати булевий isValid; (разом з null як значення за замовчуванням v невдалий конструктор) або викинути виняток, який ніколи не є інформативним при поверненні його назад від користувачів польових користувачів.

Код Правильно проклятий, я пишу тисячі конструкторів ліній і роблю все, що мені потрібно. Я вважаю, що використовується isValid при побудові об'єктів - іншими словами, дворядкові конструктори - але я чомусь переходжу до статичної заводської структури. Мені здається, ви можете зробити багато, якщо у виклику методу все ще виникають проблеми синхронізації (), але за замовчуванням можна краще "замінити" (безпечніше)

Я думаю, що нам тут потрібно зробити - це вирішити питання про null як значення за замовчуванням щодо щось String one = new String (""); як змінну члена, потім роблять перевірку на null перед призначенням рядка, переданого конструктору.

Дуже примітна кількість сировини, стратосферної інформатики, зробленої на Яві.

C ++ і так далі має ліцензії постачальників, так. Java може випередити їх на великомасштабних серверах завдяки масивній панелі інструментів. Вивчіть статичні блоки ініціалізатора, залишайтеся з нами.



0

Ви можете використовувати наступні-

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.