Справяне с грешки в Java
All Java errors are handled as exceptions. Exceptions extend the base class, Exception. You might have seen the try and catch block used. This is a way to "catch" exceptions - essentially, correct them.
Life isn't perfect. Much as we'd like to think otherwise, sometimes we encounter exceptional behavior. Things like missing files, badly formatted data to be parsed, and operations on null
things are just a few of the many exceptions you may meet in your programming career. When these things happen, the JVM throws a temper tantrum, or (more technically) throws an exception.
If a method might throw an exception, it has to declare that exception in its header. (Note that just because a method declares an exception doesn't mean that it will throw it; just that it might.) If you use a risky method, you have to tell the compiler what to do in case something bad happens. This is called catching the exception.
Try and Catch
[edit]Try and catch blocks are really simple. The basic syntax follows. For this example, we'll try to read a file that doesn't exist. (The details of file I/O comes later in this tutorial; the important part is just that this code is risky: if the file "myfile.txt" doesn't exist, the FileReader
constructor throws a FileNotFoundException
.)
System.out.println("Ready? Go!"); try { System.out.println("I think I can..."); FileReader reader = new FileReader("myfile.txt"); System.out.println("I knew I could!"); } catch(FileNotFoundException ex) { System.out.println("File not found."); } System.out.println("All done.");
Whenever a method of some class could throw an exception, you should use the try/catch block. The compiler tries to run the code in the try
block. If any statement in the block throws an exception, the JVM jumps to the appropriate catch
block; that is, the catch
block that names the thrown exception. If no code in the try
block throws an exception, the catch
block is skipped.
Consider the code above. If the named file exists, the try
blocks runs to completion, and the catch
block is skipped. The output is
Ready? Go! I think I can... I knew I could! All done.
If the file does not exist, however, the try
block halts at the FileReader
constructor, and the catch
block is run:
Ready? Go! I think I can... File not found. All done.
Exercise 1: Make a program that asks for an integer in a JOptionPane Input Message (you can use JOptionPane.showInputDialog(null, "TEXTHERE");). Then, it formats it into an integer and prints the number one above it. If the integer is not valid, it says "Bad Integer." Name your class StrToInt.
Answer:
public class StrToInt { public static void main(String args[]) { try { String s=JOptionPane.showInputDialog(null, "Enter a number"); int i1 = Integer.parseInt(s); System.out.println(i1+1); } catch(NumberFormatException nfe) { System.out.println("Bad Number"); } } }
Exceptions in the API
[edit]Cool, but how do you know if an exception could throw an exception? The hard way is when the compiler complains that you didn't properly handle the method. The easy way involves the API documentation. The standard API documentation on the Java site begins a method's documentation with its header: the access level, return type, method name, parameters, miscellaneous modifiers, and the declared exceptions. For example, the readLine
method in class java.io.BufferedReader
throws IOException
. Its header looks like this:
public String readLine() throws IOException
RuntimeException
s
[edit]-- Add text here --
Try/Catch/Finally Blocks
[edit]This is a continuation of try/catch blocks. The finally statement is always executed. It is the place where you can tidy things up, rather then duplicating code. But, you should be aware when it is executed in the flow of control.
First of all, here is where you put it:
try { ... } catch(SomeException se) { ... } finally{ ... }
Now, when it executes: it occurs before the catch statement (if the catch statement happens) or after the try statement. Essentially it happens here and here:
try { ... FINALLY CODE EXECUTED } catch(Exception e) { FINALLY CODE EXECUTED ... }
The (arguably) best part about the finally block is that it can execute code "after" returning in a method. As a very basic (and bad, but working) example, this means you could have:
public class MagicNumbers{ int aMagicNumber = 3; public MagicNumbers(){ } public int getOldAndChangeTo(int newNumber){ try { return aMagicNumber; } finally { aMagicNumber = newNumber; } } public static void main(String[] args){ MagicNumbers theNumbers = new MagicNumbers(); // Create an instance of the MagicNumbers class System.out.println(theNumbers.getOldAndChangeTo(8)); //The number 3 will have just printed to the screen and "aMagicNumber" will have changed to 8 System.out.println(theNumbers.getOldAndChangeTo(0)); //The number 8 will have just printed to the screen and "aMagicNumber" will have changed to 0 } }
Simple, eh?