2016-07-24 4 views
1

Betrachten Sie das folgende Verfahren Konten:in einem Verfahren Return null, die für mehrere Bedingungen

private static String method (String string) { 
    if (string.equals("conditionOne")) { 
     return value; 
    } else if (string.equals("conditionTwo")) { 
     return symbol; 
    } else { 
     return null; 
    } 
} 

Lasst uns sagen, dass ich für zwei Bedingungen bin Überprüfung, conditionOne und conditionTwo. Nehmen Sie außerdem an, dass ein anderer Teil des Programms sicherstellt, dass nur diese beiden Fälle jemals vorkommen. Da die Methode für alle Fälle etwas zurückgeben muss, um einen Compilerfehler zu vermeiden, ist es in Ordnung, null für den letzten else-Block nur für syntaktische Zwecke zurückzugeben, da dieser Teil niemals ausgeführt wird?

bearbeitet: Aus Gründen der Klarheit, würde ich erwähnen, dass der Compiler mir einen Fehler gibt („Erwartung return-Anweisung“), wenn ich nicht enthalten, dass letzten else Block. Anders als das Zurückgeben von null (oder eine leere Zeichenkette, wie von Anthony unten gezeigt) gibt es eine andere Möglichkeit, diese Methode zu schreiben, so dass dies nicht passiert?

Dank

+0

Die Leute, die Lampenfieber entwickelten, dachten dasselbe. Wer würde mehr Bilddaten als die Größe des Bildes weitergeben? Ihr Code wird nicht zu einem großen Exploit führen, aber zu einer (möglicherweise) schlechten Benutzererfahrung, wenn der Code abstürzt –

Antwort

1

Sie beschreiben ein sehr häufiges Szenario beim Programmieren. Sie beabsichtigen für eine bestimmte Sache, nie zu passieren, aber der Compiler weiß es auch könnte passieren. Der richtige Weg, um solche Codepfade zu handhaben, besteht darin, sicherzustellen, dass sie niemals erreicht werden, im Allgemeinen durch Werfen eines AssertionError oder RuntimeException wie IllegalArgumentException, IllegalStateException oder UnsupportedOperationException. Dies wird als failing-fast bezeichnet.

In Ihrem Fall würde ich eine IllegalArgumentException werfen, da das klar ist, was passiert ist - Ihre Methode erwartet genau zwei Eingaben; alles andere ist verboten und du solltest in solchen Fällen scheitern. Effektives Java Item 38 diskutiert das auch.

Jetzt können Sie sicher sein, dass die einzigen Eingaben, die diese Funktion unterstützt, diejenigen sind, die sie unterstützen sollen.Noch besser, jeder, der Ihre Methode falsch aufruft, erhält eine klare, umsetzbare Fehlermeldung.

Das Guava Benutzerhandbuch hat eine gute overview of different kinds of failures und wenn Sie sie erhöhen sollten.

Sie könnten dieses Problem auch auf andere Weise vermeiden - indem Sie eine bessere Methodensignatur definieren. Es sieht so aus, als ob Sie eine "stringly-typed" API definieren; Die Verwendung einer Enumeration würde dazu beitragen, zu verhindern, dass Anrufer fehlerhafte Parameter weitergeben. Siehe auch Effective Java Artikel 50 und 30.


In seltenen Fällen (in der Regel, wenn sie direkt mit Benutzereingabe zu tun) Sie wollen nicht weich und nicht ausfall schnell. Dies ist gemeinsam mit confirmation dialogs; Wenn Sie den Benutzer bitten, "Ja" oder "Nein" einzugeben, ist es in der Regel ausreichend, einfach zu prüfen, ob sie "Ja" eingegeben haben - ob sie "Nein" oder "Uhhhh" eingegeben haben, Sie behandeln es einfach als "Ja". .

+0

Könnten Sie die geworfene Ausnahme auch in einen 'else' Block setzen? –

+0

Sie könnten, aber es gibt keine Notwendigkeit, da die anderen alle "Rückkehr" blockiert, so dass der "else" -Block überflüssig ist. – dimo414

+0

Obwohl Sie vielleicht wissen, dass diese Ausnahme niemals ausgelöst werden kann, ist es im Allgemeinen sicherer, sie aus den oben genannten Gründen einzuschließen, oder? –

1

Wie Sie die Funktion als Zurückgeben eines String definiert haben, wäre es richtiger sein

if (string.equals("conditionOne")) { 
    return value; 
} else if (string.equals("conditionTwo")) { 
    return symbol; 
} else { 
    return ""; 
} 
+0

ah, okay, das macht Sinn. Danke! –

+0

Dies entlastet nur das Problem - ja Sie vermeiden 'NullPointerException', aber jetzt muss Ihr gesamter Code überprüfen, dass das Ergebnis nicht leer ist. Dieses Muster führt zu schwer zu wartendem Code, mit dem man schwer arbeiten und vernünftig umgehen kann. – dimo414

0

zu haben, wenn Sie bereits, dass die Zeichenfolge garantiert haben, werden immer gleich entweder conditionOne oder conditionTwo , dann Schreiben der 3. else Bedingung ist nicht notwendig.

Es entspricht dem Hinzufügen von Code, der nicht prüft, ob es conditionOne oder conditionTwo ist. Es ist besser, es zu entfernen.

Bearbeiten Wenn Sie Ihre Bearbeitung sehen, würde ich die obige Lösung der Rückgabe "" empfehlen, da es eine Zeichenfolge ist.

+0

Bitte beachten Sie die ** Bearbeiten ** in meinem Beitrag –

+0

@AisforAmbition Danke, ich habe meine Antwort bearbeitet. –

1

Sie können so etwas schreiben:

if (string.equals("conditionOne")) { 
    return value; 
} else if (string.equals("conditionTwo")) { 
    return symbol; 
} 
return ""; 

oder so:

string rval = ""; 
if (string.equals("conditionOne")) { 
    rval = value; 
} else if (string.equals("conditionTwo")) { 
    rval = symbol; 
} 
return rval; 

oder ähnliche

if (string.equals("conditionOne")) { 
    return value; 
} else if (string.equals("conditionTwo")) { 
    return symbol; 
} 
throw; 

bearbeitet.

+0

Ich mag dieses Format wirklich, es ist konsistenter –