2010-05-21 2 views
9

Ein möglicher Grund, weil eine NullPointerException eine Laufzeitausnahme ist, ist, weil jede Methode sie auslösen kann, so dass jede Methode eine "throws NullPointerException" haben müsste und hässlich wäre. Aber das passiert mit RemoteException.Warum NullPointerException ist eine Laufzeitausnahme und RemoteException nicht?

Und ein möglicher Grund, weil RemoteException keine Laufzeitausnahme ist, besteht darin, dem Client mitzuteilen, dass er die Ausnahme behandeln soll. Aber jede Methode in einer entfernten Umgebung muss sie auslösen, so dass es keinen Unterschied gibt, NullPointerException zu werfen.

Spekulationen? War ich klar?

+1

wie Menschen in der Sprache zu tun, die das Konzept von geprüften Ausnahmen haben nicht einmal? Was können Sie tun, was in einer anderen Sprache nicht sauber gemacht werden kann? Das Problem ist, dass die Leute "Versagen" für einen Sonderfall halten, anstatt zu erkennen, dass Versagen die Norm ist. Diese Art von Leuten mögen die großen riesigen GOTO-Anweisungen, die Ausnahmen überprüft haben. State-Test-Methoden? Zeitüberschreitungen? Naaaaah. Große gigantische GOTOs * "wenn der sh! T den Fan trifft" *. So ziemlich eine Javaspezifität und es macht sicherlich ** NICHT ** die gesamte Java-Community (zB das Spring-Framework hat einen großen Hass gegen sie). – SyntaxT3rr0r

+5

Webinator, der Typ fragte eine vollkommen vernünftige Frage. Es gibt keine Notwendigkeit zu schimpfen. – DJClayworth

Antwort

17

Ich werde die Entscheidung nicht diskutieren, ich werde nur die Erklärung der Entscheidung von Ann Wollrath (der das Design und die Implementierung von Java RMI leitete) zitieren. Dies wird von dieser message aus den RMI-NUTZER Archiven (Meldung vom Januar 1999) extrahiert:

Die Entscheidung zu treffen Remote ein Ausnahme geprüft und erfordert Fern Methoden in die Ausnahme zur Liste seines throws-Klausel ist nicht ein religiöser. Die Entscheidung basiert darauf, wie verteiltes Computing zuverlässig gemacht werden kann. Diese Frage kommt jedes Mal in einer während auf unserer Benutzerliste. Ich habe eine detaillierte Antwort, die ich vorhin eine gepostet habe. Hier ist es, wenn Sie interessiert sind. Ich konnte es nicht in rmi-users Archiv finden, also habe ich es unten eingeschlossen.

prost,

- Ann


Ich möchte die Gründe für machen Remote eine gesichtete Ausnahme, sondern als ein Runtime adressieren.

1) Netzwerke sind nicht zuverlässig

Ich wünsche, dass sie waren, aber in der Tat, sie sind es nicht. Jedes Netzwerk hat vorübergehende Fehler. Sie können in Netzwerkredundanz bauen, aber die Tatsache ist , dass die meisten Netzwerke das nicht haben. Intranets haben vorübergehende Fehler, wie das Internet tut. Also, jeder RPC gemacht, ist anfällig für einen Fehler. Die Typen der Fehler haben möglicherweise nichts zu tun mit dem "Netzwerk" an sich; Wenn Ihr Server keine Dateideskriptoren mehr enthält, wird Ihr Client eine Verbindung Ausnahme erhalten. Dies ist kein Netzwerk Fehler, im Sinne des Netzwerks gebrochen ist; Ihr Server befindet sich in einem Übergangszustand der Ressource verhungert.

RMI ist nicht entworfen, um nur den begrenzten Fall zu behandeln, dass das gesamte Netzwerk abstürzt, wenn ein einzelner Computer abstürzt. Solch ein Netzwerk würde zuverlässig betrachtet werden, entweder alles ist oben oder alles ist down - es gibt keinen Teilausfall. RMI ist für eine allgemeinere Zielgruppe ausgerichtet.

2) RPC-Fehler kann nicht von der Client

