Gibt es eine Standard-Java-Ausnahmeklasse, die “Das Objekt wurde nicht gefunden” bedeutet?

Lesezeit: 5 Minuten

Benutzer-Avatar
abl

Betrachten Sie eine Funktion der folgenden allgemeinen Form:

Foo findFoo(Collection<Foo> foos, otherarguments)
throws ObjectNotFoundException {
    for(Foo foo : foos){
        if(/* foo meets some condition*/){
            return foo;
        }
    }
    throw new ObjectNotFoundException();
}

Ein konkreter Fall wäre zum Beispiel:

User findUserByName(Collection<User> users, String name)
throws ObjectNotFoundException {
    for(User user : users){
        if(user.getName().equals(name)){
            return user;
        }
    }
    throw new ObjectNotFoundException();
}

Diese Funktionen lösen eine Ausnahme aus, wenn das Objekt nicht gefunden wird. Ich kann zu diesem Zweck eine benutzerdefinierte Ausnahmeklasse erstellen (in den Beispielen ObjectNotFoundException), aber ich würde lieber eine vorhandene Klasse verwenden. Ich konnte jedoch keine Ausnahmeklasse mit dieser Bedeutung in der Standard-Java-Bibliothek finden. Wissen Sie, ob es eine Standardausnahme gibt, die hier verwendet werden kann?

  • IlleagalArgumentException ?

    – Suresh Atta

    15. Juli 2014 um 14:05 Uhr


  • Und warum bestehen Sie darauf, dass das JDK die Ausnahme bereitstellt, wenn es sich um drei Codezeilen handelt, um sie selbst bereitzustellen? Ich weiß nicht, mit welchen APIs Sie zusätzlich arbeiten; JPA stellt beispielsweise eine “NoResultException” bereit.

    – Gibby

    15. Juli 2014 um 14:06 Uhr

  • Ich würde gehen für: IllegalArgumentException wie die dokumente sagt: Thrown to indicate that a method has been passed an illegal or inappropriate argument. Was tatsächlich passiert.

    – Jorge Campos

    15. Juli 2014 um 14:06 Uhr

  • IMHO ist es besser, eine benutzerdefinierte Ausnahme zu erstellen, die für den Kontext Ihrer Methode/Klasse/Schicht/Anwendung relevant ist, aber wenn Sie darauf bestehen, können Sie sie verwenden NoSuchElementException

    – Svetlin Zarev

    15. Juli 2014 um 14:06 Uhr


  • @Gimby An welchem ​​​​Punkt “beharrte” OP darauf, dass das JDK die Ausnahme bereitstellt? OP gab eine Präferenz an und stellte eine Frage. Darüber hinaus werden drei Codezeilen bei entsprechender Dokumentation länger. Und warum sich die Mühe machen wenn das JDK bietet es bereits?

    – Broschüre

    15. Juli 2014 um 14:10 Uhr

Benutzer-Avatar
Stefan C

Wissen Sie, ob es eine Standardausnahme gibt, die hier verwendet werden kann?

Davon gibt es ein paar Ausnahmen könnte verwendet werden (zB NoSuchElementException oder IllegalArgumentException), aber die Antwort hängt wirklich von der Semantik ab, die Sie vermitteln möchten:

  • NoSuchElementException wird in der Regel verwendet, wenn Sie eine Sequenz oder Aufzählung schrittweise durchlaufen, wobei Sie hier eine Suche haben.

  • IllegalArgumentException tendiert dazu, dass das Argument fehlerhaft ist, aber in diesem Fall könnte es sein, dass die Annahmen des Aufrufers falsch sind oder etwas, das für die Anwendungslogik spezifisch ist.

  • Mit einer benutzerdefinierten Ausnahme können Sie (in den Javadocs) genau sagen, was die Ausnahme bedeutet. Sie können es auch deklarieren überprüft … wenn es angebracht ist.

(Aber seien Sie nicht versucht, es zu verwenden UnknownUserException. Das wäre schrecklich falsch; Lesen Sie das Javadoc!)


Es lohnt sich auch, über eine Rückkehr nachzudenken nullinsbesondere wenn ein Suchfehler wahrscheinlich ein ziemlich häufiges (nicht außergewöhnliches) Ereignis in Ihrer Anwendung ist. Jedochdie Kehrseite der Rückkehr null ist, dass der Anrufer nachsehen muss null oder unerwartet riskieren NullPointerExceptions. In der Tat würde ich argumentieren, dass die übermäßige Verwendung von null ist schlimmer als die übermäßige Verwendung von Ausnahmen. Ersteres kann zu unzuverlässigen Anwendungen führen, während letzteres „nur“ schlecht für die Performance ist.

