Ich bin auf Java-Code gestoßen, der folgende Struktur hatte:
public MyParameterizedFunction(String param1, int param2)
{
this(param1, param2, false);
}
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
//use all three parameters here
}
Ich weiß, dass ich in C ++ einem Parameter einen Standardwert zuweisen kann. Zum Beispiel:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
Unterstützt Java diese Art von Syntax? Gibt es Gründe, warum diese zweistufige Syntax vorzuziehen ist?
public MyParameterizedFunction(String param1, int param2)
ist eine Konstruktor- und keine Methodendeklaration.Antworten:
Nein, die Struktur, die Sie gefunden haben, ist die, wie Java damit umgeht (dh mit Überladung anstelle von Standardparametern).
Informationen zu Konstruktoren finden Sie unter Tipp 1 zu Effective Java: Programmiersprachenhandbuch (Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren), wenn die Überladung kompliziert wird. Bei anderen Methoden kann es hilfreich sein, einige Fälle umzubenennen oder ein Parameterobjekt zu verwenden. Dies ist der Fall, wenn Sie so komplex sind, dass eine Unterscheidung schwierig ist. In einem bestimmten Fall müssen Sie anhand der Reihenfolge der Parameter unterscheiden, nicht nur anhand der Anzahl und des Typs.
quelle
static
alles wird im Jahr 2015 als ziemlich schädlich angesehen. Typensichere fließendeBuilder
Instanzen, die vollständige und gültige Bauaufträge durchsetzen, sind jetzt eine viel bessere Lösung.new
. Sie werden verwendet , die ganze Zeit in neuem Code. Builder für einfache Wertobjekte sind häufig das Ergebnis von Überentwicklung.Nein, aber Sie können das Builder-Muster verwenden , wie in dieser Antwort zum Stapelüberlauf beschrieben .
Wie in der verknüpften Antwort beschrieben, können Sie mit dem Builder-Muster Code wie schreiben
in denen einige Felder Standardwerte haben können oder auf andere Weise optional sind.
quelle
Student s1 = new Student().age(16);
, haben Sie einen Studenten ohne Namen, was möglicherweise schlecht ist. Wenn es nicht schlecht ist, ist Ihre Lösung in Ordnung.Es gibt verschiedene Möglichkeiten, Standardparameter in Java zu simulieren:
Methodenüberladung.
Eine der Einschränkungen dieses Ansatzes besteht darin, dass er nicht funktioniert, wenn Sie zwei optionale Parameter desselben Typs haben und jeder von ihnen weggelassen werden kann.
Varargs.
a) Alle optionalen Parameter sind vom gleichen Typ:
b) Die Arten der optionalen Parameter können unterschiedlich sein:
Der Hauptnachteil dieses Ansatzes besteht darin, dass bei statischen Parametern unterschiedlicher Typen die statische Typprüfung verloren geht. Wenn jeder Parameter eine andere Bedeutung hat, müssen Sie ihn auf irgendeine Weise unterscheiden.
Nullen. Um die Einschränkungen der vorherigen Ansätze zu beseitigen, können Sie Nullwerte zulassen und dann jeden Parameter in einem Methodenkörper analysieren:
Jetzt müssen alle Argumentwerte angegeben werden, die Standardwerte können jedoch null sein.
Optionale Klasse. Dieser Ansatz ähnelt Nullen, verwendet jedoch die optionale Klasse Java 8 für Parameter mit einem Standardwert:
Optional wird ein Methodenvertrag für einen Anrufer explizit festgelegt. Eine solche Signatur ist jedoch möglicherweise zu ausführlich.
Builder-Muster. Das Builder-Muster wird für Konstruktoren verwendet und durch Einführung einer separaten Builder-Klasse implementiert:
Karten. Wenn die Anzahl der Parameter zu groß ist und für die meisten von ihnen normalerweise Standardwerte verwendet werden, können Sie Methodenargumente als Zuordnung ihrer Namen / Werte übergeben:
Bitte beachten Sie, dass Sie jeden dieser Ansätze kombinieren können, um ein wünschenswertes Ergebnis zu erzielen.
quelle
return this
? Auch,FooBuilder().setA("a").build();
weil (per Definition) der Konstruktor zuerst aufgerufen wird undFooBuilder()
einen Wert zurückgibt, bedeutet dies nicht,.setA("a"):
dass er nicht die Chance bekommt, aufgerufen zu werden?return this
gibt dasselbe Objekt zurück, für das die Methode aufgerufen wurde (im BeispielFooBuilder
). Dies ermöglicht die Verkettung von Methoden in einer Anweisung, die auf dasselbe Objekt wirkt:new FooBuilder().setA(..).setB(..).setC(..)
usw., anstatt jede Methode in einer separaten Anweisung aufzurufen.new FooBuilder()
gibt einFooBuilder
Objekt zurück, für das diesetA
Methode aufgerufen wird. WiesetB
nicht aufgerufen,this.b
behält der Standardwert bei. Schließlich wird diebuild
Methode für diesesFooBuilder
Objekt aufgerufen . Diebuild
Methode erstellt einFoo
Objekt und gibt es zurück, das auf die Variable festgelegt istFoo foo
. Beachten Sie, dass dasFooBuilder
Objekt in keiner Variablen gespeichert ist.Traurigerweise Nein.
quelle
Leider ja.
könnte in Java 1.5 geschrieben werden als:
Aber ob Sie davon abhängen sollten, wie Sie sich fühlen, wenn der Compiler a generiert
für jeden Anruf.
Für mehrere voreingestellte Parameter:
könnte in Java 1.5 geschrieben werden als:
Dies entspricht der C ++ - Syntax, die nur Standardparameter am Ende der Parameterliste zulässt.
Über die Syntax hinaus gibt es einen Unterschied, bei dem die Laufzeit-Typprüfung auf übergebene Standardparameter erfolgt und der C ++ - Typ diese beim Kompilieren überprüft.
quelle
assert
Produktionscode verwenden. Eine Ausnahme auslösen.Nein, aber Sie können sie sehr einfach emulieren. Was in C ++ war:
In Java wird es eine überladene Funktion sein:
Zuvor wurde erwähnt, dass Standardparameter mehrdeutige Fälle bei der Funktionsüberladung verursachten. Das ist einfach nicht wahr, wir können im Fall von C ++ sehen: Ja, vielleicht kann es mehrdeutige Fälle erzeugen, aber dieses Problem kann leicht behandelt werden. Es wurde einfach nicht in Java entwickelt, wahrscheinlich weil die Entwickler eine viel einfachere Sprache wollten als C ++ - wenn sie Recht hatten, ist eine andere Frage. Aber die meisten von uns glauben nicht, dass er Java wegen seiner Einfachheit verwendet.
quelle
Sie können dies in Scala tun, das auf der JVM ausgeführt wird und mit Java-Programmen kompatibel ist. http://www.scala-lang.org/
dh
quelle
Nein , aber der einfachste Weg, dies umzusetzen, ist:
oder anstelle des ternären Operators können Sie Folgendes verwenden
if
:quelle
Ich könnte hier das Offensichtliche sagen, aber warum nicht einfach den "Standard" -Parameter selbst implementieren?
Für die Standardeinstellung würden Sie entweder verwenden
und wenn Sie die Standardeinstellung nicht verwenden möchten, würden Sie verwenden
quelle
//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 } } }
Wie Scala erwähnt wurde, ist auch Kotlin erwähnenswert. In Kotlin können Funktionsparameter auch Standardwerte haben und sich sogar auf andere Parameter beziehen:
Kotlin läuft wie Scala auf der JVM und kann problemlos in bestehende Java-Projekte integriert werden.
quelle
Nein.
Sie können dasselbe Verhalten erzielen, indem Sie ein Objekt mit intelligenten Standardeinstellungen übergeben. Aber auch hier kommt es darauf an, was Ihr Fall ist.
quelle
Nein. Im Allgemeinen hat Java nicht viel (irgendeinen) syntaktischen Zucker, da sie versucht haben, eine einfache Sprache zu erstellen.
quelle
const
undgoto
reserviert Schlüsselwörter, die keine Implementierung? - Besondersconst
etwas vermisse ich bitter -final
ist kein Ersatz und sie wussten es. - Und wenn Sie die bewusste Entscheidung getroffen haben, niemals zu implementieren, müssengoto
Sie das Schlüsselwort nicht reservieren. - Und später im Java-Team betrogen, indem es das Label basiertbreak
undcontinue
so mächtig wie ein Pascal machtegoto
.Anstatt zu verwenden:
Sie können die optionale Funktionalität von Java mit einer einzigen Methode nutzen:
Der Hauptunterschied besteht darin, dass Sie Wrapper-Klassen anstelle von primitiven Java-Typen verwenden müssen, um
null
Eingaben zu ermöglichen .Boolean
stattboolean
,Integer
stattint
und so weiter.quelle
Es wird nicht unterstützt, aber es gibt verschiedene Optionen wie die Verwendung von Parameterobjektmustern mit etwas Syntaxzucker:
In diesem Beispiel konstruieren wir
ParameterObject
mit Standardwerten und überschreiben diese im Abschnitt zur Initialisierung der Klasseninstanz{ param1 = 10; param2 = "bar";}
quelle
Versuchen Sie diese Lösung:
quelle
Sie können den Java Method Invocation Builder verwenden , um den Builder automatisch mit Standardwerten zu generieren.
Fügen Sie einfach @GenerateMethodInvocationBuilder zur Klasse oder Schnittstelle und @Default zu Parametern in Methoden hinzu, in denen Sie Standardwerte wünschen. Zur Kompilierungszeit wird ein Builder mit den Standardwerten generiert, die Sie in Ihren Anmerkungen angegeben haben.
Und dann können Sie die Methoden aufrufen.
Oder setzen Sie einen der Standardwerte auf einen anderen Wert.
quelle
Ein ähnlicher Ansatz für https://stackoverflow.com/a/13864910/2323964 , der in Java 8 funktioniert, ist die Verwendung einer Schnittstelle mit Standard-Gettern. Dies ist ein ausführlicheres Leerzeichen, ist jedoch verspottbar und eignet sich hervorragend, wenn Sie eine Reihe von Fällen haben, in denen Sie tatsächlich auf die Parameter aufmerksam machen möchten.
quelle
Ich habe jetzt einige Zeit damit verbracht, herauszufinden, wie dies mit Methoden verwendet werden kann, die Werte zurückgeben, und ich habe bisher keine Beispiele gesehen. Ich dachte, es könnte nützlich sein, dies hier hinzuzufügen:
quelle
So habe ich es gemacht ... es ist vielleicht nicht so praktisch wie ein 'optionales Argument' gegen Ihren definierten Parameter, aber es erledigt den Job:
Beachten Sie, dass ich denselben Methodennamen entweder nur mit einer Zeichenfolge oder mit einer Zeichenfolge und einem booleschen Wert aufrufen kann. In diesem Fall wird durch Setzen von wipeClean auf true der gesamte Text in meiner TextArea durch die angegebene Zeichenfolge ersetzt. Wenn Sie wipeClean auf false setzen oder alles zusammen weglassen, wird der bereitgestellte Text einfach an die TextArea angehängt.
Beachten Sie auch, dass ich den Code in den beiden Methoden nicht wiederhole. Ich füge lediglich die Funktionalität hinzu, die TextArea zurücksetzen zu können, indem eine neue Methode mit demselben Namen nur mit dem hinzugefügten Booleschen Wert erstellt wird.
Ich denke tatsächlich, dass dies ein wenig sauberer ist, als wenn Java ein 'optionales Argument' für unsere Parameter bereitstellen würde, da wir dann für Standardwerte usw. codieren müssten. In diesem Beispiel muss ich mir darüber keine Gedanken machen. Ja, ich habe meiner Klasse noch eine weitere Methode hinzugefügt, aber meiner bescheidenen Meinung nach ist es auf lange Sicht einfacher zu lesen.
quelle
NEIN, aber wir haben eine Alternative in Form von Funktionsüberladung.
Wird aufgerufen, wenn kein Parameter übergeben wurde
Wird aufgerufen, wenn der Parameter "a" übergeben wurde
wird aufgerufen, wenn Parameter b übergeben wurde
quelle
Es gibt ein halbes Dutzend oder bessere Probleme wie dieses. Schließlich gelangen Sie zum statischen Factory-Muster. Siehe dazu die Krypto-API. Sortieren Sie schwer zu erklären, aber denken Sie so: Wenn Sie einen Konstruktor haben, standardmäßig oder auf andere Weise, besteht die einzige Möglichkeit, den Status über die geschweiften Klammern hinaus zu verbreiten, darin, entweder einen Booleschen Wert zu haben. (zusammen mit der Null als Standardwert v fehlgeschlagener Konstruktor) oder lösen Sie eine Ausnahme aus, die niemals informativ ist, wenn Sie sie von Feldbenutzern zurückerhalten.
Code Richtig, verdammt, ich schreibe tausend Zeilenkonstruktoren und mache, was ich brauche. Ich finde die Verwendung von isValid bei der Objektkonstruktion - mit anderen Worten, zweizeilige Konstruktoren -, aber aus irgendeinem Grund migriere ich zum statischen Factory-Muster. Ich scheine nur, dass Sie viel tun können, wenn Sie in einem Methodenaufruf immer noch Probleme mit sync () haben, aber die Standardeinstellungen können besser (sicherer) "ersetzt" werden.
Ich denke, wir müssen hier das Problem von null als Standardwert gegenüber etwas behandeln. String one = new String (""); Als Mitgliedsvariable wird dann auf Null geprüft, bevor dem Konstruktor übergebene Zeichenfolge zugewiesen wird.
Sehr bemerkenswert ist die Menge an roher, stratosphärischer Informatik, die in Java durchgeführt wird.
C ++ und so weiter hat Vendor Libs, ja. Java kann sie auf großen Servern überholen, da es sich um eine riesige Toolbox handelt. Studieren Sie statische Initialisierungsblöcke, bleiben Sie bei uns.
quelle
Es wird in Java nicht unterstützt, wie beispielsweise in anderen Sprachen. Kotlin.
quelle
Sie können Folgendes verwenden:
quelle