2016-07-06 12 views
4

Ich bin oft mit dieser Frage konfrontiert. Lassen Sie uns ein kurzes Beispiel sehen, ich habe diese einfache Methode: Es ruft die Position eines String in einem String[].Java: Richtiger Weg eine Methode() sollte einen schlechten Ruf behandeln

public int getStringPosition(String s, String[] text) { 
    for (int i = 0; i < text.length; i++) { 
     if (text[i].equals(s)) { 
      return i; 
     } 
    } 
    return text.length; 
} 

Aber was ist, wenn der String nicht im Array ist? Hier wird die Größe des Arrays zurückgegeben (eine int, die nicht von einer normalen Verwendung der Methode stammen könnte). Es könnte auch -1 zurückgeben. Ich wünschte, es würde null zurückgeben, aber das scheint nicht möglich zu sein.

Wie auch immer, diese Methode wird in der gleichen Klasse von einigen anderen Methoden verwendet. Meine Frage ist ziemlich allgemein, , wie man die Fälle behandelt, in denen du nicht zurückbringen kannst, was erwartet wird?

+9

Throw Exceptions ... – Hackerdarshi

+0

Und was sollte die Ausnahme tun? Wie warne ich den Benutzer der Methode und lasse ihn weiterhin den Fluss seines Programms fortsetzen? – Fitz

+1

Trotz dessen, was @Hackerdarshi gesagt hat, die andere Möglichkeit, wie die 'String'-Methoden zum Beispiel funktionieren, könnte auch' -1' zurückgeben, wie zum Beispiel 'String # indexOf', wenn Sie primitive Typen zurückgeben. – SomeJavaGuy

Antwort

5

Wenn die Unfähigkeit, die Zeichenfolge stellt einen Fehler, ein Ausnahmezustand, dann sollten Sie einige Ausnahme an den Aufrufer werfen zu finden. Z. B.

throw new RuntimeException("String not found"); 

Wenn die Unfähigkeit, die Zeichenfolge zu finden, ist eine normale Situation, dass der Anrufer in dem normalen Ablauf des Codes behandeln will, dann sollten Sie einen speziellen Rückgabewert verwenden. Für diese Art der Suchmethode kann kein normaler Rückgabewert negativ sein, und die Konvention lautet -1, wie String.indexOf und List.indexOf. Wenn Sie diese Konvention folgen könnten Sie eigentlich Ihre Methode Körper mit einer einzigen Zeile implementieren:

return java.util.Arrays.asList(text).indexOf(s); 

Hinweis: Diese Änderung null ein wenig anders behandelt. Es gibt drei Dinge, die in Ihrer Methode null sein können: die Suchzeichenfolge, das Array und die Elemente des Arrays.Ihr aktueller Code löst eine NullPointerException aus, wenn ein Nullarray übergeben wird oder wenn er auf ein Nullelement trifft, ignoriert jedoch automatisch eine Nullsuchzeichenfolge. Durch das Zurückstellen auf List.indexOf dürfen alle Array-Elemente auch null sein, um nach einem Nullwert innerhalb des Arrays zu suchen. Es ist wahrscheinlich ein harmloser Unterschied, aber eine gut durchdachte Methode berücksichtigt solche Fragen. Beispielsweise möchten Sie möglicherweise eine leere Suchzeichenfolge als ungültige Eingabe behandeln und in diesem Fall sofort eine Ausnahme auslösen.

Eine vollständig dokumentierte öffentliche Methode würde auch den Fall mehrerer übereinstimmender Elemente innerhalb des Arrays berücksichtigen: Soll der Index mit dem niedrigsten Übereinstimmungsgrad oder ein passender Index zurückgegeben werden? Wenn ein Index akzeptabel ist, muss er den gleichen Index für wiederholte Aufrufe mit denselben Argumenten liefern? (Eine hypothetische Multithread-Suche könnte die "offensichtliche" Annahme der Rückgabe des niedrigsten Index leicht überwinden, da nicht vorhergesagt werden kann, welcher CPU-Kern zuerst eine Übereinstimmung findet.)

