Wie zeigen, wenn eine Methode null zurückgeben
-
03-07-2019 - |
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: 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 Warum gibt es nicht so etwas wie folgt aus: Es gibt viele Möglichkeiten, den Vertrag zu äußern:
throws
keywords), aber kein formaler Weg geworfen werden zum Ausdruck bringen, wenn null zurückgeführt werden könnte ? public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
return null; // this would lead to a compiler error!
}
Zusammenfassung und Schlussfolgerungen
@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. Option<T>
oder NotNull<T>
, die Klarheit hinzufügen und mindestens Laufzeitprüfung.
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:
- warten auf Sprachunterstützung, sie auszudrücken (zB die C #?! Sache)
- Nutzung Aspect Orientierung Ihre eigenen Spracherweiterungen zu bauen, sie auszudrücken
- verwenden, um einen benutzerdefinierten Typ, sie auszudrücken
- (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.