2016-04-08 5 views
0

Betrachten Sie die folgende Siutation. Ein Benutzer kann etwas eingeben wie 30D, 90D, 180D, 360D, 1M, 3M, 6M, 12M, 1Y (D = Tag, M = Monat, Y = Jahr).Ist es ratsam, Java Call-by-Wert zu "verwerten"

Ich möchte die Anzahl der Monate mit den folgenden beiden Methoden berechnen.

private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) { 
     int periodInMonths = lengthOfPeriod; 
     if ("D".equals(unitOfPeriod)) { 
      periodInMonths = lengthOfPeriod/30; 
     } else if ("Y".equals(unitOfPeriod)) { 
      periodInMonths = lengthOfPeriod * 12; 
     } 
     return periodInMonths; 
    } 

    private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) { 
     if ("D".equals(unitOfPeriod)) { 
      lengthOfPeriod = lengthOfPeriod/30; 
     } else if ("Y".equals(unitOfPeriod)) { 
      lengthOfPeriod = lengthOfPeriod * 12; 
     } 
     return lengthOfPeriod; 
    } 

Da Java mit Call-by-Wert arbeitet mit einer Referenz als Wert übergeben lengthOfPeriod wird nicht außerhalb des Verfahrens ändern. Ich bin mir nicht sicher, was besser geeignet ist.

Ich weiß, dass diese Methode mit einem Enum Periods oder etwas ähnlichem refaktoriert werden könnte. Aber lass uns das hier nicht diskutieren.

+0

könnten Sie erklären, was soll hier geschehen? – SomeJavaGuy

+0

Tun Sie, was Ihren Code klarer macht. Mir geht es beiden gut. – khelwood

+0

Ich denke, dass es ein allgemeines Problem geben könnte: Ein Programmierer könnte lengthOfPeriod (durch Setter) in der zweiten Methode ändern, die den Code außerhalb dieser Methode ändern könnte. – Chris311

Antwort

3

Das Zuweisen von Methodenparametern ist keine gute Idee (und sie sollten IMHO standardmäßig final sein). Wenn Sie die zusätzliche Variable wirklich vermeiden möchten (nicht, dass es wirklich einen Unterschied macht), können Sie in if-Klauseln Rückgaben einfügen.

Verwenden Sie jedoch keine Parameter als "automatische lokale Variablen". Dies kann zu schwer erkennbaren Fehlern führen und macht Ihren Code nicht leistungsfähiger.

+0

Ich mag diese Antwort. Können Sie ein Beispiel angeben, in dem ein Fehler auftritt? Meinst du den Fall, wenn Setter-Aufrufe für die übergebene Referenz verwendet werden? – Chris311

+0

@ Chris311 * "Könnten Sie ein Beispiel angeben, in dem ein Fehler erzeugt wird?" * Zum Beispiel 'public void setBlub (String blub) {blub = blub;}' wobei der Programmierer den Parameter sich selbst zuweist, anstatt den Feld. Oder wenn der Programmierer denkt, dass die Neuzuweisung des Parameters an die aufrufende Methode wie folgt erinnert: 'String blub; setBlub (blub); .... öffentlicher void setBlub (String blub) {blub = "default"; } '. Mit dem Parameter "final" vermeiden Sie dieses Problem. – Tom

+1

@ Chris311 Nun, nicht speziell, aber natürlich ist das auch ein potentielles Problem. Die meisten Methoden * werden den Parametern nicht zugewiesen, sodass Sie leichter übersehen können, ob Sie Änderungen an einer Methode vornehmen. Es ist konsistenter, wenn Sie die Parameter wie ursprünglich haben, und lokale Variablen, wenn die Parameter in irgendeiner Weise vorverarbeitet werden müssen. – Kayaman

0

Der einzige Unterschied ist, dass Sie eine eigene Variable int periodInMonths = lengthOfPeriod; in der ersten Methode verwenden. Aber das ist nicht notwendig!

Sie können die zweite verwenden .. Es tut was es soll!

int lengthOfPeriodInMonths = getLengthOfPeriodInMonths(lengthOfPeriod, unitOfPeriod); 

und Sie haben die berechnete int außerhalb des gespeicherten Verfahrens in lengthOfPeriodInMonths

PS: Dieser Aufruf

lengthOfPeriod = lengthOfPeriod/30; 

entspricht

lengthOfPeriod = new Integer(lengthOfPeriod/30); 

(look „auto- Boxen "in Java).

Also, wie Sie gesagt haben, Java verwendet Call-Bay-Wert. Die Variable lengthOfPeriod erhält in diesem Aufruf einen neuen Verweis. Diese Berechnung wäre also außerhalb der Methode verloren gegangen! Deshalb müssen Sie den neu berechneten Wert zurückgeben!

+0

Das ist genau das, was ich bereits weiß, aber ist es klug, auf die Verwendung einer lokalen Variablen zu verzichten? – Chris311

+0

Ja, weil die Ausführung Ihres Programms ein kleines bisschen schneller ist und es Ihren Arbeitsspeicher etc. erspart;) UND: Warum etwas hinzufügen, das nicht benötigt wird ?! – mrbela

+1

@mrbela Es hat keinen Einfluss auf die Leistung. Es ist die sogenannte * Mikro-Optimierung *, bei der man sich auf Dinge konzentriert, die eigentlich keine Rolle spielen, aber möglicherweise schlechten Code schreiben. Die Code-Klarheit bei weitem überwiegt das "Speichern" einer lokalen Variablen. Es ist besser, sich auf die Dinge zu konzentrieren, die wirklich wichtig sind, als zu denken: "Soll ich 1 Variable oder 2 verwenden?". – Kayaman

0

Erster Hinweis: Ändern Sie niemals die Methodenparameter. Sie sollten den Wert widerspiegeln, den der Benutzer der Methode zu jeder Zeit hat. Der zweite Ratschlag: Wenn jemand Ihnen rät, nie etwas zu tun, besonders wenn er oder sie den Ausdruck "niemals" verwendet, nehmen Sie seinen Rat mit einem Körnchen Salz. Es gibt keine Regeln ohne Ausnahmen (niemals ;-). Solche Regeln sind große Faustregeln, aber verwenden Sie immer Ihr eigenes Urteil. Wähle die Lösung, von der du denkst, dass sie klarer ist. Ich kenne einige Situationen, in denen ich fand, dass das Ändern von Methodenparametern besser lesbar war als die Alternative.

Zum Beispiel möchten Sie vielleicht manchmal zulassen, dass der Benutzer der Methode null an die Methode übergeben, aber dann durch einen Standardwert ersetzen.Ich finde die folgende Methode

public void doSomething(String s) { 
    if (s == null) s = ""; 
    System.out.println(s); 
} 

viel klarer als eine lokale Variable Einführung nur den Standardwert sind:

public void doSomething(final String s) { 
    String sOrEmpty = s == null ? "" : s; 
    System.out.println(sOrEmpty); 
} 
Verwandte Themen