Προς το περιεχόμενο

exception handling (Java)


Προτεινόμενες αναρτήσεις

Δημοσ.

Μπορει καποιος να εξηγησει λιγο καλυτερα πότε και γιατι χρησιμοποιουμε το throw? Δεν μπορω να καταλαβω, αφου εχουμε try/catch για ελεγχο κι εχουμε και το throws, γιατι να ριξουμε εμεις δικο μας exception? Νομιζω πως θελω ενα real-life παραδειγμα...εχω φαει ενα απογευμα πανω απο ενα βιβλιο, stack-overflow,  tutorials point κλπ και παλι κατι κολλαει...τα φωτα σας παρακαλω!

Δημοσ. (επεξεργασμένο)

Custom exception?

 

Μπορείς να θέλεις να φτιάξεις δικά σου exception γιατί δεν σε καλύπτουν τα ηδη υπάρχοντα.

 

Εκτός και αν ρωτάς γιατι γενικώς κάνουμε throw και δεν αφήνουμε την java να κάνει τα δικά της. Γιατί δεν θέλουμε έλεγχο try catch μέσα σε συναρτήσεις αλλά πιο "έξω" οπότε πετάμε exception.

Επεξ/σία από kaliakman
  • Like 1
Δημοσ. (επεξεργασμένο)

Ενας λογος που χρησιμοποιειται το throw (ισως ο κυριοτερος) ειναι στη περιπτωση που χρησιμοποιεις custom exceptions που ειναι σχετικα με το προγραμμα σου και οχι κατι generic δηλαδη σχετικα μετη γλωσσα/standard library.

Ενας λογος που θα μπορουσε να ειναι χρησιμο κατι τετοιο, ειναι στις περιπτωσεις που δε θες να χειριζεσαι καποιο exception επιτοπου στο σημειο που συμβανει, αλλα σε πιο high level κωδικα, δηλαδη στον κωδικα που καλει τον κωδικα που προκαλεσε το exception. Με αυτο τον τροπο μπορεις να οργανωνεις καλυτερα τον exception-handling κωδικα σου και να τον εχεις μονο σε 1 σημειο, για πιθανως πολλα instances/συναρτησεις στις οποιες καλειται το throw.

Αν θες real-life παραδειγματα, πηγαινε GitHub και ψαξε. Οριστε παραδειγματα στον κωδικα του παιχνιδιου Osu! που ειναι γραμμενο σε C#:

https://github.com/ppy/osu/search?p=1&q=throw&type=&utf8=✓

Επεξ/σία από vel0city
Δημοσ. (επεξεργασμένο)

Λοιπόν...Εστω ότι έχουμε την class A και class B.

H κλάση class A είναι υπεύθυνη για να λαμβάνει κάποια στοιχεία του χρήστη και η class B για να τα αποθηκεύει. 

Η class A χρησιμοποιεί μία μέθοδο της class B η οποία θα απουηκεύσει τα δεδομένα του χρήστη στην βάση μας. Έστω όμως οτι κάτι παει στραβά και θέλουμε να πετάξουμε ένα μύνημα σφάλματος  απο την class B προς την class A.Πως θα γίνει αυτό? (Φυσικά με την μαγική λεξη throw). Η μέθοδος της class B θα κάνει ένα throw το σφάλμα που ανίχνευεσαι. 

Απο εκει και πέρα η μέθοδος της κλάσης A θα χρησιμοποιείσει try/catch ώστε να πιάσει αυτό το throw και να εμφανίσει το ανάλογο μύνημα σφάλματος.


Αυτο που πρέπει να κρατήσεις  είναι πως χρησιμοποιούμε try/catch στις μεθόδους οι οποίες θέλουμε να χειριστούν κάποια exception τα οποία προκύπτουν. Εαν μία μέθοδος πετάξει ένα exception και εσύ δεν θες να το διαχειριστεί η συγκεκριμένη αλλά μία αλλη μέθοδος 

που την καλεί τότε απλά θα χρησιμοποιησεις την λέξη throw .