Für Java 8 und höher ist das Zurückgeben von an Optional wäre eine sauberere Wahl, als a zurückzugeben null.


In diesen Dingen ist es wichtig, über die Dogmen hinauszublicken und sich auf der Grundlage dessen zu entscheiden, was der tatsächliche Kontext erfordert.

Benutzer-Avatar
Paul

IllegalArgumentException wird hier manchmal verwendet, aber die Verwendung Ihrer eigenen Ausnahme ist vollkommen in Ordnung.

Nebenbei würde ich empfehlen, eine Karte mit zu verwenden String name als Schlüssel und User als Wert. Das Iterieren über die Sammlung wäre dann unnötig und es würde verhindern, dass zwei Benutzer mit demselben Namen in der Sammlung vorhanden sind. Wenn Sie keine Karte verwenden möchten, verteidigen Sie sich zumindest dagegen NullPointerException so:

User findUserByName(Collection<User> users, String name) throws ObjectNotFoundException
{
  if (name == null)
  {
    throw new IllegalArgumentException("name parameter must not be null");
  }
  if (users == null)
  {
    throw new IllegalArgumentException("Collection of users must not be null");
  }
  for(User user : users)
  {
    if(name.equals(user.getName()))
    {
      return user;
    }
  }
  throw new ObjectNotFoundException("Unable to locate user with name: " + name);
}

  • Verspäteter Kommentar. Es ist fraglich, ob Sie sich dagegen „wehren“ sollten null und NPEs. Die alternative Sichtweise ist, dass wenn a null wird an eine API-Methode übergeben, die dies nicht ist dokumentiert als zulassen nulldann ist das ein BUG, ​​und du sollte werfen Sie die NPE (als die spezifischste Ausnahme für diese Bedingung). Das vollständige Verhindern der NPE (z. B. durch den Versuch, “gut zu machen”) oder das Auslösen einer anderen Ausnahme wird nicht helfen, und kann machen die Sache noch schlimmer, indem sie ein Problem verbergen, das dem Entwickler / Betreuer zur Kenntnis gebracht werden sollte.

    – Stefan C

    17. Juni 2019 um 0:12 Uhr

  • In diesem Beispiel macht es keinen Unterschied, ob Sie a werfen NullPointerException oder ein IllegalArgumentException. Beides sind ungeprüfte Ausnahmen, und beides sollte Lassen Sie den Aufrufer mit einem Stacktrace “aussteigen”, den der Entwickler einsehen kann. Also zumindest die users == null Prüfung ist überflüssig. (NPE ist dein Freund, nicht dein Feind!)

    – Stefan C

    17. Juni 2019 um 0:15 Uhr


Bei Java 8 würde ich empfehlen, für diesen Anwendungsfall ein Optional zu verwenden.

Optional<User> findUserByName(Collection<User> users, String name){
    Optional<User> value = users
        .stream()
        .filter(a -> a.equals(name))
        .findFirst();
}

Dadurch wird dem Aufrufer auch sehr deutlich, dass das Optional leer sein kann, wenn der Wert nicht gefunden wird. Wenn Sie wirklich eine Ausnahme auslösen möchten, können Sie verwenden orElseThrows in Optional, um es zu erreichen.

Dies hängt vom dokumentierten Schnittstellenvertrag Ihrer Methode ab:

Wenn die Dokumentation Ihrer Methode besagt, dass die name Streit muss dem Namen eines existierenden Benutzers entsprechen, dann ist es angemessen zu werfen IllegalArgumentException wenn der Name nicht gefunden wird, bedeutet dies, dass der Aufrufer gegen die Anforderungen der Methode verstoßen hat, indem er einen Namen übergeben hat, der keinem Benutzer entspricht.

Wenn Ihre Methode nicht besagt, dass der Name einem vorhandenen Benutzer entsprechen muss, ist das Übergeben eines unbekannten Namens kein Fehler, und Sie sollten überhaupt keine Ausnahme auslösen. Rückkehr null wäre in dieser Situation angebracht.

Beachten Sie, dass Ihre findUserByName Methode erfindet im Grunde die Map.get Methode, die zurückkehrt null wenn der angegebene Schlüssel nicht gefunden wird.

1282750cookie-checkGibt es eine Standard-Java-Ausnahmeklasse, die “Das Objekt wurde nicht gefunden” bedeutet?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy