2015-06-23 1 views
12

Jedes Mal, wenn ich, wenn die übergebenen Parameter auf ein Verfahren zu überprüfen, hatte nicht null sind, habe ich eine Null-Scheck zu schreiben und eine IllegalArgumentException wenn die Nullprüfung nicht werfen:Objects.requireNonNull (T obj) anstelle von Null-Checks und manuell geworfen IllegalArgumentException?

if (user == null) { 
     throw new IllegalArgumentException("User can't be null."); 
    } 

jedoch durch den Quellcode Lesen von Einige Java 8 Klassen wie ArrayList, ich fand heraus, dass Oracle Objects.requireNonNull verwenden, um einen Parameter gegen einen Nullwert zu überprüfen, und dann, wenn der Test fehlschlägt, wird NullPointerException geworfen.

Auf diese Weise, die früheren Code-Schnipsel wie dies durch die Annahme dieses Ansatzes aussehen sollen:

Objects.requireNonNull(user, "User can't be null."); 

Kleiner und besser lesbar.

Unter der Annahme, dass ich die Kontrolle über die gesamte Ausnahmebehandlung des Systems haben, (auch, dass ich nicht, manchmal ist es Teil des Geschäfts ist es, diese ungeprüften Ausnahmen zu behandeln), sollte ich meine IllegalArgumentExceptions mit NullPointerException und Nutzung zu ersetzen Objects.requireNonNull anstatt meine eigene Nullprüfung und Ausnahmewerfen zu schreiben?

+9

Wir tun dies im JDK für neuen Code und alten Code opportunistisch anzupassen. Und es ist in der Zukunft durchaus möglich, dass die JVM schließlich Objects.requireNonNull ins Leben rufen wird, was ein weiterer Grund ist, sie zu bevorzugen. Die Debatte "sollte ich NPE oder IAE nutzen" ist meist ein Ratschlag; beide Positionen sind vertretbar, und die meiste Anstrengung, die zwischen ihnen verbracht wird, ist verschwendet. –

+1

Wenn Brian Goetz sagt, dass er es in einer Richtung macht, ist es wahrscheinlich so, wie du es willst ;-). – Daniel

+0

@BrianGoetz, auf diese Weise bevorzuge ich die "NullPointerException", wenn diese Nullprüfung fehlschlägt. Joshua hat bereits in seinem Buch die Präferenz für "NPE" gegenüber "IAE" angegeben, und auch wenn ich lese, was Sie über die Zukunft des JDK gesagt haben, denke ich, dass ich genug Beweise dafür habe. By the way, @OSryx answer stills valid um eine andere Art der Parameterprüfung zu implementieren. –

Antwort

10

Mit Objects.requireNonNull(c) können Sie sehr elegant überprüfen, ob das Element nicht null ist. Aber es gibt eine interessante Diskussion darüber, ob man NullPointerException oder IllegalArgumentException ->IllegalArgumentException or NullPointerException for a null parameter? wählt. So werfen NullPointerException ist der Java-Weg, um auszudrücken, dass eine Referenz null ist.

Andernfalls können Sie Ihre eigene Methode requireNotNull() machen. Es ist ganz einfach:

public static <T> T requireNonNull(T obj) { 
     if (obj == null) 
      throw new NullPointerException(); 
     return obj; 
    } 

und Sie können die Ausnahme NullPointerException von IllegalArgumentException ändern.

+0

Die bestbewerteten Antworten der besagten Diskussion gaben einen Punkt zusammen mit den Antworten hier. 'IllegalArgumentException' sieht besser aus, also kann ich immer noch kombiniert mit meiner" eigenen Version "von' Objects.requireNotNull' verwenden, die die Ausnahme auslöst, die ich möchte. –

+4

sei vorsichtig, manchmal ist die bestbewertete Antwort vielleicht die älteste;) –

+2

Du hast Recht. Indem ich ein bisschen mehr suche, habe ich herausgefunden, dass selbst Joshua Bloch die Verwendung von 'NullPointerException' anstelle von, IllegalArgumentException' verteidigt. Ich öffnete sein Buch, um sicherzugehen. Jetzt verstehe ich, warum es manchmal als "Heiliger Krieg" -Frage bezeichnet wird, beide Ansätze haben gute Seiten. Diese Diskussion ist jedoch nicht die Idee dieses Themas, daher kann ich Ihre Antwort sehr bald annehmen. –

6

Es gibt eine Diskussion darüber, welche Art von Ausnahme ausgelöst werden soll, wenn eine Methode einen Nullwert empfängt, den sie nicht erwartet. Einige Leute argumentieren für NullPointerException, einige Leute argumentieren für IllegalArgumentException. Der JDK-Weg scheint in solchen Fällen NullPointerException zu werfen, weshalb der Objects.requireNonNull es wirft.

Aber ich würde den vorhandenen Code nicht nur wegen dieser Methode ändern, obwohl Sie möglicherweise die Verwendung von Objects.requireNonNull in neuem Code in Betracht ziehen möchten. (Wenn Sie es verwenden, wird der Code normalerweise lesbarer als auf Null überprüft und eine Ausnahme manuell ausgelöst.)

+2

Wo ich arbeite, haben wir unsere eigene 'Ensure.notNull (Object val, String msg)' erstellt, die im Grunde dasselbe tut. Allerdings wird aus den von Hoopje angegebenen Gründen "IllegalArgumentException" und nicht "NullPointerException" ausgelöst. Wir haben dies als vorzuziehen gefunden, da es behauptete Nicht-Null-Argumente deutlich von zufälligen NPXs unterscheidet. Obwohl ich es noch nicht in unserer Codebasis gemacht habe, habe ich darüber nachgedacht, eine neue 'NullArgumentException' zu erstellen (erweitert 'IllegalArgumentException') und diese zu werfen. – Paul

+1

Dieses "* Wir haben festgestellt, dass dies vorzuziehen ist, da es behauptete Nicht-Null-Argumente klar von zufälligen NPXs unterscheidet. *" Ist ein bisschen verwerflich - wenn Sie eine NPE erhalten, haben Sie auch eine Zeilennummer, so dass Sie in diesem speziellen Fall sehen können dass das Argument null ist - und "Objects.requireNonNull" ermöglicht es Ihnen, eine spezifische Fehlermeldung anzugeben, wenn Sie möchten. – assylias

Verwandte Themen