Bedenken Sie auch, dass die Methode deklariert werden könnte.

1

Sie können null nicht zurückgeben, weil Sie einen primitype-Typ zurückgeben. Return Ganzzahl statt und Null wird erlaubt.

Trotzdem habe ich mit dem Kommentator oben zustimmen, die Ausnahme der richtige Weg ist dies

+0

Ich mag die Rückkehr Integer Idee. Ziel ist es, den Benutzer sein Programm fortsetzen zu lassen. Viele Methoden von Apache POI, die ich gerade verwende, geben oft 'null' zurück, wenn ich nach etwas frage, während es bereitgestellt werden kann. So kann ich weiter Code schreiben, indem ich vorher den Null-Fall teste. – Fitz

+2

Aber das kann zu NullPointerException führen, und schließlich müssten Sie Ausnahmen behandeln ... – Hackerdarshi

+0

der Benutzer kann die Ausnahme erfassen, protokollieren oder einen Standardwert zuweisen (oder was immer er benötigt) und das Programm fortsetzen. – SCouto

5

Probleme zu behandeln Wenn der Fall, dass die s nicht in text ist keine gültige Art und Weise ist die Methode aufzurufen, sollten Sie werfen eine Ausnahme, z IllegalParameterException.

Wenn es jedoch in Ordnung ist, die Methode auf diese Weise aufzurufen, sollten Sie keine Ausnahme auslösen, da dies eine gültige erwartete Verwendung ist. In diesem Fall könnten Sie z.B. zurückgeben -1.

Aber -1 ist in diesem Fall eine "magische Zahl", die Art von schlechte Praxis ist so sollten Sie eine Konstante dafür erklären.

private static final int STRING_NOT_IN_TEXT=-1; 

/** 
* @return first position of 's' in 'text' 
*   and if 's' is not in 'text' returns NOT_IN_TEXT 
*/ 
public static int getStringPosition(final String s, final String[] text) { 
    for (int i = 0; i < text.length; i++) { 
     if (text[i].equals(s)) { 
      return i; 
     } 
    } 
    return STRING_NOT_IN_TEXT; 
} 

Ps.s. Sie können auch überprüfen, ob die textnull ist und diesen Fall behandeln, außer einfach das System NullPointerReference werfen lassen.

+1

Ich mag das auch. Ich dachte daran, '-1' zurückzugeben und das scheint noch besser zu sein. – Fitz

4

Es ist beliebig. Einige Entwickler werfen Ausnahmen, andere geben einige spezielle Werte wie -1 zurück. Am wichtigsten ist es, genau zu definieren, was Ihre Methode in jedem Fall tut, damit Leute, die Ihren Code verwenden, wissen, woran sie arbeiten.

+0

Ok, also gibt es keine Allgemeinheit. Viele Methoden von Apache POI, die ich momentan verwende, geben oft null zurück, wenn ich nach etwas frage, während es bereitgestellt werden kann. So kann ich weiter Code schreiben, indem ich vorher den Null-Fall teste. Danke für die Antwort. – Fitz

+1

Vorsicht, das Testen von null funktioniert nur mit nicht-primitiven Typen wie String, ArrayList usw. (primitive Typen sind Dinge wie int, double, float usw.) – Ephi

1

Es ist ein gutes patern, um null zurückzugeben, wenn nichts gefunden wurde. Sie können Integer anstelle von int verwenden. Die Integer Klasse umschließt einen Wert des primitiven Typs int in einem Objekt. Ein Objekt vom Typ Integer enthält ein einzelnes Feld, dessen Typ int ist. Das ist, warum können Sie null zurück, wenn Sie es wie

public Integer getStringPosition(String s, String[] text) 
2

