Java exception handling -- Java exceptions

Posted by keystroke on Mon, 20 Dec 2021 04:02:03 +0100

Summary

  • Java uses exceptions to represent errors, and catches exceptions through try... catch;
  • The Java exception is class and inherits from Throwable;
  • Error is a serious error that does not need to be captured, and Exception is a manageable error that should be captured;
  • RuntimeException does not need to be forcibly captured, non runtimeException (Checked Exception) needs to be forcibly captured, or declared with throws;
  • It is not recommended to catch exceptions without any processing.

Java has a built-in exception handling mechanism, which always uses exceptions to represent errors.

An exception is a class, so it carries type information. Exceptions can be thrown anywhere, but they only need to be caught at the upper level, which is separated from method calls:

try {
    String s = processFile("C:\\test.txt");
    // ok:
} catch (FileNotFoundException e) {
    // file not found:
} catch (SecurityException e) {
    // no read permission:
} catch (IOException e) {
    // io error:
} catch (Exception e) {
    // other error:
}

Because the Java exception is class, its inheritance relationship is as follows:

From the inheritance relationship, we can see that throwable is the root of the Exception system, which inherits from Object. Throwable has two systems: error and Exception. Error indicates a serious error, and the program is generally unable to do anything about it, for example:

  • OutOfMemoryError: out of memory
  • NoClassDefFoundError: a Class could not be loaded
  • StackOverflowError: stack overflow

An Exception is a runtime error that can be caught and processed.

Some exceptions are part of the application's logical handling and should be caught and handled. For example:

  • NumberFormatException: malformed numeric type
  • FileNotFoundException: file not found
  • SocketException: failed to read the network

There are also some exceptions caused by incorrect programming of program logic. The program itself should be repaired. For example:

  • NullPointerException: call a method or field on a null object
  • IndexOutOfBoundsException: array index out of bounds

Exception s fall into two categories:

  • RuntimeException and its subclasses;
  • Non RuntimeException (including IOException, reflective operationexception, etc.)

Java stipulates:

  • Exceptions that must be caught include Exception and its subclasses, but do not include RuntimeException and its subclasses. This type of Exception is called Checked Exception.
  • Exceptions that do not need to be caught include Error and its subclasses, RuntimeException and its subclasses.

Note: the compiler does not make mandatory capture requirements for RuntimeException and its subclasses, which does not mean that the application itself should not capture and process RuntimeException. Whether it needs to be captured, and analyze the specific problems.

Catch exception

Catch Exception using try Catch statement, put the code with possible exceptions into try {...} And then catch the corresponding Exception and its subclasses:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        byte[] bs = toGBK("chinese");
        System.out.println(Arrays.toString(bs)); // [-42, -48, -50, -60]
    }

    static byte[] toGBK(String s) {
        try {
            // Convert String to byte []:
            return s.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            // If the system does not support GBK encoding, an unsupported encoding exception is caught:
            System.out.println(e); // Print exception information
            return s.getBytes(); // Try using the default encoding
        }
    }
}

If we do not capture unsupported encoding exception, the compilation will fail:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        byte[] bs = toGBK("chinese");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
        return s.getBytes("GBK");
    }
}

The compiler will report an error. The error message is similar to: unreported exception UnsupportedEncodingException; must be caught or declared to be thrown, and accurately indicate that the statement to be captured is return s.getBytes("GBK");. This means that checked exceptions such as UnsupportedEncodingException must be captured.

This is because string The GetBytes (string) method definition is:

public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
    ...
}

When defining a method, throw XXX is used to represent the types of exceptions that the method may throw. When calling, the caller must force these exceptions to be caught, otherwise the compiler will report an error.

In the togbk () method, because string. Is called For the GetBytes (string) method, unsupported encoding exception must be caught. Instead of capturing it, we can use throws at the method definition to indicate that the toGBK() method may throw UnsupportedEncodingException, so that the toGBK() method can pass the compiler check:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        byte[] bs = toGBK("chinese");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
        return s.getBytes("GBK");
    }
}

The above code will still get compilation errors, but this time, the compiler does not prompt to call return s.getBytes("GBK"); But byte[] bs = toGBK("Chinese");. Because in the main() method, calling toGBK() does not capture the UnsupportedEncodingException that it may declare.

The repair method is to catch the exception in the main() method and handle it:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        try {
            byte[] bs = toGBK("chinese");
            System.out.println(Arrays.toString(bs));
        } catch (UnsupportedEncodingException e) {
            System.out.println(e);
        }
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
        // Convert String to byte []:
        return s.getBytes("GBK");
    }
}

It can be seen that as long as the Checked Exception declared by the method is not captured at the call layer, it must also be captured at a higher call layer.

All uncaught exceptions must also be caught in the main() method in the end, and try will not be omitted. This is guaranteed by the compiler. The main() method is also the last chance to catch an Exception.

If it is test code, the above writing is a little troublesome. If you don't want to write any try code, you can directly define the main() method as throws Exception:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) throws Exception {
        byte[] bs = toGBK("chinese");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
        // Convert String to byte []:
        return s.getBytes("GBK");
    }
}

Because the main() method declares that exceptions may be thrown, it also declares that all exceptions may be thrown, so there is no need to catch them internally. The price is that once an Exception occurs, the program will exit immediately.

Others like to "digest" exceptions inside toGBK():

static byte[] toGBK(String s) {
    try {
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
        // Do nothing
    }
    return null;

This method of not processing after capture is very bad. Even if you can't do anything, you should record the exception first:

static byte[] toGBK(String s) {
    try {
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
        // Write it down first:
        e.printStackTrace();
    }
    return null;

All exceptions can call the printStackTrace() method to print the exception stack, which is a simple and useful method to print exceptions quickly.

Topics: Java Exception