Kan ik meerdere Java-uitzonderingen opvangen in dezelfde catch-clausule?

In Java wil ik zoiets als dit doen:

try {
    ...     
} catch (/* code to catch IllegalArgumentException, SecurityException, 
            IllegalAccessException, and NoSuchFieldException at the same time */) {
   someCode();
}

…in plaats van:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

Is er een manier om dit te doen?


Antwoord 1, autoriteit 100%

Dit is mogelijk sinds Java 7. De syntaxis voor een multi-catch-blok is:

try { 
  ...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
            NoSuchFieldException e) { 
  someCode();
}

Houd er echter rekening mee dat als alle uitzonderingen tot dezelfde klassenhiërarchie behoren, u eenvoudig dat basisuitzonderingstype kunt opvangen.

Houd er rekening mee dat u niet zowel ExceptionAals ExceptionBin hetzelfde blok kunt vangen als ExceptionBdirect of indirect is geërfd van ExceptionA. De compiler zal klagen:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA

De oplossing hiervoor is om alleen de voorouderuitzondering in de uitzonderingenlijst op te nemen, omdat het ook uitzonderingen van het afstammelingstype opvangt.


Antwoord 2, autoriteit 9%

Niet precies vóór Java 7, maar ik zou zoiets als dit doen:

Java 6 en eerder

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {
     someCode();
  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     
  } else {
    throw new RuntimeException(exc);
  }
}

Java 7

try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException |NoSuchFieldException exc) {
  someCode();
}

Antwoord 3, autoriteit 2%

Binnen Java 7 kunt u meerdere catch-clausules definiëren, zoals:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}

Antwoord 4

Als er een hiërarchie van uitzonderingen is, kunt u de basisklasse gebruiken om alle subklassen van uitzonderingen op te vangen. In het gedegenereerde geval kun je alleJava-uitzonderingen opvangen met:

try {
   ...
} catch (Exception e) {
   someCode();
}

In een meer algemeen geval als RepositoryException de basisklasse is en PathNotFoundException een afgeleide klasse is, dan:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

De bovenstaande code zal RepositoryException en PathNotFoundException opvangen voor één soort uitzonderingsbehandeling en alle andere uitzonderingen worden op één hoop gegooid.
Sinds Java 7, volgens het antwoord van @OscarRyz hierboven:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}

Antwoord 5

Nee, één per klant vóór Java 7.

Je kunt een superklasse vangen, zoals java.lang.Exception, zolang je in alle gevallen dezelfde actie onderneemt.

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
    e.printStackTrace();
}

Maar dat is misschien niet de beste methode. Je zou alleen een uitzondering moeten opvangen als je een strategie hebt om het daadwerkelijk af te handelen – en loggen en opnieuw gooien is niet “het afhandelen”. Als u geen corrigerende actie heeft, kunt u deze beter toevoegen aan de handtekening van de methode en deze laten opborrelen bij iemand die de situatie aankan.


Antwoord 6

Een schoner (maar minder uitgebreid, en misschien niet zo geprefereerd) alternatief voor het antwoord van gebruiker454322 op Java 6 (dwz Android) zou zijn om alle Exception‘s te vangen en RuntimeExceptions. Dit zou niet werken als je van plan bent om andere soorten uitzonderingen verder op de stapel te vangen (tenzij je ze ook opnieuw gooit), maar het zal effectief alle aangevinkteuitzonderingen opvangen.

Bijvoorbeeld:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

Dat gezegd hebbende, voor breedsprakigheid is het misschien het beste om een ​​boolean of een andere variabele in te stellen en op basis daarvan wat code uit te voeren na het try-catch-blok.


Antwoord 7

In pre-7 hoe zit het met:

 Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }

Antwoord 8

Voor kotlin is het voorlopig niet mogelijk, maar ze hebben overwogen om het toe te voegen: Bron
Maar voor nu een klein trucje:

try {
    // code
} catch(ex:Exception) {
    when(ex) {
        is SomeException,
        is AnotherException -> {
            // handle
        }
        else -> throw ex
    }
}

Antwoord 9

Het is heel eenvoudig:

try { 
  // Your code here.
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
            NoSuchFieldException e) { 
  // Handle exception here.
}

Antwoord 10

Vang de uitzondering die toevallig een bovenliggende klasse is in de uitzonderingshiërarchie. Dit is natuurlijk een slechte gewoonte. In jouw geval is de algemene bovenliggende uitzondering toevallig de Exception-klasse, en het vangen van elke uitzondering die een instantie van Exception is, is inderdaad een slechte gewoonte – uitzonderingen zoals NullPointerException zijn meestal programmeerfouten en moeten meestal worden opgelost door te controleren op null-waarden.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

5 × four =

Other episodes