JavaJava · Chapterبەش 11 · Lectureوانە 11.2
Exceptions: try, catch and finallyهەڵاوێردەکان: try، catch و finally
Handle runtime errors instead of crashing: the exception object, try and catch, the common exceptions with their real messages, several catch blocks and multi-catch, finally, the family of checked and unchecked exceptions, catch or declare with throws, throw and your own exception classes, a safe input loop with Locale.ROOT, try-with-resources, and why an empty catch is dangerous.
لە جیاتی وەستان چارەسەر بکە: ، try و catch، باو بە پەیامە ڕاستەقینەکانیانەوە، چەند بەشێکی catch و catchـی چەندجۆری، finally، خێزانی پشکنراو و نەپشکنراو، گرتن یان ڕاگەیاندن بە throws، throw و خۆت، سەلامەتی بە Locale.ROOT، و بۆچی catchـی بەتاڵ مەترسیدارە.
What you will learnچی فێر دەبیت
- Catch exceptions with try and catch, read the exception object, and explain which lines are skipped.
- Use several catch blocks in the right order, multi-catch and finally.
- Tell checked from unchecked exceptions and fix 'must be caught or declared to be thrown'.
- Throw exceptions with throw, declare them with throws and write your own exception class.
- Write a safe input loop and close resources with try-with-resources.
- بە try و catch بگریت، بخوێنیتەوە و ڕوونی بکەیتەوە کام دێڕ تێدەپەڕێنرێت.
- چەند بەشێکی catch بە ڕیزی دروست، catchـی چەندجۆری و finally بەکار بهێنیت.
- لە نەپشکنراوەکان جیا بکەیتەوە و 'must be caught or declared to be thrown' چاک بکەیت.
- بە throw فڕێ بدەیت، بە throws ڕایانبگەیەنیت و خۆت بنووسیت.
- سەلامەتی بنووسیت و بە دابخەیت.
When a program crashesکاتێک بەرنامەیەک دەوەستێت
A runtime error stops a program in the middle (Runtime errors). Java reports it by throwing an : an object that says what went wrong. Turning text into a number is a classic case: Integer.parseInt("42") gives 42, but Integer.parseInt("abc") has no number to give:
لە ناوەڕاستدا دەوەستێنێت (هەڵەکانی کاتی جێبەجێکردن). Java ئەمە بە فڕێدانی ڕادەگەیەنێت: کە دەڵێت چی هەڵە چوو. گۆڕینی دەق بۆ ژمارە نموونەیەکی ناسراوە: Integer.parseInt("42") 42 دەدات، بەڵام Integer.parseInt("abc") هیچ ژمارەیەکی نییە بیدات:
public class ParseCrash {
public static void main(String[] args) {
String text = "abc";
System.out.println("Converting " + text);
int number = Integer.parseInt(text);
System.out.println("Twice: " + number * 2);
}
}$ java ParseCrash Converting abc Exception in thread "main" java.lang.NumberFormatException: For input string: "abc" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:668) at java.base/java.lang.Integer.parseInt(Integer.java:786) at ParseCrash.main(ParseCrash.java:5)
Twice: was never printed: the program stopped at line 5. Until now you read such a stack trace to fix the code (Reading a stack trace). Some problems, though, come from outside: a user types abc, a file is missing. The program cannot prevent them, but it can handle them, and that is what this lesson teaches.
Twice: هەرگیز چاپ نەکرا: لە دێڕی 5 وەستا. تا ئێستا لەم جۆرەت دەخوێندەوە بۆ ئەوەی کۆدەکە چاک بکەیت (خوێندنەوەی ڕێچکەی هەڵە). بەڵام هەندێک کێشە لە دەرەوە دێن: abc دەنووسێت، نییە. ناتوانێت ڕێگرییان لێ بکات، بەڵام دەتوانێت چارەسەریان بکات و ئەم وانەیە ئەوە فێر دەکات.
Catching an exception: try and catchگرتنی هەڵاوێردەیەک: try و catch
Put the risky lines in a try block, and in a catch block say what to do when one exception type happens. If nothing is thrown, the catch block is skipped. If that exception is thrown, Java jumps to the catch block, and after it the program goes on normally. This is :
دێڕە مەترسیدارەکان بخەرە ناو بەشی tryـەوە و لە بەشی catchـدا بڵێ چی بکرێت کاتێک جۆرێکی ڕوو دەدات. ئەگەر هیچ فڕێ نەدرێت، بەشی catch تێدەپەڕێنرێت. ئەگەر ئەو فڕێ بدرێت، Java باز دەدات بۆ بەشی catch و دوای ئەو بە ئاسایی بەردەوام دەبێت. ئەمە :
public class CatchIt {
public static void main(String[] args) {
String text = "abc";
try {
int number = Integer.parseInt(text);
System.out.println("Twice: " + number * 2);
} catch (NumberFormatException e) {
System.out.println("Not a whole number: " + text);
}
System.out.println("The program goes on");
}
}$ java CatchIt Not a whole number: abc The program goes on
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5-6
The risky lines: line 6 is skipped if line 5 throws.
دێڕە مەترسیدارەکان: ئەگەر دێڕی 5 فڕێ بدات، دێڕی 6 تێدەپەڕێنرێت.
- Lineدێڕی 7-9
Runs only when a NumberFormatException is thrown in the try block.
تەنیا کاتێک جێبەجێ دەبێت کە NumberFormatException لە بەشی tryـدا فڕێ بدرێت.
$ java CatchIt Twice: 42 The program goes on
Exceptions in Java: what happens when a program crashes, catching an exception with try and catch, several catch blocks, one catch for two types, and the finally block.
لە Javaـدا: کاتێک لە ناکاو دەوەستێت چی ڕوودەدات، گرتنی بە try و catch، چەند بلۆکی catch، یەک catch بۆ دوو جۆر و بلۆکی finally.
Watch 0:00–6:03: what an exception is, then try and catch blocks.
لە 0:00 تا 6:03 سەیر بکە: چییە، پاشان بلۆکەکانی try و catch.
Catching an exception: try and catchگرتنی هەڵاوێردەیەک: try و catch
Inside the catch: the exception object eلە ناو catchـدا: ئۆبجێکتی هەڵاوێردە، e
In catch (NumberFormatException e), e is the exception object, like a parameter. e.getMessage() gives only the message, printing e gives the type and the message, and e.printStackTrace() prints the whole stack trace, while the program goes on:
لە catch (NumberFormatException e)ـدا، e ، وەک . e.getMessage() تەنیا پەیامەکە دەدات، چاپکردنی e جۆر و پەیامەکە دەدات و e.printStackTrace() هەموو چاپ دەکات، لە کاتێکدا بەردەوام دەبێت:
public class ExceptionParts {
public static void main(String[] args) {
try {
int number = Integer.parseInt("abc");
System.out.println(number);
} catch (NumberFormatException e) {
System.out.println("getMessage(): " + e.getMessage());
System.out.println("the object: " + e);
e.printStackTrace();
}
System.out.println("The program goes on");
}
}$ java ExceptionParts getMessage(): For input string: "abc" the object: java.lang.NumberFormatException: For input string: "abc" java.lang.NumberFormatException: For input string: "abc" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:668) at java.base/java.lang.Integer.parseInt(Integer.java:786) at ExceptionParts.main(ExceptionParts.java:4) The program goes on
A message helps the user; the stack trace helps you, the programmer. A real program shows the user a short sentence and keeps the stack trace for the developers, for example in a log file.
پەیامێک یارمەتیی دەدات؛ یارمەتیی تۆی دەدات. ڕاستەقینە ڕستەیەکی کورت پیشانی دەدات و بۆ هەڵدەگرێت، بۆ نموونە لە .
Catch the exceptions you expectئەو جۆرە هەڵاوێردەیەی چاوەڕێی دەکەیت بیگرە
A catch block catches only its own type, and the types below it in the family (soon). Everything else passes by, and the program stops as before. Here the text is a good number, 0, but the division by zero throws something else:
بەشی catch تەنیا جۆری خۆی دەگرێت، لەگەڵ ئەو جۆرانەی لە خێزانەکەدا لە خوارییەوەن (بەم زووانە). هەموو شتێکی تر تێدەپەڕێت و وەک پێشتر دەوەستێت. لێرە دەقەکە ژمارەیەکی دروستە، 0، بەڵام دابەشکردن بەسەر سفردا شتێکی تر فڕێ دەدات:
public class WrongCatch {
public static void main(String[] args) {
String text = "0";
try {
int friends = Integer.parseInt(text);
System.out.println("Each friend pays " + 30000 / friends + " dinars");
} catch (NumberFormatException e) {
System.out.println("Not a number");
}
System.out.println("Done");
}
}$ java WrongCatch Exception in thread "main" java.lang.ArithmeticException: / by zero at WrongCatch.main(WrongCatch.java:6)
These are the exceptions you will meet most often. The messages are real, from JDK 17:
ئەمانە باوترین کە دەیانبینیت. پەیامەکان ڕاستەقینەن، لە JDK 17ـەوە:
| Exception | Typical causeهۆکاری باو | Messageپەیام |
|---|---|---|
ArithmeticException | a whole number divided by 0 دابەش بەسەر 0دا | / by zero |
NumberFormatException | Integer.parseInt("abc")Integer.parseInt("abc") | For input string: "abc" |
InputMismatchException | nextInt() reads abc (Wrong input)nextInt() abc دەخوێنێتەوە (نێوخستەی هەڵە) | no messageبێ پەیام |
ArrayIndexOutOfBoundsException | marks[3] on length 3 (Outside the array)marks[3] بە درێژیی 3 (دەرەوەی ڕیزەک) | Index 3 out of bounds for length 3 |
StringIndexOutOfBoundsException | "Java".charAt(9) (Outside the string)"Java".charAt(9) (دەرەوەی زنجیرەنووسە) | String index out of range: 9 |
NullPointerException | a method called on null (null); a switch on a null String stops the same way (A null String) لەسەر null بانگ کراوە (null)؛ switchـێک لەسەر Stringـێکی nullیش بە هەمان شێوە دەوەستێت (Stringـی null) | Cannot invoke "String.length()" because "<local1>" is null |
ConcurrentModificationException | removing inside a for-each loop (HashMap and HashSet)لابردن لە ناو (HashMap و HashSet) | no messageبێ پەیام |
IllegalArgumentException | a method refuses a value (throw) ڕەت دەکاتەوە (throw) | your own messageپەیامی خۆت |
Catch the exceptions you expectئەو جۆرە هەڵاوێردەیەی چاوەڕێی دەکەیت بیگرە
Several catch blocksچەند بەشێکی catch
One try can have several catch blocks. Java checks them from the top and runs the first one whose type matches; the others are skipped. Each pass of this loop meets a different exception:
یەک try دەتوانێت چەند بەشێکی catchـی هەبێت. Java لە سەرەوە دەیانپشکنێت و یەکەمیان کە جۆرەکەی بگونجێت جێبەجێ دەکات؛ ئەوانی تر تێدەپەڕێنرێن. لە هەر ئەم جیاواز ڕوو دەدات:
public class SeveralCatches {
public static void main(String[] args) {
String[] answers = {"4", "0", "four"};
for (int i = 0; i <= 3; i++) {
try {
int friends = Integer.parseInt(answers[i]);
System.out.println("Each of " + friends + " friends pays " + 30000 / friends + " dinars");
} catch (NumberFormatException e) {
System.out.println("\"" + answers[i] + "\" is not a whole number");
} catch (ArithmeticException e) {
System.out.println("Nobody to share the bill with");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("There is no answer number " + i);
}
}
}
}$ java SeveralCatches Each of 4 friends pays 7500 dinars Nobody to share the bill with "four" is not a whole number There is no answer number 3
Order matters. A general catch (Exception e) above a specific one would catch everything first, so javac refuses the block that can never run:
ڕیزبەندی گرنگە. catch (Exception e)ـی گشتی لە سەرووی دانەیەکی تایبەتەوە سەرەتا هەموو شتێک دەگرێت، بۆیە javac ئەو بەشە ڕەت دەکاتەوە کە هەرگیز جێبەجێ نابێت:
$ javac CatchOrder.java
CatchOrder.java:7: error: exception ArithmeticException has already been caught
} catch (ArithmeticException e) {
^
1 errorCatch the exceptions you expectئەو جۆرە هەڵاوێردەیەی چاوەڕێی دەکەیت بیگرە
One catch for two types: |یەک catch بۆ دوو جۆر: |
When two exceptions need the same handling, name both in one catch block, separated by | (Java 7 and later). e.getMessage() then shows which problem it was:
کاتێک دوو پێویستیان بە هەمان چارەسەر هەیە، هەردووکیان لە یەک بەشی catchـدا بنووسە و بە | جیایان بکەرەوە (Java 7 و دواتر). پاشان e.getMessage() پیشان دەدات کامە کێشە بوو:
public class MultiCatch {
public static void main(String[] args) {
String[] answers = {"4", "0", "four"};
for (String answer : answers) {
try {
int friends = Integer.parseInt(answer);
System.out.println("Each pays " + 30000 / friends + " dinars");
} catch (NumberFormatException | ArithmeticException e) {
System.out.println("Cannot share the bill with \"" + answer + "\": " + e.getMessage());
}
}
}
}$ java MultiCatch Each pays 7500 dinars Cannot share the bill with "0": / by zero Cannot share the bill with "four": For input string: "four"
The types joined by | may not be parent and child. javac refuses NumberFormatException | IllegalArgumentException:
ئەو جۆرانەی بە | پێکەوە دەبەسترێن نابێت باوک و منداڵ بن. javac NumberFormatException | IllegalArgumentException ڕەت دەکاتەوە:
$ javac Related.java
Related.java:5: error: Alternatives in a multi-catch statement cannot be related by subclassing
} catch (NumberFormatException | IllegalArgumentException e) {
^
Alternative NumberFormatException is a subclass of alternative IllegalArgumentException
1 errorfinally: it always runsfinally: هەمیشە جێبەجێ دەبێت
A finally block after the catch blocks runs every time the try statement ends: after a normal run, after a caught exception, and even when no catch block matches: then finally runs first, and the exception goes on to the caller (here nobody catches it, so the program stops). Put there the work that must happen in any case:
بەشی finally لە دوای بەشەکانی catch هەر جارێک try کۆتایی دێت جێبەجێ دەبێت: دوای جێبەجێبوونێکی ئاسایی، دوای گیراو و تەنانەت کاتێک هیچ بەشێکی catch نەگونجێت: ئەوکاتە سەرەتا finally جێبەجێ دەبێت، پاشان دەچێت بۆ (لێرە کەس نایگرێت، بۆیە دەوەستێت). ئەو کارەی لە هەموو حاڵەتێکدا دەبێت بکرێت لەوێ دابنێ:
public class FinallyRuns {
static void share(String answer) {
System.out.println("Answer: " + answer);
try {
int friends = Integer.parseInt(answer);
System.out.println("Each pays " + 30000 / friends + " dinars");
} catch (NumberFormatException e) {
System.out.println("Not a number");
} finally {
System.out.println("finally runs");
}
}
public static void main(String[] args) {
share("4");
share("four");
share("0");
System.out.println("This line is never reached");
}
}$ java FinallyRuns Answer: 4 Each pays 7500 dinars finally runs Answer: four Not a number finally runs Answer: 0 finally runs Exception in thread "main" java.lang.ArithmeticException: / by zero at FinallyRuns.share(FinallyRuns.java:6) at FinallyRuns.main(FinallyRuns.java:17)
Exceptions in Java: what happens when a program crashes, catching an exception with try and catch, several catch blocks, one catch for two types, and the finally block.
لە Javaـدا: کاتێک لە ناکاو دەوەستێت چی ڕوودەدات، گرتنی بە try و catch، چەند بلۆکی catch، یەک catch بۆ دوو جۆر و بلۆکی finally.
Watch 8:27 to the end: the finally block and when it runs.
لە 8:27 تا کۆتایی سەیر بکە: بلۆکی finally و کەی جێبەجێ دەبێت.
finally: it always runsfinally: هەمیشە جێبەجێ دەبێت
Step by step: where the program jumpsهەنگاو بە هەنگاو: بەرنامەکە بۆ کوێ باز دەدات
The animation runs one try statement with the answer "0", then with "4". Watch which lines run, which are skipped, and where the program jumps:
ئەنیمەیشنەکە یەک try بە وەڵامی "0" جێبەجێ دەکات، پاشان بە "4". سەیر بکە کام دێڕ جێبەجێ دەبێت، کام تێدەپەڕێنرێت و بۆ کوێ باز دەدات:


The same try statement inside a method, called with both answers; the real output matches the animation:
هەمان try لە ناو ، بە هەردوو وەڵامەکە بانگ کراوە؛ ڕاستەقینە لەگەڵ ئەنیمەیشنەکە دەگونجێت:
public class ShareBill {
static void share(String answer) {
try {
int friends = Integer.parseInt(answer);
int each = 30000 / friends;
System.out.println("Each pays " + each);
} catch (NumberFormatException e) {
System.out.println("Not a number");
} catch (ArithmeticException e) {
System.out.println("Nobody to share with");
} finally {
System.out.println("finally runs");
}
System.out.println("Next answer");
}
public static void main(String[] args) {
share("0");
share("4");
}
}$ java ShareBill Nobody to share with finally runs Next answer Each pays 7500 finally runs Next answer
The exception family: checked and uncheckedخێزانی هەڵاوێردەکان: پشکنراو و نەپشکنراو
Exceptions are classes, and they form a family through inheritance (extends). At the top is Throwable with two branches: Error for serious problems that a program should not try to catch, such as StackOverflowError (Stack overflow), and Exception for problems a program can handle. A catch for a parent type also catches its children: catch (RuntimeException e) catches an ArithmeticException too.
و لە ڕێگەی خێزانێک پێک دەهێنن (extends). لە سەرەوە Throwable هەیە بە دوو لق: Error بۆ کێشەی گەورە کە نابێت هەوڵی گرتنیان بدات، وەک StackOverflowError (سەرڕێژبوونی ستاک)؛ Exceptionیش بۆ ئەو کێشانەی دەتوانێت چارەسەریان بکات. catchـێک بۆ جۆرێکی باوک منداڵەکانیشی دەگرێت: catch (RuntimeException e) ArithmeticExceptionیش دەگرێت.
are RuntimeException, Error and their subclasses: javac does not make you handle them, because they usually show a that you should fix in the code. All the others are : javac checks that your code deals with them. The next screen shows how.
بریتین لە RuntimeException، Error و : javac ناچارت ناکات مامەڵەیان لەگەڵ بکەیت، چونکە زۆرجار پیشان دەدەن کە دەبێت لە کۆدەکەدا چاکی بکەیت. هەموو ئەوانی تر : javac دەپشکنێت کە کۆدەکەت مامەڵەیان لەگەڵ دەکات. پەڕەی داهاتوو پیشانی دەدات چۆن.
Checked exceptions: catch or declareهەڵاوێردە پشکنراوەکان: بیگرە یان ڕایبگەیەنە
A Scanner can read a file as well as the keyboard: new Scanner(new File("notes.txt")). If the file is missing, it throws a FileNotFoundException, a checked exception, so javac refuses code that ignores it:
Scanner دەتوانێت بخوێنێتەوە وەک چۆن دەخوێنێتەوە: new Scanner(new File("notes.txt")). ئەگەر نەبێت، FileNotFoundException فڕێ دەدات، کە ، بۆیە javac ئەو کۆدە ڕەت دەکاتەوە کە گوێی پێ نادات:
import java.io.File;
import java.util.Scanner;
public class ReadNotes {
public static void main(String[] args) {
Scanner reader = new Scanner(new File("notes.txt"));
System.out.println(reader.nextLine());
}
}$ javac ReadNotes.java
ReadNotes.java:6: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
Scanner reader = new Scanner(new File("notes.txt"));
^
1 errorAn that the checks for: a method that can throw it, such as IOException from work with files, must either catch it or name it after throws, or the program does not compile. Compare .
کە دەیپشکنێت: کە دەتوانێت فڕێی بدات، وەک IOException لە کارکردن لەگەڵ ، یان دەبێت بیگرێت یان دوای throws ناوی بهێنێت، ئەگەر نا کۆمپایل نابێت. بەراوردی بکە لەگەڵ .
Fix 1, catch it: the program decides what to do. We ran it once without notes.txt and once after creating it:
چارەسەری 1، بیگرە: خۆی بڕیار دەدات چی بکات. جارێک بەبێ notes.txt و جارێک دوای دروستکردنی جێبەجێمان کرد:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ReadNotes {
public static void main(String[] args) {
try {
Scanner reader = new Scanner(new File("notes.txt"));
System.out.println("First line: " + reader.nextLine());
reader.close();
} catch (FileNotFoundException e) {
System.out.println("Could not open the file: " + e.getMessage());
}
}
}$ java ReadNotes Could not open the file: notes.txt (No such file or directory) $ printf 'Buy bread\nCall Aram\n' > notes.txt $ java ReadNotes First line: Buy bread
Fix 2, declare it with throws after the brackets of the method. The method hands the problem to its caller; for main that is the JVM, which prints the stack trace:
چارەسەری 2، ڕایبگەیەنە بە throws لە دوای کەوانەکانی . کێشەکە دەداتە دەست ؛ بۆ main ئەوە JVMـە، کە چاپ دەکات:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ReadNotes {
public static void main(String[] args) throws FileNotFoundException {
Scanner reader = new Scanner(new File("notes.txt"));
System.out.println("First line: " + reader.nextLine());
reader.close();
}
}$ java ReadNotes Exception in thread "main" java.io.FileNotFoundException: notes.txt (No such file or directory) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:216) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157) at java.base/java.util.Scanner.<init>(Scanner.java:639) at ReadNotes.main(ReadNotes.java:7)
Throwing an exception yourself: throwفڕێدانی هەڵاوێردەیەک بە دەستی خۆت: throw
You met throw once already: in Removing an element it refuses an index outside the array. Your own methods can refuse a bad value with throw and a new exception object. throw ends the method at once, like return, and the exception travels to the caller:
پێشتر جارێک throwـت بینی: لە لابردنی دانەیەکـدا دەرەوەی ڕەت دەکاتەوە. خۆت دەتوانن خراپ بە throw و نوێ ڕەت بکەنەوە. throw یەکسەر کۆتایی پێ دەهێنێت (وەک return) و دەچێت بۆ :
public class CheckMark {
static void saveMark(int mark) {
if (mark < 0 || mark > 100) {
throw new IllegalArgumentException("a mark must be 0 to 100, not " + mark);
}
System.out.println(mark + " saved");
}
public static void main(String[] args) {
saveMark(85);
saveMark(120);
System.out.println("This line is never reached");
}
}$ java CheckMark 85 saved Exception in thread "main" java.lang.IllegalArgumentException: a mark must be 0 to 100, not 120 at CheckMark.saveMark(CheckMark.java:4) at CheckMark.main(CheckMark.java:11)
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4
IllegalArgumentException is Java's usual unchecked exception for a bad argument.
IllegalArgumentException نەپشکنراوی ئاسایی Javaـیە بۆ خراپ.
The caller can catch it and carry on with the next value:
دەتوانێت بیگرێت و بە دواتر بەردەوام بێت:
public class CheckMarks {
static void saveMark(int mark) {
if (mark < 0 || mark > 100) {
throw new IllegalArgumentException("a mark must be 0 to 100, not " + mark);
}
System.out.println(mark + " saved");
}
public static void main(String[] args) {
int[] typed = {85, 120, 47};
for (int mark : typed) {
try {
saveMark(mark);
} catch (IllegalArgumentException e) {
System.out.println("Refused: " + e.getMessage());
}
}
}
}$ java CheckMarks 85 saved Refused: a mark must be 0 to 100, not 120 47 saved
Your own exception classکلاسی هەڵاوێردەی خۆت
For a problem that belongs to your program, write your own exception class: a class that extends Exception (extends) and hands its message to the parent with super(message) (super(...)). By custom, its name ends in Exception. Because it extends Exception and not RuntimeException, it is checked, so a method that throws it says so with throws:
بۆ کێشەیەک کە هی ، خۆت بنووسە: کە Exception extends دەکات (extends) و بە super(message) پەیامەکەی دەداتە باوکەکەی (super(...)). بە نەریت ناوەکەی بە Exception کۆتایی دێت. چونکە Exception extends دەکات نەک RuntimeException، پشکنراوە، بۆیە کە فڕێی دەدات بە throws دەیڵێت:
class MarkOutOfRangeException extends Exception {
MarkOutOfRangeException(String message) {
super(message);
}
}
public class MarkBook {
static void addMark(String name, int mark) throws MarkOutOfRangeException {
if (mark < 0 || mark > 100) {
throw new MarkOutOfRangeException(name + ": " + mark + " is not between 0 and 100");
}
System.out.println(name + ": " + mark + " saved");
}
public static void main(String[] args) throws MarkOutOfRangeException {
addMark("Aram", 85);
addMark("Shilan", 105);
}
}$ java MarkBook Aram: 85 saved Exception in thread "main" MarkOutOfRangeException: Shilan: 105 is not between 0 and 100 at MarkBook.addMark(MarkBook.java:10) at MarkBook.main(MarkBook.java:17)
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1-5
A checked exception class: extends Exception, passes the message on.
پشکنراو: Exception extends دەکات و پەیامەکە دەگوازێتەوە.
- Lineدێڕی 8
throwsis required: the exception is checked.throwsپێویستە: پشکنراوە.
The caller catches it like any other exception:
وەک هەر تر دەیگرێت:
class MarkOutOfRangeException extends Exception {
MarkOutOfRangeException(String message) {
super(message);
}
}
public class MarkBookSafe {
static void addMark(String name, int mark) throws MarkOutOfRangeException {
if (mark < 0 || mark > 100) {
throw new MarkOutOfRangeException(name + ": " + mark + " is not between 0 and 100");
}
System.out.println(name + ": " + mark + " saved");
}
public static void main(String[] args) {
String[] names = {"Aram", "Shilan", "Karwan"};
int[] marks = {85, 105, 72};
for (int i = 0; i < names.length; i++) {
try {
addMark(names[i], marks[i]);
} catch (MarkOutOfRangeException e) {
System.out.println("Not saved. " + e.getMessage());
}
}
}
}$ java MarkBookSafe Aram: 85 saved Not saved. Shilan: 105 is not between 0 and 100 Karwan: 72 saved
A safe input loopخولێکی سەلامەتی نێوخستە
Now the program from Wrong input can ask again instead of stopping. Read in a loop; when nextDouble() throws InputMismatchException, take the bad token away with next() and ask again. Locale.ROOT makes the Scanner accept 85.5 on every computer (Locale.ROOT):
ئێستا ئەو نێوخستەی هەڵە دەتوانێت لە جیاتی وەستان دووپاتە بپرسێت. لە بخوێنەوە؛ کاتێک nextDouble() InputMismatchException فڕێ دەدات، پارچە خراپەکە بە next() لاببە و دووپاتە بپرسە. Locale.ROOT وا دەکات Scanner لە هەموو کۆمپیوتەرێکدا 85.5 وەربگرێت (Locale.ROOT):
import java.util.InputMismatchException;
import java.util.Locale;
import java.util.Scanner;
public class AskMark {
public static void main(String[] args) {
Scanner input = new Scanner(System.in).useLocale(Locale.ROOT);
double mark;
while (true) {
System.out.print("Mark (0-100): ");
try {
mark = input.nextDouble();
if (mark >= 0 && mark <= 100) {
break; // a good mark: leave the loop
}
System.out.println(mark + " is outside 0-100.");
} catch (InputMismatchException e) {
String bad = input.next(); // take the bad token out of the input
System.out.println(bad + " is not a number.");
}
}
System.out.println("Saved: " + mark);
}
}$ java AskMark Mark (0-100): ninety ninety is not a number. Mark (0-100): 120 120.0 is outside 0-100. Mark (0-100): 85.5 Saved: 85.5
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 13-14
A number in range ends the loop with break.
ژمارەیەک لە نێوان 0 و 100دا بە break کۆتایی پێ دەهێنێت.
- Lineدێڕی 18
next() takes the bad token away; without it the loop never ends.
next() پارچە خراپەکە لادەبات؛ بەبێ ئەو هەرگیز کۆتایی نایەت.
Checking first with hasNextDouble() works too (Look before you take). If the input ends completely (Ctrl+D; on Windows Ctrl+Z, then Enter), nextDouble() throws NoSuchElementException, the parent of InputMismatchException, which this catch does not catch.
پشکنینی پێشوەختە بە hasNextDouble()یش کار دەکات (پێش وەرگرتن سەیر بکە). ئەگەر بە تەواوی کۆتایی بێت (Ctrl+D؛ لە Windows Ctrl+Z و پاشان Enter)، nextDouble() NoSuchElementException فڕێ دەدات، باوکی InputMismatchException، کە ئەم catchـە نایگرێت.
A safe input loopخولێکی سەلامەتی نێوخستە
Forget next(), and the loop never endsnext() لەبیر بکە و خولەکە هەرگیز کۆتایی نایەت
A failed nextDouble() does not take the bad token: it stays at the front of the input. Without input.next() in the catch block, the same ninety fails again and again. We stopped this run with Ctrl+C after one second:
nextDouble()ـی شکستخواردوو پارچە خراپەکە نابات: لە سەرەتای دەمێنێتەوە. بەبێ input.next() لە بەشی catchـدا، هەمان ninety دووپاتە و دووپاتە شکست دەهێنێت. ئەم جێبەجێکردنەمان دوای یەک چرکە بە Ctrl+C ڕاگرت:
import java.util.InputMismatchException;
import java.util.Locale;
import java.util.Scanner;
public class AskMarkBug {
public static void main(String[] args) {
Scanner input = new Scanner(System.in).useLocale(Locale.ROOT);
double mark;
while (true) {
System.out.print("Mark (0-100): ");
try {
mark = input.nextDouble();
if (mark >= 0 && mark <= 100) {
break;
}
System.out.println(mark + " is outside 0-100.");
} catch (InputMismatchException e) {
System.out.println("That is not a number."); // the bad token is still waiting
}
}
System.out.println("Saved: " + mark);
}
}$ printf 'ninety\n' | java AskMarkBug Mark (0-100): That is not a number. Mark (0-100): That is not a number. Mark (0-100): That is not a number. Mark (0-100): That is not a number. [... 206 573 more lines in one second, until Ctrl+C ...]
try-with-resources: closing things by itselfڕستەی try-with-resources: داخستنی شتەکان بە خۆی
Files, Scanners and network connections are resources: a program must close them when it is done with them. With (Java 7 and later) you open them in brackets after try, and Java closes them at the end of the block, even when an exception happens. To watch it, here is a Door class that announces when it opens and closes; it implements the interface AutoCloseable (Interfaces):
، Scannerـەکان و پەیوەندییەکانی : دەبێت دوای تەواوبوونی کارەکەی دایانبخات. بە (Java 7 و دواتر) لە ناو کەوانەدا لە دوای try دەیانکەیتەوە و Java لە کۆتایی بەشەکەدا دایاندەخات، تەنانەت کاتێک ڕوو دەدات. بۆ بینینی ئەمە، سەیری Door بکە کە ڕادەگەیەنێت کەی دەکرێتەوە و کەی دادەخرێت؛ AutoCloseable جێبەجێ دەکات (نێوبەستەکان):
class Door implements AutoCloseable {
String name;
Door(String name) {
this.name = name;
System.out.println(name + " opened");
}
@Override
public void close() {
System.out.println(name + " closed");
}
}
public class Doors {
public static void main(String[] args) {
try (Door front = new Door("Front door");
Door back = new Door("Back door")) {
System.out.println("Working inside");
System.out.println(10 / 0);
System.out.println("Never printed");
} catch (ArithmeticException e) {
System.out.println("Caught: " + e.getMessage());
} finally {
System.out.println("finally");
}
}
}$ java Doors Front door opened Back door opened Working inside Back door closed Front door closed Caught: / by zero finally
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 17-18
Two resources, opened in the brackets after try.
دوو ، لە ناو کەوانەی دوای tryـدا دەکرێنەوە.
The doors closed in reverse order, before the catch block ran. The next lesson uses this with real files (Files).
دەرگاکان بە ڕیزی پێچەوانە داخران، پێش ئەوەی بەشی catch جێبەجێ ببێت. وانەی داهاتوو ئەمە لەگەڵ ڕاستەقینە بەکار دەهێنێت (فایلەکان).
A try that opens its resources in brackets, as in try (Scanner in = new Scanner(file)) { … }, and closes them by itself at the end, even when an happens. It replaces closing files by hand in finally.
tryـێکە کە سەرچاوەکانی لە ناو کەوانەدا دەکاتەوە (try (Scanner in = new Scanner(file)) { … }) و لە کۆتاییدا خۆی دایاندەخات، تەنانەت ئەگەر ڕوو بدات. لە جیاتی داخستنی بە دەست لە finallyـدا بەکار دێت.
Do not catch everything, do not catch silentlyهەموو شتێک مەگرە، بە بێدەنگیش مەیگرە
catch (Exception e) catches every exception, including the ones that show a bug. With an empty block, the bug disappears without a word and the program gives a wrong answer:
catch (Exception e) هەموو دەگرێت، ئەوانەشی کە پیشان دەدەن. بە بەشێکی بەتاڵ، بەبێ هیچ وشەیەک ون دەبێت و وەڵامێکی هەڵە دەدات:
public class SilentBug {
public static void main(String[] args) {
int[] marks = {80, 90, 70};
int total = 0;
int average = 0;
try {
for (int i = 0; i <= marks.length; i++) { // the bug: <= goes one place too far
total += marks[i];
}
average = total / marks.length;
} catch (Exception e) {
// nothing here: the error is swallowed
}
System.out.println("Average: " + average);
}
}$ java SilentBug Average: 0
The real average is 80. Catch only what you expect, and always say what happened; the same code with a specific catch that prints the exception shows the bug at once:
تێکڕای ڕاستەقینە 80ـە. تەنیا ئەوە بگرە کە چاوەڕێی دەکەیت و هەمیشە بڵێ چی ڕوویدا؛ هەمان کۆد بە catchـێکی تایبەت کە چاپ دەکات یەکسەر پیشان دەدات:
$ java SilentBugShown Bug: java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 Average: 0
Common mistakesهەڵە باوەکان
| You wroteنووسیت | What happensچی ڕوو دەدات | Fixچارەسەر |
|---|---|---|
| A variable declared inside try, used after it لە ناو try ناساندراوە و دوای ئەو بەکار هاتووە | error: cannot find symbol symbol: variable age | Declare it before try (int age = 0;).پێش try بیناسێنە (int age = 0;). |
catch (Exception e) before a specific catchcatch (Exception e) پێش catchـێکی تایبەت | error: exception ArithmeticException has already been caught | Specific catch blocks first, Exception last.بەشە تایبەتەکانی catch سەرەتا، Exception لە کۆتاییدا. |
catch (NumberFormatException | IllegalArgumentException e) | error: Alternatives in a multi-catch statement cannot be related by subclassing | Catch only the parent type.تەنیا جۆری باوک بگرە. |
| A checked exception neither caught nor declared کە نە گیراوە نە ڕاگەیەنراوە | error: unreported exception FileNotFoundException; must be caught or declared to be thrown | try/catch, or throws on the method.try/catch، یان throws لەسەر . |
Throwing your own checked exception without throwsفڕێدانی پشکنراوی خۆت بەبێ throws | error: unreported exception MarkOutOfRangeException; must be caught or declared to be thrown | Add throws MarkOutOfRangeException.throws MarkOutOfRangeException زیاد بکە. |
catch (InputMismatchException e) without input.next()catch (InputMismatchException e) بەبێ input.next() | an endless loop | Take the bad token: input.next().پارچە خراپەکە ببە: input.next(). |
An empty catch (Exception e) { }catch (Exception e) { }ـی بەتاڵ | a wrong result and no messageئەنجامێکی هەڵە و هیچ پەیامێک | Catch specific types and report them.جۆرە تایبەتەکان بگرە و ڕایانبگەیەنە. |
| Catching an exception that is really a bugگرتنی کە لە ڕاستیدا | the bug stays hidden شاراوە دەمێنێتەوە | Fix the code, e.g. i < marks.length.کۆدەکە چاک بکە، بۆ نموونە i < marks.length. |
The first mistake in full:
یەکەم هەڵە بە تەواوی:
public class TryScope {
public static void main(String[] args) {
try {
int age = Integer.parseInt("20");
} catch (NumberFormatException e) {
System.out.println("Not a number");
}
System.out.println(age + 1);
}
}$ javac TryScope.java
TryScope.java:8: error: cannot find symbol
System.out.println(age + 1);
^
symbol: variable age
location: class TryScope
1 errorPracticeڕاهێنان
Read two whole numbers and print their quotient. Print Please type whole numbers only. for bad input and You cannot divide by zero. for a zero divisor.
دوو بخوێنەوە و ئەنجامی دابەشکردنەکەیان چاپ بکە. بۆ خراپ Please type whole numbers only. و بۆ دابەشکەری سفر You cannot divide by zero. چاپ بکە.
Show answerوەڵامەکە پیشان بدە
import java.util.InputMismatchException;
import java.util.Scanner;
public class SafeDivide {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
System.out.print("Dividend: ");
int a = input.nextInt();
System.out.print("Divisor: ");
int b = input.nextInt();
System.out.println(a + " / " + b + " = " + a / b);
} catch (InputMismatchException e) {
System.out.println("Please type whole numbers only.");
} catch (ArithmeticException e) {
System.out.println("You cannot divide by zero.");
}
}
}$ java SafeDivide Dividend: 17 Divisor: 5 17 / 5 = 3 $ java SafeDivide Dividend: 17 Divisor: 0 You cannot divide by zero. $ java SafeDivide Dividend: 17 Divisor: five Please type whole numbers only.
Both reads and the division are in one try; each catch handles one kind of problem.
هەردوو خوێندنەوەکە و دابەشکردنەکە لە یەک tryـدان؛ هەر catchـێک جۆرێک کێشە چارەسەر دەکات.
Without running it, write down what this program prints. Then compare with the answer.
بەبێ جێبەجێکردنی، بینووسە ئەم چی چاپ دەکات. پاشان لەگەڵ وەڵامەکە بەراوردی بکە.
public class Predict {
public static void main(String[] args) {
int[] numbers = {4, 0, 2};
for (int n : numbers) {
try {
System.out.println("A " + n);
System.out.println("B " + 8 / n);
} catch (ArithmeticException e) {
System.out.println("C");
} finally {
System.out.println("D");
}
}
System.out.println("E");
}
}Show answerوەڵامەکە پیشان بدە
$ java Predict A 4 B 2 D A 0 C D A 2 B 4 D E
For 0, line B throws before it prints, so C runs; D (finally) runs for every number; E comes once after the loop.
بۆ 0، دێڕی B پێش چاپکردن فڕێ دەدات، بۆیە C جێبەجێ دەبێت؛ D (finally) بۆ هەموو ژمارەیەک جێبەجێ دەبێت؛ E یەک جار دوای دێت.
Write a checked NotEnoughMoneyException and a method withdraw(int amount) that throws it when the amount is more than the balance of 50 000 dinars. Try 20 000, 40 000 and 30 000.
NotEnoughMoneyExceptionـێکی پشکنراو و withdraw(int amount) بنووسە کە فڕێی بدات کاتێک بڕەکە لە باڵانسی 50 000 دینار زیاترە. 20 000، 40 000 و 30 000 تاقی بکەرەوە.
Hintئاماژە
extends Exception, super(message), throws.
extends Exception، super(message)، throws.
Show answerوەڵامەکە پیشان بدە
class NotEnoughMoneyException extends Exception {
NotEnoughMoneyException(String message) {
super(message);
}
}
public class Bank {
static int balance = 50000;
static void withdraw(int amount) throws NotEnoughMoneyException {
if (amount > balance) {
throw new NotEnoughMoneyException("you asked for " + amount + " but have only " + balance);
}
balance -= amount;
System.out.println("Took " + amount + ", left " + balance);
}
public static void main(String[] args) {
int[] requests = {20000, 40000, 30000};
for (int amount : requests) {
try {
withdraw(amount);
} catch (NotEnoughMoneyException e) {
System.out.println("Refused: " + e.getMessage());
}
}
}
}$ java Bank Took 20000, left 30000 Refused: you asked for 40000 but have only 30000 Took 30000, left 0
Add up the whole numbers in "12 7 x 30 4.5 9", skip the rest, and count how many you skipped.
ناو "12 7 x 30 4.5 9" کۆ بکەرەوە، ئەوانی تر تێپەڕێنە و بژمێرە چەندت تێپەڕاند.
Show answerوەڵامەکە پیشان بدە
public class SumNumbers {
public static void main(String[] args) {
String line = "12 7 x 30 4.5 9";
int sum = 0;
int skipped = 0;
for (String part : line.split(" ")) {
try {
sum += Integer.parseInt(part);
} catch (NumberFormatException e) {
skipped++;
}
}
System.out.println("Sum: " + sum + ", skipped: " + skipped);
}
}$ java SumNumbers Sum: 58, skipped: 2
x and 4.5 throw NumberFormatException in parseInt; the catch counts them: 12 + 7 + 30 + 9 = 58.
x و 4.5 لە parseIntـدا NumberFormatException فڕێ دەدەن؛ catchـەکە دەیانژمێرێت: 12 + 7 + 30 + 9 = 58.
Summaryکورتە
- An exception is an object that a program throws when something goes wrong: a type, a message and a stack trace.
tryholds the risky lines; a matchingcatchhandles the exception and the program goes on; the rest of try is skipped.- Several catch blocks: specific first;
|joins unrelated types;finallyalways runs. - Checked exceptions (such as IOException) must be caught or declared with
throws; unchecked ones (RuntimeException, Error) usually mean a bug. throw new IllegalArgumentException("...")refuses a bad value; your own exception class extendsException.- A safe input loop catches, takes the bad token with
next()and asks again; try-with-resources closes resources by itself.
- کە فڕێی دەدات کاتێک شتێک هەڵە دەچێت: جۆرێک، پەیامێک و .
tryدێڕە مەترسیدارەکان هەڵدەگرێت؛catchـی گونجاو چارەسەر دەکات و بەردەوام دەبێت؛ باقیی try تێدەپەڕێنرێت.- چەند بەشێکی catch: تایبەت سەرەتا؛
|جۆری بێپەیوەندی پێکەوە دەبەستێت؛finallyهەمیشە جێبەجێ دەبێت. - (وەک IOException) دەبێت بگیرێن یان بە
throwsڕابگەیەنرێن؛ نەپشکنراوەکان (RuntimeException، Error) زۆرجار واتای دەدەن. throw new IllegalArgumentException("...")خراپ ڕەت دەکاتەوە؛ خۆتExceptionextends دەکات.- سەلامەتی دەگرێت، پارچە خراپەکە بە
next()دەبات و دووپاتە دەپرسێت؛ خۆی دادەخات.
What is the difference between throw and throws?جیاوازیی نێوان throw و throws چییە؟
throw throws one exception object now; throws in a method header says that the method may throw that type.
throw ئێستا یەک فڕێ دەدات؛ throws لە سەری دەڵێت ئەو لەوانەیە ئەو جۆرە فڕێ بدات.
When does finally not run?finally کەی جێبەجێ نابێت؟
Only if the JVM itself stops first, for example with System.exit. A caught, an uncaught exception or a return does not stop it.
تەنیا ئەگەر خودی JVM سەرەتا بوەستێت، بۆ نموونە بە System.exit. گیراو، نەگیراو یان return ڕێگری لێ ناکەن.
Why is FileNotFoundException checked but NullPointerException not?بۆچی FileNotFoundException پشکنراوە بەڵام NullPointerException نا؟
A missing file can happen in a correct program, so the caller should plan for it; a null method call is a bug to fix.
نەبوونی دەکرێت لە دروستیشدا ڕوو بدات، بۆیە دەبێت بیری لێ بکاتەوە؛ بانگکردنی لەسەر null کە دەبێت چاک بکرێت.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Files: Create, Write, Read and Deleteفایلەکان: دروستکردن، نووسین، خوێندنەوە و سڕینەوە
Related lecturesوانە پەیوەندیدارەکان
- Handling Errors with try and exceptمامەڵەکردن لەگەڵ هەڵاوێردە بە try و except
- Inheritance and Polymorphismبۆماوە و فرەشێوەیی
- Abstract Classes, Interfaces, Inner Classes and Enumsکلاسە ڕووتەکان، نێوبەستەکان، کلاسە ناوەکییەکان و ئینەمەکان
- HashMap and HashSetHashMap و HashSet
- Files: Create, Write, Read and Deleteفایلەکان: دروستکردن، نووسین، خوێندنەوە و سڕینەوە
- Recursionخۆبانگکردنەوە
- Project: A Student Marks Managerپڕۆژیلە: بەڕێوەبەری نمرەی قوتابیان
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- W3Schools: Java Exceptions (try...catch)
- W3Schools: Java Multiple Exceptions
- W3Schools: Java try-with-resources
- The Java Tutorials: The Catch or Specify Requirement
- The Java Tutorials: The finally Block
- The Java Tutorials: The try-with-resources Statement
- The Java Tutorials: How to Throw Exceptions
- The Java Tutorials: Creating Exception Classes
- The Java Tutorials: Unchecked Exceptions, the Controversy
- Java Language Specification (Java SE 17), Chapter 11: Exceptions
- Java SE 17 API: java.util.Scanner (nextDouble, InputMismatchException)
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.