Ez az oldal tartalmazza a könyvben előforduló kivételkezelési példák forrását és a hozzájuk tartozó magyarázatokat.
|
Új kivételosztály létrehozása és a program egy más pontján
kivételek kiváltása.
class MyException extends Exception {
}
//...
throw new Exception("Valamilyen hiba!");
throw new MyException();
//...
A teljes program: kivetel1.java
|
A példában két új kivételosztály jön létre, melyet Verem típusú
objektumok váltanak ki. A VeremMegteltException-t akkor, ha a fix
méretű verembe már nem fér több elem. Ekkor a kimaradó elem a
kivételen keresztül a kezelőhöz is eljut, és a miVolt metódussal
lekérdezhető.
class VeremException extends Exception {
}
class VeremMegteltException extends VeremException {
private Object utolsó;
public VeremMegteltException(Object o) {
utolsó=o;
}
public Object miVolt(){
return utolsó;
}
}
class Verem {
final static public int MÉRET=10;
private Object tároló[]=new Object[MÉRET];
private int mutató=0;
//...
public void betesz(Object o) {
//...
if( mutató<tároló.length ) {
tároló[mutató++]=o;
}
else {
throw new VeremMegteltException(o);
}
//...
}
}
}
A teljes program: Verem1.java
|
A try blokk figyeli a benne szereplő utasításokat kivétel
keletkezése szempontjából. A catch ágak elkapják a
paraméterüknek megfelelő típusú kivételt és végrehajtják az
ághoz tartozó utasításokat.
try {
/*Java utasítások*/
}
catch(Típus1 változónév1) { /*Java utasítások*/ }
catch(Típus2 változónév2) { /*Java utasítások*/ }
catch(Típus3 változónév3) { /*Java utasítások*/ }
//...
A teljes program: kivetel2.java
|
Fontos jól megválasztani a kivételkezelő ágak sorrendjét, a
speciálisabbtól az általánosabb felé haladva.
class VeremException extends Exception {
}
class VeremMegteltException extends VeremException {
}
class ListaException extends Exception {
}
try {
/*...*/
}
catch(VeremMegteltException v1) { /*...*/ }
catch(VeremException v2) { /*...*/ }
catch(Exception v3) { /*...*/ }
A teljes program: Verem2.java
|
Az alábbi fájlmegnyitási példa jól szemlélteti a finally
használatának szükségességét. Ha az out megnyitásra
került, akkor bármelyik lefutásnál lezáródik.
FileOutputStream out = null;
int data = 1;
try {
out = new FileOutputStream("kimenet.txt");
out.write(data);
out.flush();
} catch (IOException e) {
System.out.println("Fájl írási hiba!");
} finally {
if (out != null) {
try { out.close(); }
catch( IOException ioe) { System.out.println("Lezárási hiba!"); }
}
}
A teljes program: finally.java
|
A korábbi vermes példa kiegészítése a
VeremMegteltException elkapásával.
public void betesz(Object o) {
try{
if( mutató<tároló.length ) {
tároló[mutató++]=o;
}
else {
throw new VeremMegteltException(o);
}
}
catch(VeremMegteltException e) {
System.out.println("A(z) "+e.miVolt()+" objektum nem fért a verembe!");
}
catch(Exception e) {
System.out.println("Valamilyen hiba történt!");
}
finally {
System.out.println("A betesz metódus lefutott!");
}
}
A teljes program: Verem1.java
|
Az alábbi példában szereplő catch ág minden
kivételt elkap, de semmit nem kezd velük. Így a felhasználó nem
értesül a hibáról, amikor az bekövetkezik.
public void f(Object o) {
try{
// időnként kivételt okozó műveletek
}
catch(Exception e) {
}
}
A teljes program: kivetel3.java
|
Ha a metódus írója nem tud vagy nem akar mit kezdeni a fellépő
kivételekkel, akkor specifikálja azokat.
metódus() throws Exception1, Exception2, ... {
//...
}
A teljes program: kivetel4.java
|
Mivel egy általános verem esetén a verem felhasználója tudja,
hogy mit kell tenni betelés esetén, ezért jobb specifikálni, és
nem elkapni a keletkező kivételeket.
public void betesz(Object o) throws VeremMegteltException {
//...
if( mutató < tároló.length ) {
tároló[mutató++]=o;
}
else {
throw new VeremMegteltException(o);
}
//...
}
A teljes program: Verem3.java
|
Az alábbi példa a kivételkezelés összes elemét felvonultatja:
kiváltás, terjedés, elkapás, kezelés, specifikálás.
class MyException extends Exception {
public MyException(String s) { super(s); }
}
class Teszt {
static int dobo(String s) throws MyException {
try {
if (s.equals("osztas")) {
int i = 0;
return i/i;
}
if (s.equals("null")) {
s = null;
return s.length();
}
if (s.equals("teszt")) {
throw new MyException("Teszt üzenet");
}
return 0;
} finally {
System.out.println("[dobo(\"" + s +"\") vége]");
}
}
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
try {
dobo(args[i]);
System.out.println("Teszt \""+
args[i]+
"\" nem váltott ki kivételt");
}
catch (Exception e) {
System.out.println("Teszt \""+
args[i]+
"\" kiváltott egy kivételt: "+
e.getClass()+"\n "+
e.getMessage()+" üzenettel");
}
}
}
}
A teljes program: Teszt.java
|
Az alappélda, amit hibakezeléssel kétféleképpen is kibővíthetünk.
gyumolcs() {
alma(); //meghívott eljárások
//...
korte();
//...
barack();
}
A teljes program: kivetel5.java
|
A hagyományos kezelési mód megnöveli a kódot, és
áttekinthetetlenné teszi.
gyumolcs() {
ret1=alma(); if(ret1==ok) {
//...
ret2=korte(); if(ret2==ok) {
//...
ret3=barack(); if(ret3==ok) {
return ok;
}
else { /* barack hibakezelése */ }
}
else { /* korte hibakezelése */ }
}
else {/* alma hibakezelése */ }
}
A teljes program: kivetel6.java
|
Kivételkezeléssel a kód növekedése kisebb, és ami még fontosabb
a kód sokkal áttekinthetőbb.
class AlmaException extends Exception {}
class KorteException extends Exception {}
class BarackException extends Exception {}
gyumolcs() {
try {
alma();
korte();
barack();
}
catch(AlmaException hiba1) { /* alma hibakezelése */ }
catch(KorteException hiba2) { /* korte hibakezelése */ }
catch(BarackException hiba3) { /* barack hibakezelése */ }
}
A teljes program: kivetel7.java
|
Az alappélda, amit hibaterjesztéssel kétféleképpen is kibővíthetünk.
gyumolcs() {
alma();
//folytatás1
}
alma() {
jonatan();
//folytatás2
}
jonatan() {
//műveletek
}
A teljes program: kivetel8.java
|
A hagyományos hibaterjesztés elbonyolítja a kódot és olyan részt
is érint, amit nem volna szükséges.
gyumolcs() {
ret=alma();
if(ret!=ok) {
//hibakezelés
} else {
//folytatás1
}
}
alma() {
ret=jonatan();
if(ret!=ok) {
return hiba;
} else {
//folytatás2
}
}
jonatan() {
//műveletek
if( művelethiba )
return hiba;
}
A teljes program: kivetel9.java
|
A kivételkezelés elegáns módot ad a hibaterjesztésre.
gyumolcs() {
try {
alma();
//folytatás1
}
catch(VmiException) {
//hibakezelés
}
}
alma() throws VmiException {
jonatan();
//folytatás2
}
jonatan() throws VmiException {
//műveletek
}
A teljes program: kivetel10.java
|
A kivételosztályok használatával nem kell rejtélyes hibakódokat
használni, és a hibáról is több tudható meg.
class VeremException extends Exception {}
class VeremMegteltException extends VeremException {}
class VeremUresException extends VeremException {}
A teljes program: Verem4.java
|