Zusammenfassung der Implementierung von Standardargumenten in Java

Java hat keine ** Standardargumentfunktion **, daher habe ich eine alternative Implementierung zusammengefasst.

TL;DR Ich denke, dass es kein Problem gibt, wenn es mit der folgenden Richtlinie implementiert wird.

Anzahl der Argumente, die Sie als Standard festlegen möchten Lösungen
~ 4 Überlast
5 ~ Builder-Muster

Was ist das Standardargument?

Das Standardargument in diesem Artikel ist, wenn der Wert beim Aufrufen der Methode nicht als tatsächliches Argument festgelegt wird. Stattdessen handelt es sich um einen Mechanismus zum Initialisieren mit dem Standardwert. (Ich denke, es ist eine Syntax, die hauptsächlich in modernen Sprachen eingeführt wird.)

Unten finden Sie ein Beispiel für die in Groovy geschriebenen Standardargumente.

def foo(a = 0, b = "undefined") {
    println "a = $a, b = $b"
}

foo(23, "hoge")  // => a = 23, b = hoge
foo()            // => a = 0, b = undefined

Implementierung in Java

1. Überladung | Wenn die Anzahl der Standardargumente gering ist

Sie können es einfach mit dem Muster implementieren, das Sie am häufigsten sehen.

    static void foo(int a, String b) {
        System.out.println("a = " + a + ", b = " + b);
    }

    static void foo(int a) { foo(a, "undefined"); } //Nur Argument b ist das Standardargument
    static void foo(String b) { foo(0, b); }        //Nur Argument a ist das Standardargument
    static void foo() { foo(0, "undefined"); }      //Argument a,Beide b sind Standardargumente

    public static void main(String[] args) {
        foo(23, "hoge");    // => a = 23, b = hoge
        foo(23);            // => a = 23, b = undefined
        foo("hoge");        // => a = 0, b = hoge
        foo();              // => a = 0, b = undefined
    }

Im Beispiel sind die in foo (int a, String b) deklarierten Argumente unterschiedliche Typen Durch Überladen können Sie Standardwerte für alle Argumente festlegen. Wenn die Argumente a und b vom gleichen Typ sind, ist es nicht möglich, "Standardargument nur für Argument a" und "Standardargument nur für Argument b" gleichzeitig zu deklarieren. In diesem Fall bleibt keine andere Wahl, als es mit dem später beschriebenen Builder-Muster oder durch Übergeben von Null zu implementieren.

(Ergänzung) Argument variabler Länge | Wenn das formale Argument des Array-Typs nicht angegeben ist, wird der Standardwert des leeren Arrays eingegeben.

Der Teil, der zu einem Argument variabler Länge wird, hat die Einschränkung, dass es das letzte der Methodenargumente ist. Wenn im letzten Argument nichts angegeben ist, wird automatisch ein leeres Array (Länge = 0) übergeben. In solchen Fällen besteht daher keine Notwendigkeit zur Überlastung.

    static void foo(String a, int... b) {
        int bSum = IntStream.of(b).sum();

        System.out.println("a = " + a + ", sum = " + bSum);
    }

    public static void main(String[] args) {
        foo("hoge", 23, 42);  // => a = hoge, sum = 65
        foo("hoge");          // => a = hoge, sum = 0
    }

2. Builder-Muster | Kann auf vielfältige Weise verwendet werden. Das Problem beim Erstellen einer Klasse ist jedoch ...

Zusätzlich zur Überladung gibt es ein häufig verwendetes Muster, das das Builder-Muster verwendet, um Standardargumente festzulegen. Überladen ist nett, weil Sie den Standardwert leicht festlegen können, aber wenn die Anzahl der Argumente groß wird Der Code ist leichter zu lesen, wenn Sie ihn durch das Builder-Muster ersetzen. Gemäß der SonarQube-Regel ist es wünschenswert, dass die Anzahl der Argumente 4 oder weniger als Schwellenwert beträgt. Java: Methods should not have too many parameters | SonarQube - Rules

