Com gestionar les excepcions de Java de la manera correcta

Com gestionar les excepcions de Java de la manera correcta

Com a novell en programació, el concepte de manipulació d’excepcions pot ser difícil embolicar el cap. No és que el concepte en si sigui difícil, però la terminologia pot fer que sembli més avançat del que és. I és una característica tan poderosa que és propensa a un ús indegut i abusiu.





En aquest article, aprendreu quines són les excepcions, per què són importants, com utilitzar-les i els errors habituals que cal evitar. La majoria dels llenguatges moderns tenen algun tipus d’excepció, de manera que, si alguna vegada passeu de Java, podeu portar la majoria d’aquests consells.





Comprensió de les excepcions de Java

A Java, un fitxer excepció és un objecte que indica que s'ha produït alguna cosa anormal (o 'excepcional') durant l'execució de l'aplicació. Aquestes excepcions són llançat , que bàsicament vol dir que es crea un objecte d'excepció (similar a com es generen els errors).





La bellesa és que pots atrapar excepcions generades, que us permeten afrontar l'estat anormal i permetre que l'aplicació continuï executant-se com si res no anés malament. Per exemple, mentre que un punter nul en C pot bloquejar la vostra aplicació, Java us permet llançar i atrapar

NullPointerException

s abans que una variable nul·la tingui l'oportunitat de provocar un bloqueig.



Recordeu, una excepció és només un objecte, però amb una característica important: s’ha d’estendre des del fitxer

Exception

classe o qualsevol subclasse de





Exception

. Tot i que Java té tot tipus d’excepcions integrades, també podeu crear les vostres pròpies si ho desitgeu. Alguns dels excepcions Java més comunes incloure:

  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • RuntimeException
  • IllegalStateException

Què passa, doncs, quan es produeix una excepció?





En primer lloc, Java busca dins del mètode immediat per veure si hi ha codi que gestioni el tipus d’excepció que vau llançar. Si no existeix un controlador, es fixa en el mètode que va cridar el mètode actual per veure si hi ha un identificador. Si no, es fixa en el mètode que va cridar això mètode, i després el següent, etc. Si no es detecta l'excepció, l'aplicació imprimeix una traça de pila i es bloqueja. (En realitat és més matisat que simplement estavellar-se, però aquest és un tema avançat més enllà de l'abast d'aquest article).

A traça de pila és una llista de tots els mètodes que Java va recórrer mentre buscava un controlador d’excepcions. A continuació s’explica el traçat de pila:

Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

D’això en podem extreure molt. En primer lloc, l'excepció llançada va ser una

NullPointerException

. Es va produir al

getTitle()

mètode a la línia 16 de Book.java. Aquest mètode es va cridar des de

getBookTitles()

a la línia 25 d'Autor.java. Això es va cridar des del mètode

main()

a la línia 14 de Bootstrap.java. Com podeu veure, conèixer tot això facilita la depuració.

Però, de nou, el veritable avantatge de les excepcions és que podeu 'gestionar' la condició anormal detectant l'excepció, ajustant les coses i reprenent l'aplicació sense bloquejar-vos.

Ús d’excepcions Java al codi

Diguem que sí

someMethod()

que pren un enter i executa una lògica que es podria trencar si l'enter és inferior a 0 o superior a 100. Aquest podria ser un bon lloc per llançar una excepció:

com aconseguir més emotes en contracció
public void someMethod(int value) {
if (value 100) {
throw new
IllegalArgumentException

Per obtenir aquesta excepció, heu d’anar a on

someMethod()

es diu i utilitza el fitxer bloc de prova de captura :

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}

Tot dins del provar El bloc s'executarà en ordre fins que es produeixi una excepció. Tan aviat com es llança una excepció, totes les sentències posteriors s'ometen i la lògica de l'aplicació salta immediatament al fitxer atrapar bloc.

En el nostre exemple, introduïm el bloc try i cridem immediatament

someMethod()

. Com que 200 no oscil·la entre 0 i 100, un

IllegalArgumentException

es tira. Això posa fi immediatament a l'execució de

someMethod()

, salta la resta de la lògica del bloc try (

someOtherMethod()

mai es diu) i reprèn l'execució dins del bloc de captura.

Què passaria si truquéssim?

someMethod(50)

en lloc d'això? El

IllegalArgumentException

mai no seria llançat.

someMethod()

s'executaria amb normalitat. El bloc try s'executaria de manera normal, cridant

someOtherMethod()

quan someMethod () es completa. Quan

someOtherMethod()

finalitza, el bloc de captura s'ometria i

callingMethod()

continuaria.

Tingueu en compte que podeu tenir diversos blocs de captura per bloc de prova:

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}

Tingueu en compte també que és opcional finalment el bloc també existeix:

public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}

El codi dins d'un bloc finalment és sempre executat passi el que passi. Si teniu una declaració de retorn al bloc try, el bloc final s'executa abans de sortir del mètode. Si llanceu una altra excepció al bloc de captura, el bloc final s'executa abans de llançar l'excepció.

Heu d’utilitzar el bloc finalment quan tingueu objectes que cal netejar abans que finalitzi el mètode. Per exemple, si heu obert un fitxer al bloc try i després heu generat una excepció, el bloc final us permet tancar el fitxer abans de deixar el mètode.

Tingueu en compte que finalment podeu tenir un bloc sense cap bloc de captura:

public void method() {
try {
// ...
} finally {
// ...
}
}