Teilausfall ist eine Tatsache des verteilte Programmierung ausgeblendet werden; Diese Fehler können nicht zum Programm ausgeblendet werden. Ein Fehler wird im Client angezeigt, unabhängig davon, ob die Ausnahme aktiviert oder deaktiviert ist, es wird weiterhin angezeigt. Also, wie sollten solche Ausfälle dem Client angezeigt werden?

3) überprüft Ausnahmen mehr robustere Programme fördern

Es gab eine Zeit, als Eiche und die früheste Version von Java nicht Ausnahmen geprüft hatte. Exception Handling war beratend, und es war eine unsichere Welt da draußen. Es war unsere Gruppe (Jim Waldo und ich insbesondere :-), dass empfohlen, dass es Ausnahmen vom Compiler überprüft werden. Jim war ziemlich überzeugend in seinen Argumenten und erzählte von einer Welt, in der robuster Code herrschen würde. Nach einiger Überlegung wurde Java umgerüstet, um Ausnahmen überprüft zu haben. Nur die Ausnahmen für , bei denen keine Wiederherstellung erfolgte oder Anwendungsfehler widerspiegeln, wären deaktiviert ( )., OutOfMemoryError, NullPointerException bzw.). Und die Welt war wieder sicher.

Stellen Sie sich die Java-Ingenieure Überraschung wenn viele Ausnahmen in der Java-API und Compiler von ungeprüft geprüft geändert wurden, und der Compiler die Unterscheidung durchgesetzt, sie entdeckt Fehler in den Implementierungen! Also, die besten Bemühungen im Umgang mit Fehler Bedingungen, wie gut gemeint, war nicht gut genug. Das Compiler ist nützlich für etwas :-)

4) Remote sollte hier eine gesichtete Ausnahme

Ok, also wieder auf dem richtigen Weg sein. Da ein Remote eine Tatsache des Lebens in einem RPC-Aufruf (siehe # 1, # 2) und überprüft Ausnahmen Sie sicher Code (# 3) schreiben zwingen, dachten wir, dass Remote eine geprüfte Ausnahme machen a war gute Idee. Schreiben von robusten verteilte Programme ist hart genug, ohne den Compiler Sie mit Ausnahmen zu helfen.

So könnte man argumentieren, dass eine RemoteException ist wie ein OutOfMemoryError; Ihr Programm sollte tot umfallen, wenn ein Remote-Aufruf fehlschlägt. Ich stimme diesem Punkt nicht zu. Ja, in einigen Fällen gibt es keine Wiederherstellung von RemoteException; aber wenn Sie schreiben ein zuverlässiges verteiltes Programm, muss Ihr Client Fehler fangen und entsprechend versuchen. Vielleicht müssen Sie einen anderen Server kontaktieren, oder eine Transaktion von einigen sort abbrechen. Wenn die RemoteException nicht behandelt wird, wird es versickern und crash Ihren Client (yuk).

Andere gesagt haben, dass es einige Remote-Schnittstellen sind, die in sowohl lokalen Fall und dem Remote- Fall und dem Kunden nicht mit den Ausnahmen von Abkommen werden in der lokalen Fall haben sollte, so sollte Remote nicht müssen in einer throws-Klausel sein und Handhabung sollte nicht obligatorisch sein. Wenn wir nun Remote-Schnittstelle Methoden erlaubt Remote wegzulassen und hatte einen „rmic“ -Schalter Stubs zu erzeugen die eine nicht geprüfte Remote werfen würde, die Client hat keine Wahl in der Angelegenheit. Die Entscheidung der Ausnahmebehandlung sollte bei der Client bleiben. Wenn Sie eine Schnittstelle definieren, die nur die ungeprüften Ausnahmen auslöst, können Sie niemals einen Client schreiben, der Compiler-Hilfe im Umgang mit diese Ausnahmen wünscht. Wir haben bereits aus dem obigen Beispiel gesehen, dass geprüfte Ausnahmen robuste Code fördert.

Ein weiteres Problem, das jetzt immer wieder auftauchte und wieder ist, dass Entwickler auf müssen einfach nur lokale Schnittstellen übersetzen und sie als Remote-Schnittstellen verwenden. Diese kann für eine kleine Gruppe von Fällen funktionieren, aber , wenn die Schnittstelle nicht mit Gleichzeitigkeit und Teilausfall und Anruf Latenz im Auge, das Protokoll erfaßt durch die Schnittstelle entworfen wurde nicht geeignet sein kann im verteilten zu verwenden Fall. Sind genug Informationen in diese Operationen übergeben, um die Operationen idempotent zu machen? Vielleicht, aber höchstwahrscheinlich nicht.

Putting Remote in jeder throws-Klausel wie ein Schmerz scheinen mag, aber sein Preis zu zahlen robust verteilte Anwendungen für das Schreiben.

- Ann Wollrath

+1

Sie sieht ziemlich überzeugt aus, dass Leute "robuste verteilte Anwendungen" [sic] in Sprachen nicht geschrieben haben, die nicht einmal das Konzept der geprüften Ausnahmen haben. Ich hätte gerne ein bisschen von dem, was sie letztes Jahrhundert geraucht hat, klingt stark :) – SyntaxT3rr0r