Im Beispiel wird geschrieben, um den Standardwert im Builder-Muster für die Methode mit zwei Argumenten festzulegen.

import lombok.Builder;
import lombok.Value;

public class BuilderPattern {
    
    static void foo(Foo foo) {
        System.out.println("foo = " + foo);
    }
    
    public static void main(String[] args) {
        var specifiedFoo = Foo.builder().a(23).b("hoge").build();
        var defaultFoo = Foo.builder().build();
        foo(specifiedFoo);  // => foo = Foo(a=23, b=hoge)
        foo(defaultFoo);    // => foo = Foo(a=0, b=undefined)
    }
}

@Value
@Builder
class Foo {
    @Builder.Default
    Integer a = 0;
    @Builder.Default
    String b = "undefined";
}

(Ergänzung) Kartentyp | Wenn Sie dies tun, verwenden Sie bitte Builder

Sie können dasselbe mit dem Builder-Muster mit Map tun, aber wenn Sie dies tun möchten, ist es meiner Meinung nach besser, es mit Builder zu schreiben.

    static void foo(Map<Foo, Object> params) {
        var a = (int) params.getOrDefault(Foo.A, 0);
        var b = (String) params.getOrDefault(Foo.B, "undefined");
        System.out.println("a = " + a + ", b = " + b);
    }

    public static void main(String[] args) {
        foo(Map.of(Foo.A, 23, Foo.B, "hoge"));  // => a = 23, b = hoge
        foo(Map.of());                          // => a = 0, b = undefined
    }

    enum Foo {
        A, B
    }

3. Übergeben Sie Null | Wenn das Argument zum Festlegen des Standardwerts nur das erste oder das zweite ist

Wie ich in der Erklärung der Überladung geschrieben habe, wenn die deklarierten Argumente vom gleichen Typ sind, In einigen Fällen war es nicht möglich, für jedes Argument einen Standardwert festzulegen. Die Problemumgehung besteht darin, einen Standardwert innerhalb der Methode festzulegen. Es ist jedoch nicht möglich, allein anhand der Methodensignatur zu bestimmen, welche Variable den Standardwert hat. Methodenbenutzer müssen sich Javadoc oder die Implementierung der Methode ansehen, ein Muster, das sie nicht viel verwenden möchten.

    static void foo(String a, Integer b, Integer c) {
        b = Objects.requireNonNullElse(b, 0);
        c = Objects.requireNonNullElse(c, 0);
        System.out.println("a = " + a + ", b = " + b + ", c = " + c);
    }

    public static void main(String[] args) {
        foo("hoge", 23, 42);      // => a = hoge, b = 23, c = 42
        foo("hoge", null, null);  // => a = hoge, b = 0, c = 0
    }

(Ergänzung) Optionaler Typ | Nr. Zettai.

Als Problem mit dem oben erwähnten Null-Passing-Muster "Es ist nicht möglich, allein anhand der Methodensignatur zu bestimmen, welche Variable den Standardwert hat." Es ist leicht zu fragen: "Nun, vielleicht kann der optionale Typ verwendet werden?", Aber dies scheint ziemlich kritisiert zu sein. Da der optionale Typ ein Mechanismus ist, der dem Aufrufer mitteilt, dass der ursprünglich von der Methode zurückgegebene Wert null sein kann. Wenn Sie den optionalen Typ für das Argument verwenden, wird der Code redundanter und die Anzahl der bedeutungslosen Codes nimmt zu. Daher ist der folgende Schreibstil strengstens untersagt.

    static void foo(String a, Optional<Integer> bOpt) {
        var b = bOpt.orElse(0);
        System.out.println("a = " + a + ", b = " + b);
    }

    public static void main(String[] args) {
        foo("hoge", Optional.of(23));    // => a = hoge, b = 23
        foo("hoge", Optional.empty());   // => a = hoge, b = 0
        foo("hoge", null);               // => NullPointerException
    }

Verweise

