Frage

Nach der Buchung diese Frage und Lesen von , dass man erkennen ich, dass es sehr wichtig ist zu wissen, ob ein Verfahren sollte null zurückzukehren, oder ob dies einen Fehler betrachtet und eine Ausnahme geworfen werden sollte. Es gibt auch eine nette Diskussion, wenn href="https://stackoverflow.com/questions/175532/return-null-or-throw-exception"> return ‚null‘ oder throw Ausnahme

Ich bin ein Verfahren zu schreiben, und ich weiß schon, ob ich null zurückkehren will oder eine Ausnahme auslösen, was der beste Weg ist meine Entscheidung zum Ausdruck bringt, mit anderen Worten, meinen Vertrag zu dokumentieren?

Einige Möglichkeiten, die ich mir vorstellen kann:

  • Schreiben Sie es in den Spezifikationen / der Dokumentation nach unten (es wird jemand lesen?)
  • Machen Sie es Teil des Methodennamen (wie ich vorgeschlagen hier )
  • davon ausgehen, dass jede Methode, dass wirft Eine Ausnahme wird nicht return null, und jeder, der 'nicht' throw tut Macht return null.

Ich spreche hauptsächlich über Java, aber es könnte auf andere Sprachen gelten auch: Warum gibt es eine formale Art und Weise zum Ausdruck bringen, wenn Ausnahmen (der throws keywords), aber kein formaler Weg geworfen werden zum Ausdruck bringen, wenn null zurückgeführt werden könnte ?

Warum gibt es nicht so etwas wie folgt aus:

public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}

Zusammenfassung und Schlussfolgerungen

Es gibt viele Möglichkeiten, den Vertrag zu äußern:

  • Wenn Ihre IDE unterstützen (wie IntelliJ), es ist am besten, eine Anmerkung wie @NotNull zu verwenden, da es für den Programmierer sichtbar und kann für die automatisierte Kompilierung Überprüfung verwendet werden. Es gibt eine Plugin für Eclipse Unterstützung für diese hinzuzufügen, aber es hat nicht Arbeit für mich.
  • Falls dies nicht eine Option, verwenden, um benutzerdefinierte Typen wie Option<T> oder NotNull<T>, die Klarheit hinzufügen und mindestens Laufzeitprüfung.
  • Auf jeden Fall in der JavaDoc den Vertrag zu dokumentieren hilft schadet nie und manchmal sogar.
  • Methodennamen Verwendung des NULL-Zulässigkeit des Rückgabewertes zu dokumentieren, von niemandem vorgeschlagen wurde, aber mich, und obwohl es sehr ausführlich und vielleicht nicht immer nützlich, ich glaube immer noch, manchmal ist es seine Vorteile hat, zu.
War es hilfreich?

Lösung

Eine sehr gute Follow-up-Frage. Ich halte einen ganz besonderen Wert null, und wenn eine Methode null zurückkehren muss dokumentieren eindeutig im Javadoc, wenn es funktioniert (@return some value ..., or null if ...). Bei der Codierung Ich bin defensiv, und davon ausgehen, ein Verfahren null zurückkehren kann, wenn ich es kann davon überzeugt bin nicht (zum Beispiel, weil die Javadoc gesagt.)

realisierten Menschen, dass dies ein Problem ist, und eine vorgeschlagene Lösung ist Anmerkungen zu verwenden, um die Absicht, in eine Art und Weise zu erklären, es automatisch überprüft werden kann. Siehe JSR 305: Anmerkungen für Software Defect Detection JSR 308: Anmerkungen auf Java-Typen und JetBrain des Nullable How-To .

Ihr Beispiel könnte wie folgt aussehen, und von der IDE, die Compiler oder anderen Code-Analyse-Tools abgelehnt.

@NotNull
public Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}

Andere Tipps

Sie können den Option Typen , die sehr viel wie eine Liste, die null oder ein Element aufweist. Ein Rückgabetyp Option<Object> zeigt an, dass das Verfahren eine Object zurückkehren kann, oder sie kann einen speziellen Wert vom Typ None zurückzukehren. Dieser Typ ist ein Ersatz für die Verwendung von null mit einem besseren Art überprüft.

Beispiel:

public Option<Integer> parseInt(String s) {
   try {
      return Option.some(Integer.parseInt(s));
   }
   catch (Exception e) {
      return Option.none();
   }
}

Wenn Sie diese konsequent nutzen, Sie auf IDE null-Warnungen drehen, oder einfach nur grep für null verwenden, die nicht in Ihrem Code angezeigt werden soll, wenn Sie Option.none() verwenden überall Sie normaly ein null wörtlichen verwenden würde.

Option kommt mit Scala Standard, und es Maybe in Haskell genannt wird. Der Link oben ist auf eine Bibliothek mit dem Namen Functional Java , die es enthält. Diese Version implementiert die Iterable-Schnittstelle und hat monadischen Methoden, die Sie Dinge gut zusammensetzen lassen. Um zum Beispiel einen Standardwert von 0 bei None bieten:

