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 |
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
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.
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
}
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";
}
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
}
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
}
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
}
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