Java optional parameters | Stack Overflow Java: Methods should not have too many parameters | SonarQube - Rules Why should Java 8's Optional not be used in arguments | Stack Overflow

Recommended Posts

Zusammenfassung der Implementierung von Standardargumenten in Java
So implementieren Sie die Datumsberechnung in Java
[java] Zusammenfassung des Umgangs mit char
Zusammenfassung zum Schreiben von Anmerkungsargumenten
So erzwingen Sie Codierungskonventionen in Java
[Java] [Maven3] Zusammenfassung der Verwendung von Maven3
Zusammenfassung der Auswahl von Elementen in Selen
[java] Zusammenfassung des Umgangs mit Zeichenketten
[Java] Zusammenfassung, wie Lambda-Ausdrücke weggelassen werden
[Java] So implementieren Sie Multithreading
Zusammenfassung der Java-Kommunikations-API (1) Verwendung von Socket
Zusammenfassung der Java-Kommunikations-API (3) Verwendung von SocketChannel
Zusammenfassung der Java-Kommunikations-API (2) Verwendung von HttpUrlConnection
Wie man JAVA in 7 Tagen lernt
Wie verwende ich Klassen in Java?
So benennen Sie Variablen in Java
Versuchen Sie, Yuma in Java zu implementieren
So verketten Sie Zeichenfolgen mit Java
So implementieren Sie eine einzeilige Anzeige von TextView in der Android-Entwicklung
So leiten Sie den letzten Tag des Monats in Java ab
Zusammenfassung der Verwendung des im IE festgelegten Proxy-Sets bei der Verbindung mit Java
So erstellen Sie eine Java-Kalenderzusammenfassung
So implementieren Sie Suchfunktionen in Rails
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Versuchen Sie, n-ary Addition in Java zu implementieren
[Webpacker] Zusammenfassung der Installation von Bootstrap und jQuery in Rails 6.0
So implementieren Sie einen Job, der die Java-API in JobScheduler verwendet
So führen Sie eine Basiskonvertierung in Java durch
Einbetten von Janus Graph in Java
So erhalten Sie das Datum mit Java
So implementieren Sie Ranking-Funktionen in Rails
So implementieren Sie die asynchrone Verarbeitung in Outsystems
So ermitteln Sie die Länge einer Audiodatei mit Java
So erhöhen Sie den Wert von Map in einer Zeile in Java
[Java] Übergeben Sie Argumente an den Konstruktor in Mockito / Set default call to method an callRealMethod
So ermitteln Sie die Gesamtzahl der Seiten beim Paging in Java
So zeigen Sie eine Webseite in Java an
So erhalten Sie eine Klasse von Element in Java
So verbergen Sie Nullfelder als Antwort in Java
So implementieren Sie eine ähnliche Funktion in Rails
Verwendung von JQuery in Rails 6 js.erb
So implementieren Sie optimistisches Sperren in der REST-API
So lösen Sie Ausdrucksprobleme in Java
Wie schreibe ich Java String # getBytes in Kotlin?
So implementieren Sie Paginierung in GraphQL (für Ruby)
Zusammenfassung der Java-Unterstützung 2018
Gedanke: Wie man eine funktionale Schnittstelle für eigene Funktionen verwendet (Java)
[Java] So erhalten Sie die URL der Übergangsquelle
So implementieren Sie UICollectionView mit Code nur in Swift
Aufrufen von Funktionen in großen Mengen mit Java Reflection
So erstellen Sie eine Java-Umgebung in nur 3 Sekunden
[Java] So lassen Sie den privaten Konstruktor in Lombok weg
So implementieren Sie die Gastanmeldung in 5 Minuten im Rails-Portfolio
So implementieren Sie eine nette Funktion in Ajax mit Rails
Ich habe versucht, die Firebase-Push-Benachrichtigung in Java zu implementieren
Wie schreibe ich Scala aus der Perspektive von Java
[Java] Arten von Kommentaren und wie man sie schreibt