Παρακατω εγραψα  (ενα τσαπατσουλικο) παράδειγμα:

	 static void fun(int number1,int number2) throws NullPointerException,IOException
	    {
		 /* αν οαριθμός number1 έίναι μεγαλύτερος τοτε πέτα ένα exception τυπου NullPointerException αλλα μην κάτσεις και
αχοληθείς με τον χειρισμό του ( αυτο θα το αναλάβει η κλάση που θα καλέσει την μέθοδο fun) */
		 if(number1>number2){
			 throw new NullPointerException();
		 }
		 else{
			 throw new IOException();
		 }
	      
	    }
	
	public static void main(String[] args) {
		try {
			fun(2,5);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	}

το παραπάνω παράδειγμα θα βγάλει στην κονσόλα 

java.io.IOException
    at Test.fun(Test.java:13)
    at Test.main(Test.java:20)
 

Επεξ/σία από makisvisual
Δημοσ. (επεξεργασμένο)
4 ώρες πριν, makisvisual είπε

Λοιπόν...Εστω ότι έχουμε την class A και class B.

H κλάση class A είναι υπεύθυνη για να λαμβάνει κάποια στοιχεία του χρήστη και η class B για να τα αποθηκεύει. 

Η class A χρησιμοποιεί μία μέθοδο της class B η οποία θα απουηκεύσει τα δεδομένα του χρήστη στην βάση μας. Έστω όμως οτι κάτι παει στραβά και θέλουμε να πετάξουμε ένα μύνημα σφάλματος  απο την class B προς την class A.Πως θα γίνει αυτό? (Φυσικά με την μαγική λεξη throw). Η μέθοδος της class B θα κάνει ένα throw το σφάλμα που ανίχνευεσαι. 

Απο εκει και πέρα η μέθοδος της κλάσης A θα χρησιμοποιείσει try/catch ώστε να πιάσει αυτό το throw και να εμφανίσει το ανάλογο μύνημα σφάλματος.


Αυτο που πρέπει να κρατήσεις  είναι πως χρησιμοποιούμε try/catch στις μεθόδους οι οποίες θέλουμε να χειριστούν κάποια exception τα οποία προκύπτουν. Εαν μία μέθοδος πετάξει ένα exception και εσύ δεν θες να το διαχειριστεί η συγκεκριμένη αλλά μία αλλη μέθοδος 

που την καλεί τότε απλά θα χρησιμοποιησεις την λέξη throw .

Παρακατω εγραψα  (ενα τσαπατσουλικο) παράδειγμα:


	 static void fun(int number1,int number2) throws NullPointerException,IOException
	    {
		 /* αν οαριθμός number1 έίναι μεγαλύτερος τοτε πέτα ένα exception τυπου NullPointerException αλλα μην κάτσεις και
αχοληθείς με τον χειρισμό του ( αυτο θα το αναλάβει η κλάση που θα καλέσει την μέθοδο fun) */
		 if(number1>number2){
			 throw new NullPointerException();
		 }
		 else{
			 throw new IOException();
		 }
	      
	    }
	
	public static void main(String[] args) {
		try {
			fun(2,5);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	}

το παραπάνω παράδειγμα θα βγάλει στην κονσόλα 

java.io.IOException
    at Test.fun(Test.java:13)
    at Test.main(Test.java:20)
 

Ωστοσο, εφοσον στο signature της fun() δηλωνουμε μεσω του throws στην επομενη συναρτηση στο call stack, "hey, εδω μαλλον θα εχει exception, ομως δεν θα ασχοληθω εγω, ασχολησου εσυ η προηγουμενη", τοτε γιατι ειναι αναγκη να κανουμε throw?


αυτο δεν καταλαβαινω. Γιατι throw? αφου υπαρχει το throws για checked exceptions!
Μισο.. το NullPointerException ειναι unchecked exception και θα εμφανιστει κατα το runtime, ποτε βασει του https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html, νταξει αν θελουμε το αγνοουμε, αλλα δεν ειναι κακο να το βαλουμε κιολας.
Το ΙΟException, ειναι checked exeption, οποτε θα βαλουμε το throws στο signature. Απο κει κι επειτα, γιατι throw?

Ευχαριστω guys, ειναι το πρωτο πραγμα που με εχει δυκολεψει αρκετα να το κατανοησω, προφανως λογω ελλειψης εμπειριας..

Επεξ/σία από nickname2016
Δημοσ.

Throw μπορείς να έχεις μέσα σε catch. Π.χ. κανείς log το error και μετά αφήνεις το exception γίνει throw.

try
{
   ...
}
catch(Exception ex)
{
   log(ex);
   throw;
}

 

Δημοσ.
Στις 28/1/2018 στις 2:28 ΠΜ, vel0city είπε

Ενας λογος που χρησιμοποιειται το throw (ισως ο κυριοτερος) ειναι στη περιπτωση που χρησιμοποιεις custom exceptions που ειναι σχετικα με το προγραμμα σου και οχι κατι generic δηλαδη σχετικα μετη γλωσσα/standard library.

Ενας λογος που θα μπορουσε να ειναι χρησιμο κατι τετοιο, ειναι στις περιπτωσεις που δε θες να χειριζεσαι καποιο exception επιτοπου στο σημειο που συμβανει, αλλα σε πιο high level κωδικα, δηλαδη στον κωδικα που καλει τον κωδικα που προκαλεσε το exception. Με αυτο τον τροπο μπορεις να οργανωνεις καλυτερα τον exception-handling κωδικα σου και να τον εχεις μονο σε 1 σημειο, για πιθανως πολλα instances/συναρτησεις στις οποιες καλειται το throw.

Αν θες real-life παραδειγματα, πηγαινε GitHub και ψαξε. Οριστε παραδειγματα στον κωδικα του παιχνιδιου Osu! που ειναι γραμμενο σε C#:

https://github.com/ppy/osu/search?p=1&q=throw&type=&utf8=✓

 

Και εγω παρόμοια άποψη εχω. Μπορεί να μην θέλεις να χειριστείς το πρόβλημα στο συγκεκριμένο σημείο αλλα θέλεις να χειριστεί σε υψηλότερο επίπεδο.

Για παράδειγμα, γραφεις μια βιβλιοθήκη και όταν βρεθεί πρόβλημα, δεν γίνεται να το χειριστείς. Το στέλνεις πίσω στον "χρηστη" της βιβλιοθήκης για να αποφασίσει αυτός τι θα γινει.

Οπως επίσης, μπορεί να θελεις να κρασαρεις το πρόγραμμα για να αντιληφθείς οτι εκεί έχεις πρόβλημα στα δεδομένα (π.χ. ειναι λαθος δεδομένα), η λάθος στον τρόπο χρήσης της βιβλιοθήκης.

Το υψηλότερο επιπεδο υλοποίησης μπορει να αποφασίσει να δείξει ενα dialog στην οθονη π.χ. η οτιδήποτε άλλο κρίνει απαραίτητο.

Αμα προσπαθήσεις να χειριστείς ολα τα λαθη στο σημείο ακριβως που συμβαίνουν ο κώδικας μπορει εύκολα να γίνει μπάχαλο.

 

Δημοσ.

Eαν βαλεις μόνο την λέξη throws δεν θα πετάξει το exception στην επόμενη μέθοδο.

Να στο πιο όσο πιο απλοικα μπορώ...πως στην υπογραφή μίας μεθόδου δηλώνεις εαν θα είναι τύπου String ή long κτλ κτλ...και στο τέλος της μεθόδους πρέπει πάντα να έχεις το keyword return.

Eτσι είναι και εδώ...δηλώνεις τι exceptions υπάρχει περίπτωση να πετάξει η μέθοδος με την λέξη throws και χρησιμοποιείς την λέξη throw για να κάνεις ένα return των exceptions αυτων.

  • Thanks 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...