machen Es sind zwei Dinge, die mir in den Sinn kommen:

a) es ist sehr viel gilt für Methoden, die einen „Index“ zurück, die in Punkte jede Art von Sequenz zu -1 zurück, um anzuzeigen, „keine Übereinstimmung gefunden“

b) es kann auch gültig sein, um nur einige Laufzeit-Exception zu werfen, wie Illegal

Wenn man über Option „b)“ denken sie etwas Zeiten helfen, zwei Methoden zu haben, wie ein findIndex() vs. getIndex(); und per Konvention würden "Find" -Methoden immer eine Ausnahme auslösen; während der andere null/-1 oder einen anderen Wert zurückgibt. Aber natürlich ist das dann etwas, das Sie für Ihr Projekt/Ihr Team/Ihre Person lokal definieren. Mit anderen Worten: Alle Leute, die sich mit Ihrem Code beschäftigen, müssen verstehen, dass das Aufrufen von findXyz() eine Ausnahme auslösen könnte; und dass es andere Methoden gibt, die nicht werfen.

Und als eine Randnotiz sollten Sie immer versuchen, mit "Standardlösungen" übereinzustimmen. Was ich meine ist; übernehmen Sie den Code würde Sammlungen werden:

int getIndex(String stringToSearch, List<String> stringsToSearch) { 
    return stringsToSearch.indexOf(stringToSearch); 

Ratet mal, was diese zurück ... und sich nun fragen, ob Sie Ihre Array-basierte Lösung wünschen würde die gleiche Sache wie die Java Standard Sammlungen zu tun ...

(letzte Randbemerkung: ja, meine Variablennamen sind furchtbar lang, aber ich denke immer noch, dass ein langer Name besser ist als "s" ... da der spätere nichts über den beabsichtigten Gebrauch von ihnen sagt Parameter).

2

Befolgen Sie gängige und bekannte Kodierungskonventionen: Ihre Methode sieht so aus: String.indexOf (String) geben Sie einfach -1 zurück, wenn die Eingabe nicht gefunden wird. Ausnahmen sollten "außergewöhnlich" sein und keine Zeichenfolge in einem Array finden, die es nicht ist.

Wenn Sie etwas mehr OO Sie und NotFound Gefunden von den Klassen implementiert etwas wie

Result search(T something,Set<T> someSet); 

mit der Schnittstelle Ergebnis umsetzen können unterschiedlich behandelt werden; im Allgemeinen, obwohl diese Lösung ein Overkill aussieht.

+0

Ich verstehe etwas "allgemeiner". Aber was bedeutet OO * genau *? :) – Fitz

+1

Objektorientiert;) – aros

1

Sie könnten die Vorschläge hier verwenden, aber:

  • ‚-1‘ ist ein „Zauberwert“ und wird oft als anti-Muster angesehen
  • Ausnahmen für eine Nicht-Ausnahmesituation zu werfen ist auch als ein Anti-Muster (und einige werden sagen, werfen keine Nicht-System-Ausnahme ist ein Anti-Muster)
  • Verwenden Sie Integer als Rückgabetyp und geben Sie einen null Wert zurück. Jedoch null wird auch als Anti-Muster (google „null die Milliarden-Dollar-Fehler“)

gesehen Wenn Sie nichts dagegen haben die oben dann voran gehen und eine der Optionen verwenden (alle häufig durch eine verwendet werden

viele Programmierer)

Sie auch einen Optional/Vielleicht/Option Typ

public Optional<Integer> getStringPosition(String s, String[] text) { 
    for (int i = 0; i < text.length; i++) { 
     if (text[i].equals(s)) { 
      Optional.of(i); 
     } 
    } 
    return Optional.empty(); 
} 

Optional in Java verfügbar ist nutzen könnten 8. Wenn Sie eine ältere Version verwenden, können Sie eine der vielen verfügbaren Implementierungen verwenden (z. B. https://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Optional.html)