+7

@Downvoter Ich ** wirklich ** frage mich, warum diese Antwort downvoted wurde. Auch wenn Sie mit dem Autor nicht einverstanden sind, poste ich die ** Referenz **, keine Meinung. Emotionale Downvotes sind lächerlich. –

+1

Ich kann mir nicht vorstellen, warum irgendjemand dies abschwächen würde, wenn es, unabhängig von seinen Gefühlen auf geprüfte Ausnahmen, eindeutig die wahrscheinlich richtige Antwort auf die Frage ist, die Sie möglicherweise bekommen könnten. – ColinD

4

Es gibt erheblich mehr Potenzial für NullPointerException als RemoteException. Jeder Code, der eine Methode für ein Objekt aufruft (also praktisch irgendeinen Java-Code), könnte möglicherweise eine NullPointerException werfen. Nur RMI-Code kann eine RemoteException werfen. Dies ist eine kleine Teilmenge von "All Code".

Beim Schreiben der RMI-Bibliotheken haben die Designer entschieden, dass der Clientcode mit diesen Ausnahmen umgehen soll. Wenn man die Art der Remote-Codeausführung betrachtet, ist das vernünftig.

0

RemoteException nur Code der Anwendung Neben von java.rmi und javax.rmi Paketen (und ihrem Subpackages) ist RemoteException eine Art von IOException, ähnlich wie SocketException ist ... und alle IOException s Ausnahmen geprüft.

+0

Ich werde Sie nicht abmelden, aber diese Antwort ist kein möglicher Grund dafür, keine RuntimeException zu sein. RemoteException könnte nur eine Art von Ausnahme anstelle von IOExeption sein. Sei eine IOException ist eine Entscheidung, die nach der Entscheidung getroffen wird, die Ausnahme zu prüfen. –

+0

Alle Ausnahmen in Java, die sich mit Kommunikation befassen, sind Unterklassen von 'IOException'. 'IOException' (und alle anderen Klassen, die von' Exception' anstelle von 'RuntimeException' erben) ist eine geprüfte Ausnahme, daher sind alle Klassen, die von ihr erben, ebenfalls geprüfte Ausnahmen. – Powerlord

2

So wie ich es verstehe, ist:

  • Runtime werden für Dinge geworfen, die vermeidbar waren.
  • Ausnahmen werden für Dinge ausgelöst, die sich nicht verhindern lassen, aber wiederherstellbar sind
  • Fehler werden für Dinge ausgelöst, die nicht durchführbar und nicht wiederherstellbar sind.

Zum Beispiel können NullPointerExceptions immer vermieden werden und sind daher unchecked Ausnahmen. Eine RemoteException kann bei einem Netzwerkfehler auftreten, der vor dem Methodenaufruf nicht sinnvoll verhindert werden kann und daher überprüft wird.

+1

Ich glaube, Sie haben "Exceptions" und "RuntimeExceptions" in Ihrer Liste umgekehrt. 'NullPointerException' ist eine' RuntimeException'. – Matthew

+0

Aha, ja! Danke – Steve

Verwandte Themen