int x = optionalInt.orSome(0);

Und Sie können diese ersetzen ...

if (myString != null && !"".equals(myString))

... mit diesem, wenn Sie eine Option<String> haben ...

for (String s : myOptionString)

Tatsächlich: in unserem Rahmen haben wir einen ‚Nicht-Null‘ Zeigertyp, der, dass das Verfahren, um anzuzeigen, zurückgeführt werden kann, wird immer einen Wert zurückgeben

.

Ich sehe drei Möglichkeiten:

  1. warten auf Sprachunterstützung, sie auszudrücken (zB die C #?! Sache)
  2. Nutzung Aspect Orientierung Ihre eigenen Spracherweiterungen zu bauen, sie auszudrücken
  3. verwenden, um einen benutzerdefinierten Typ, sie auszudrücken
  4. (aber baut auf Entwickler Zusammenarbeit) verwenden, um ein Namensschema, um anzuzeigen,

Für Java kann man die Javadoc Beschreibung eines Verfahrens verwenden, um die Bedeutung des zurückgegebenen Wert zu dokumentieren, einschließlich, ob es null sein kann. Wie bereits erwähnt wurde, Anmerkungen auch hier Hilfe bieten können.

Auf der anderen Seite, ich gebe zu, dass ich nicht sehe null als etwas zu befürchten. Es gibt Situationen, in denen „niemand zu Hause“ ist ein sinnvoller Zustand (obwohl die Null-Objekt-Technik auch realen Wert hat hier).

Es ist sicher richtig, dass auf einem Nullwert einen Methodenaufruf versucht, wird eine Ausnahme verursachen. Aber so wird versucht, durch Null zu dividieren. Das bedeutet nicht, dass wir auf eine Kampagne gehen müssen Nullen zu beseitigen! Es bedeutet nur, dass wir den Vertrag auf einem Verfahren und das Richtige zu tun mit den Werten verstehen müssen, die es gibt.

Haben Sie hatte einen Blick auf Spec # ?

Sie können Ihre eigene Anmerkung (Java) oder Attribut (C #) schreiben, um anzuzeigen, dass der Rückgabewert null sein könnte. Nichts wird es automatisch überprüfen (obwohl .NET 4.0 haben Code Verträge diese Art der Sache), aber es wäre zumindest als Dokumentation.

Es gibt einige Unterstützung für eine @Nullable und @NotNull Anmerkung in IntelliJ IDEA . Es gibt auch einige sprechen diese Anmerkungen über das Hinzufügen (oder eine ähnliche Funktion) auf Java 7. Leider weiß ich nicht, wie weit die bekam oder ob es überhaupt noch auf dem richtigen Weg.

Vielleicht könnten Sie eine generische Klasse definieren namens „NotNull“, so dass Ihre Methode aussehen könnte:

public NotNull<Object> methodWhichCannotReturnNull(int i) throws Exception
{
   // the following would lead to a run-time error thown by the
   // NotNull constructor, if it's constructed with a null value
   return new NotNull<Object>(null);
}

Dies ist immer noch eine Laufzeit (keine Übersetzungszeit) überprüfen, aber:

  • Es geworfen wird bei der Durchführung des Verfahrens (es ist kein Fehler im Telefonvorwahl)
  • Es ist selbsterklärend (der Anrufer weiß, dass er NotNull<T> als Rückgabetyp ist geting)

Um jeden Preis vermeiden auf dem JavaDocs verlassen. Die Leute lesen sie nur, wenn die Signatur nicht trivial und selbsterklärend erscheint (was schlecht ist für den Anfang), und diese, die tatsächlich die Mühe, sie zu lesen sind weniger wahrscheinlich einen Fehler mit den Nullen zu machen, da sie derzeit vorsichtiger sein werden .

Wenn Sie Java 5 + verwenden, können Sie eine benutzerdefinierte Annotation verwenden, z.B. @MayReturnNull

UPDATE

Alle Codierung Philosophie beiseite (Rückkehr null, mit Ausnahmen, Assertions, Blabla), ich hoffe, die oben Ihre Frage beantwortet. Abgesehen von Primitiven mit Standardwerten, können komplexe Typen oder nicht null sein, und Ihr Code muss damit umgehen.

Im Allgemeinen würde ich davon ausgehen, dass ein Nullrückgabewert ist gegen den Vertrag des API standardmäßig. Es ist fast immer möglich, Ihren Code so zu gestalten, dass ein Nullwert wird nie von Ihrer APIs während „normalen“ Ablaufs der Ausführung zurückgegeben. (Zum Beispiel überprüfen foo.contains (obj) eher dann foo.get Aufruf (obj) und einen separaten Zweig für null hat. Oder verwenden Sie die Null-Objekt Muster .

Wenn Sie nicht Ihre API in so gestalten kann, würde ich klar dokumentieren, wann und warum eine Null geworfen werden könnte - bei mindestens in der Javadoc und möglicherweise auch mit einer benutzerdefinierten @annotation solche wie einige der anderen Antworten vorgeschlagen haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top