Això us permet fer la neteja necessària mentre permeteu que les excepcions llançades propaguen la pila d’invocació del mètode (és a dir, no voleu gestionar l’excepció aquí, però heu de netejar primer).

Excepcions marcades contra excepcions no verificades a Java

A diferència de la majoria dels idiomes, Java distingeix entre excepcions comprovades i excepcions sense comprovar (per exemple, C # només té excepcions sense marcar). Una excepció comprovada haver de quedar atrapat en el mètode on es produeix l'excepció o bé no es compilarà el codi.

Per crear una excepció marcada, amplieu des de

Exception

. Per crear una excepció no marcada, amplieu des de

RuntimeException

.

Qualsevol mètode que generi una excepció marcada ha de denotar-ho a la signatura del mètode mitjançant llança paraula clau. Des de Java integrat

IOException

és una excepció marcada, no es compilarà el codi següent:

public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Primer heu de declarar que genera una excepció marcada:

public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Tingueu en compte que un mètode es pot declarar que genera una excepció, però mai no genera una excepció. Tot i així, caldrà capturar l'excepció o bé no es compilarà el codi.

Quan heu d’utilitzar excepcions marcades o no?

La documentació oficial de Java té un fitxer pàgina sobre aquesta pregunta . Resumeix la diferència amb una succinta regla general: 'Si es pot esperar raonablement que un client es recuperi d'una excepció, converteix-lo en una excepció comprovada. Si un client no pot fer res per recuperar-se de l'excepció, convertiu-lo en una excepció sense comprovar. '

Però aquesta pauta pot estar obsoleta. D'una banda, les excepcions marcades donen lloc a un codi més robust. D'altra banda, cap altre llenguatge no ha comprovat les excepcions de la mateixa manera que Java, cosa que mostra dues coses: una, la funció no és prou útil perquè altres idiomes la puguin robar, i dues, es pot viure sense elles. A més, les excepcions marcades no juguen bé amb les expressions lambda introduïdes a Java 8.

Directrius per a l'ús d'excepcions de Java

Les excepcions són útils, però s’utilitzen i s’abusen fàcilment. A continuació, es detallen alguns consells i pràctiques recomanades que us ajudaran a evitar embolicar-los.

  • Preferiu excepcions específiques a excepcions generals. Utilitzeu NumberFormatException sobre IllegalArgumentException quan sigui possible, utilitzeu IllegalArgumentException sobre RuntimeException quan sigui possible.
  • No agafeu mai Throwable ! El Exception classe realment s'estén Throwable , i el bloc de captures realment funciona amb Throwable o qualsevol classe que estengui Throwable. Tanmateix, el Error la classe també s'estén Throwable i mai no voleu agafar cap Error perquè Error s indiquen problemes greus irrecuperables.
  • No agafeu mai Exception ! InterruptedException s'estén Exception , de manera que qualsevol bloc que atrapi Exception també atraparà InterruptedException , i aquesta és una excepció molt important amb la qual no us voleu embolicar (sobretot en aplicacions de diversos fils) tret que sàpiga què feu. Si no sabeu quina excepció voleu capturar, penseu a no agafar res.
  • Utilitzeu missatges descriptius per facilitar la depuració. Quan feu una excepció, podeu proporcionar un String missatge com a argument. Es pot accedir a aquest missatge al bloc de captures mitjançant el Exception.getMessage() mètode, però si l'excepció no es captura mai, el missatge també apareixerà com a part de la traça de la pila.
  • Intenteu no captar i ignorar les excepcions. Per evitar les molèsties de les excepcions comprovades, molts programadors novells i mandrosos configuraran un bloc de captures però el deixaran buit. Dolent! Maneu-lo sempre amb gràcia, però si no podeu, com a mínim imprimiu una traça de pila perquè sàpiga l'excepció. Podeu fer-ho amb el Exception.printStackTrace() mètode.
  • Compte amb l’excés d’excepcions. Quan tens un martell, tot sembla un clau. Quan conegueu les excepcions per primera vegada, és possible que us sentiu obligat a convertir-ho tot en una excepció ... fins al punt que la major part del flux de control de l’aplicació es redueix al tractament d’excepcions. Recordeu, les excepcions estan pensades per a ocurrències 'excepcionals'.

Ara hauríeu d’estar prou còmode amb excepcions per entendre què són, per què s’utilitzen i com incorporar-los al vostre propi codi. Si no enteneu completament el concepte, està bé! Vaig trigar una estona a 'fer clic' al meu cap, de manera que no tingueu la sensació de necessitar-ho a corre-cuita. Pren-te el teu temps.

Tens alguna pregunta? Coneixeu algun altre consell relacionat amb les excepcions que he perdut? Comparteix-los als comentaris següents.

Compartir Compartir Tweet Correu electrònic Com es crea un diagrama de flux de dades per visualitzar les dades de qualsevol projecte

Els diagrames de flux de dades (DFD) de qualsevol procés us ajuden a entendre com flueixen les dades des de la font fins a la destinació. A continuació us expliquem com crear-lo.

Llegiu a continuació
Temes relacionats
  • Programació
  • Java
Sobre l'autor Joel Lee(1524 articles publicats)

Joel Lee és l’editor en cap de MakeUseOf des del 2018. Té un B.S. en informàtica i més de nou anys d'experiència en redacció i edició professional.

per què els meus jocs continuen fallant en PC?
Més de Joel Lee

Subscriu-te al nostre butlletí

Uniu-vos al nostre butlletí per obtenir consells tècnics, ressenyes, llibres electrònics gratuïts i ofertes exclusives.

Feu clic aquí per subscriure-us