Chapter 7 exceptions, assertions, and logs

Posted by RyanJones on Wed, 09 Feb 2022 01:54:14 +0100

Chapter 7 exceptions, assertions, and logs

7.1 handling errors

7.1.1 anomaly classification

The following figure is a simplified diagram of the Java exception hierarchy

  • Error
    • Describes the internal errors and resource exhaustion errors of the Java runtime system
  • Exception
    • RuntimeException
      • Bad type conversion.
      • Array access out of bounds i
      • Access null pointer
    • Other exceptions
      • An attempt was made to read data after the end of the file
      • An attempt was made to open a file that does not exist
      • An attempt was made to find a Class object based on the given string, and the Class represented by this string does not exist

If RuntimeException occurs, it must be your problem

The Java language specification calls all exceptions derived from the Error class or RuntimeException class as unchecked exceptions, and all other exceptions as checked exceptions

7.1.2 declare the checked exception

If an exception may occur in a method, the exception that may be thrown should be declared in the header of the method, such as

public FileInputStream(String name) throws FileNotFoundException

However, not all possible exceptions should be declared. Generally, exceptions should be thrown in the following four cases:

  1. Call a method that throws the checked exception
  2. Errors found during program operation
  3. If an error occurs in the program, for example, a[-l]=0 will throw a non checked exception such as ArraylndexOutOffloundsException
  4. Internal error in Java virtual machine and runtime library

If a method is likely to throw multiple checked exception types, all exception classes must be listed in the header of the method. Each exception class is separated by commas

class MyAnimation
{
	// ...
    public Image loadImage(String s) throws FileNotFoundException, EOFException
    {
        // ...
    }
}

If the superclass method does not throw any checked exceptions, the class cannot throw any checked exceptions

7.1.3 how to throw an exception

There are two ways to throw an exception

// method 1
throw new EOFException();
// method 2
EOFException e = new EOFException();
throw e;

7.1.4 create exception class

You may encounter problems that cannot be fully described by the standard exception class. In this case, it is natural to create your own exception class.

Define a class derived from Exception or a class derived from Exception. The defined class should contain two constructors:

  • One is the default constructor
  • The other is a constructor with detailed description
class FileFormatException extends IOException
{
    public FileFormatException() {}
    public FileFormatException(String gripe)
    {
        super(gripe);
    }
}

7.2 catching exceptions

After throwing an exception? Of course, you also need to catch exceptions

7.2.1 catching exceptions

If an exception is not caught anywhere when it occurs, the program will terminate execution and print the exception information on the console, including the type of exception and the content of the stack

For the graphical interface program, after catching the exception, the heap information will also be printed, but the program will return to the processing loop of the user interface

To catch exceptions, you need to set the try/catch statement block

try
{
    //code  
}
catch(ExceptionType e)
{
    // handler for this type
}

Execution order of try/catch:

  • Any code in the try statement block throws an exception class described in the catch clause
    • The program will skip the rest of the try statement block
    • The program will execute the processor code in the catch clause
  • If the code in the try statement block does not throw any exceptions, the program will skip the catch clause
  • If an exception type is thrown that is not declared in the catch clause, the method will exit immediately

If you write a method that overrides the superclass and the method does not throw an exception (such as paintcomponent in JComponent), the method must catch every checked exception in the method code. Exceptions beyond the range of exception classes listed by superclass methods are not allowed in the throws specifier of subclasses.

7.2.2 capture multiple exceptions

Multiple exception types can be caught in a try statement block. To get more information about the object, try using e.getMessage() or e.getclass() Getname () gets the actual type of the exception object, and the same catch clause can catch multiple exception types

try
{
    // code that might throw exceptions
}
catch(FileNotFoundException | UnKnownHostException e)
{
    // emergency action for missing files and unknown hosts
}
catch(IOException e)
{
    // emergency action for all other I/O problems
}
  • When multiple exceptions are caught, the exception variable is implied as the final variable
  • Getting multiple exceptions will not only make your code look simpler, but also more efficient. The generated bytecode contains only one code block corresponding to the common 1 clause

7.2.3 throw exception and exception chain again

You can throw an exception in the catch clause. The purpose of this is to change the type of exception, or another way is to set the original exception as the reason of the new exception

try
{
    //access the database
}
catch(SQLException e)
{
    Throwable se = new ServletException("database error");
    se.initCause(e);
    throw se;
}

7.2.4 finally clause

The code in the finally clause is executed whether or not an exception is caught

try
{
    // code that might throw exceptions
}
catch(IOException e)
{
    // emergency action for all other I/O problems
}
finally
{
	in.close();
}

When the finally clause contains a return statement, an unexpected result will appear „ suppose you use the return statement to exit from the try statement block. The contents of the finally clause will be executed before the method returns. If there is also a return statement in the finally clause, the return value will overwrite the original return value

public static int f(int n)
{
    try
    {
        int r = n * n;
        return r;
    }
    finally
    {
        if(n == 2) return 0;
    }
}

If f(2) is called, the evaluation result of the try statement block is r=4, and the return statement is executed. However, before the method actually returns, the finally clause must be executed. The finally clause will cause the method to return 0, which overrides the original return value of 4

7.2.5 try statement with resources

General form of resource release

// open a resource
try
{
    // work with the resource
}
finally
{
    // close the resource
}

Assuming that the resource belongs to a class that implements the autoclosable interface, Java se 7 provides a useful shortcut for this code pattern

void close() throws Exception

try(Resource res = ...)
{
    wotk with res
}

The above code is the simplest form of try with resources. After the try block exits, res.close() will be called automatically

7.2.6 analyzing stack trace elements

  • Stack trace is a list of method calling procedures, which contains the specific location of method calls during program execution

  • You can call the printStackTrace method of Throwable class to access the text description information of stack track

    Throwable t = new Throwable();
    StringWriter out = new StringWriter();
    t.printStackTrace(new PrintWriter(out));
    String description = out.toString();
    
  • A more flexible method is to use the getStackTrace method, which will get an array of StackTraceElement objects

    Throwable t = new Throwable();
    StackTraceElement[] frames = t.getStackTrace();
    for(StackTraceElement frame: frames)
        // analyze frame
    
  • Static thread Getallstacktrace method, which can generate stack tracks of all threads

    Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
    for(Thread t: map.keySet())
    {
        StackTraceElement[] frames = map.get(t);
        // analyze
    }
    

7.3 skills of using exception mechanism

  1. Exception handling is no substitute for simple testing

    It takes much more time to catch exceptions than to execute simple tests

  2. Don't refine exceptions too much

  3. Using exception hierarchy

  4. Don't suppress exceptions

  5. When detecting errors, "harsh" is better than laissez faire

  6. Don't be shy about passing exceptions

7.4 using assertions

7.4.1 concept of assertion

The assertion mechanism allows some check statements to be inserted into the code during testing. When the code is released, these inserted check statements will be automatically removed

assert condition;

assert condition: expression;

The expression will be passed into the constructor of AssertionError and converted into a message string

7.4.2 enable and disable assertions

By default, assertions are disabled. It can be enabled with the - enableassertions or - ea option when running the program

java -enableassertions MyApp

It is not necessary to recompile the program when assertions are enabled or disabled. Enabling or disabling assertions is a feature of the classloader

7.4.3 using assertions to complete parameter checking

When to use assertions:

  • Assertion failure is a fatal and unrecoverable error
  • Assertion detection is only used in the development and test phases

Topics: Java Back-end