11th Chapter exception, assertion, log, debug
- Handling Errors
- Catching exceptions
- Tips for using exception mechanisms
- Using assertions
- Log
- Test technique
- GUI Programming Troubleshooting Tips
- Using the debugger
11.1 Handling Errors 11.1.1 Exception classification
- are inherited from the Throwable class
Divided into error and exception
The Java language specification derives from all exceptions of the error class or RuntimeException class called an unchecked (unchecked) exception, and all other exceptions are referred to as checked (checked) exceptions.
11.1.2 declaration has checked for exceptions
Here are four ways to write your own method. Need to throw an exception
- Invokes a method that throws a checked exception. For example, the FileInputStream constructor
- The program runs and finds an error, and throws a checked exception with the throw statement
- Internal errors with Java virtual machines and run-time libraries
For Java methods that may be used by others, with exception specification (Exception specification), this method may throw an exception at the header of the method, assuming that there are multiple comma-separated
class MyAnimation{ ... public Image loadImage(String s) throws IOException FileNotFoundException { ... }}
On the method of subclass overriding superclass that piece didn't read.
11.1.3 How to throw an exception
- Find a suitable exception class
- In the method declaration
- Create an object of this class
Throws an Object
String readData(Scanner in) thros EOFException{ ... while(...) { if(!in.hasNext()) { if(n<len) throw new EOFException(); } } ... return S;}//还能含有一个字符串參数的构造器String girpe="Content-length " +len +",Recived" + n ;throw new EOFException(girpe);
11.1.4 Creating exception classes
Create a class that derives from exception, or a class that derives from the exception subclass.
It is generally necessary to define two constructors, one is the default, and the other is a constructor with specific descriptive information (the ToString method of the superclass Throwable will print the specific information)
class FileFormatException extends IOException{ public FileFormatException() {} public FileFormatException(String gripe) { super(gripe); }}
String getMessage()
Can obtain the Throwable object specific descriptive narrative information, namely constructs the string which throws in.
11.2 Catching exceptions
- Assuming the exception is not captured, the program will stop running
Assuming you want to catch an exception, here's the simplest Try/catch statement block
try{ code more code more code}catch (ExceptionType e){ handler for this type }
Assume that whatever code in a try statement block throws the exception that is described in the catch clause. So
- Skip the remaining try statements
- The processor code in the CATCH clause will be run
Here's a simple example.
public void read(String filename){ try { InputStrem in = new FileInputStream(filename); int b; while((b!=in.read())!=-1) { process input; } } catch (IOException exception) { exception.printStackTrace(); }}
For the above code
Usually the best choice is not to do anything, but to pass the exception to the caller.
Suppose the Read method has an error, let the caller of the Read method worry!
Assuming that such a process is used, it is necessary to declare that this method may throw a IOException
public void read(String filename) throws IOException{ InputStrem in = new FileInputStream(filename); int b; while((b!=in.read())!=-1) { process input; }}
- The throws specifier in a method that does not agree with subclasses overriding a superclass exceeds the exception range listed by the superclass. Suppose there is something that does not belong, cannot be throws, can only capture and deal with itself
11.2.1 Capturing multiple exceptions
Basic statement
try {}catch (FileNotFoundException e){}catch (UnknownHostException e){}catch (IOException e){}
Suppose you need to get specific information
e.getMessage() //具体错误信息e.getClass().getName() //异常对象的实际类型
Combine catch statements as if they were handled
try{ code..}catch (FileNotFoundException | UnknownHostException e){}
11.2.2 again throws an exception or an exception chain
The basic method of catching the exception to be thrown again
try{ access the database}catch (SQLException e){ throw new ServletException("database error: "+e.getMessage());}
Another way to not lose the original exception
try{ access the database}catch (SQLException e){ Throwable se=new ServletException("database error"); se.initCause(e); throw se;}
When an exception is caught. Can get the original exception again with the following statement:
Throwable e = se.getCause();
The book strongly recommends such packaging methods, without losing the details of the original anomaly.
Sometimes it's just a record exception.
try{ access the database}catch (SQLException e){ logger.log(level,message,e); throw e;}
11.2.3 finaly clause
The basic syntax
try{}catch(Exception e){}finally{ in.close();}
Regardless of whether you throw an exception in a try or throw an exception in a catch, Finall always runs
The use of Try/catch and try/finally statement blocks is strongly used alone, rather than the basic syntax. For example, the following:
InputStream in= ... ;try { try { code that might throw exceptions } finally { in.close(); }}catch(IOException e){ show error message}
The inner try has only one responsibility to confirm that the input stream is closed. The outer try is used to ensure that errors are reported.
Note : When finally
and catch
including return
the statement, it will run finally
return
.
Note : finally
It is also possible to throw an exception that causes catch
the exception to be thrown to be overwritten
11.2.4 a try statement with a resource
If the resource implements the AutoCloseable
/ Closeable
interface class. Ability to take advantage of try
statements with resources
try(Resource res=...){ work with res}
When try exits, it calls Res.close () on its own initiative. A typical example is given below.
try (Scanner in=new Scanner(new FileInputStream("/usr/share/dict/words"))){ while (in.hasNext()) System.out.println(in.next());}
You can also specify multiple resources, such as:
try (Scanner in = new Scanner(new FileInputStream("/usr/share/dict/words")), PrintWriter out=new PrintWriter("out.txt")){ while(in.hasNext()) out.println(in.next().toUpperCase());}
The assumption .close()
also throws an exception, but does not overwrite the original thrown exception, but is suppressed. Suppose you want to know what these suppressed anomalies can be through the getsuppressed method.
11.2.5 parsing Stack trace elements
A stack trace ( stack trace
) is a list of method invocation procedures.
The more flexible way is to use getStackTrace()
.
It will get an array of Stacktraceelement objects.
Like what:
Throwable t = new Throwable();StackTraceElement[] frames = t.getStackTrace();for(StackTraceElement f : frames) System.out.println(f); 输出factorial(4):StackTraceTest.factorial(StackTraceTest.java:8)StackTraceTest.factorial(StackTraceTest.java:14)StackTraceTest.factorial(StackTraceTest.java:14)StackTraceTest.factorial(StackTraceTest.java:14)StackTraceTest.factorial(StackTraceTest.java:14)StackTraceTest.factorial(StackTrcaceTest.java:14)StackTraceTest.main(StackTraceTest.java:23)
Can get the file name, class name. Line number of the code that is currently running
A static Thread.getallstacktrace method that obtains a stack trace of all threads. Here is a sample
Map<Thread,StackTraceElement[]> map=Thread.getAllStackTraces();for(Thread t : map.keySet()){ StackTraceElement[] frames=map.get(t); for(StackTraceElement f : frames) System.out.println(f);}
11.3 Techniques for using exception mechanisms
- Exceptions are not a substitute for a simple test.
- Do not refine the exception excessively
- Using exception hierarchies
- Don't be shy about passing exceptions. Sometimes you are a class designer and should be determined by the user about the exception
11.4 Using assertions
Assertkeyword has two forms of expression
assert 条件;//为false ,抛出一个AssertionError异常assert 条件:表达式;//表达式传入异常作为一个消息字符串。
11.4.1 Enable or disable assertions
- -ea or-enableassertions enabled, default is disabled
- Also can start the assertion of some packages, also can Jin Yong part of the assertion of the package
11.4.2 using assertion completion parameter check
- An assertion failure is a fatal, unrecoverable error.
- Assertion checking is only used for development and test phase.
- Assertions are a tactical tool used in the test and debug phases, and logging is a strategy tool that can be used throughout the life cycle of a program.
11.5 Logging 11.5.1 Basic Log
The log system manages a default logger named Logger.global, which can be replaced with System.out and log information is logged via the info method
Logger.getGlobal().info("File->Open menu item selected");//print //三月 15, 2016 7:33:25 下午 log main //信息: File->Open menu item selected
Self-actively includes time, called Class name and method.
Logger.gelGlobal().setLevel(Level.OFF)
To cancel all logs
11.5.2 Advanced Log
Call the GetLogger method to create or retrieve a logger
Logger myLogger= Logger.getLogger("log.zhouyong");
Suppose you set the log level for the log. Then its child logger will inherit this property as well.
There's a little bit of 7 logger levels
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- Finer
- FINEST
In the default case. Only the first three levels are recorded. Other levels can also be set. Like what:
logger.setLevel(Level.FINE)
Today, fine and higher-level records can be recorded
Also able to use Level.all to turn all Level.off off all
There are several ways to record
logger.warning(message);logger.fine(message);//同一时候还能够用log方法指定级别logger.log(Level.FINE,message);
The general use of Config,fine and other records to help diagnose, but for the program ape does not have much meaning debugging information.
The default logging will show the include log call class name and method name. However, assuming that the virtual machine is optimized, it may not be able to get accurate information. At this point the Logp method is required to obtain the exact location of the calling class and method, such as the following:
void logp(level l,String className,String methodName,String message)
Here are some other ways to track the running flow
void entering(String className,String methodName)void entering(String className,String methodName,Object param)void entering(String className,String methodName,Object[] params)void exiting(String className,String methodName)void exiting(String className,String methodName,Object result)
Like what:
不知道有什么用。。
The most common use of logging is to record unexpected exceptions. There are two ways to use it.
void throwing(String className,String methodName,Throwable t)void log(Level l,String message ,Throwable t)
The typical use is:
if(...){ IOExcption exception = new IOException("..."); logger.throwing("com.my","read",exception); throw exception; //FINER级别}
And also
try{ ...}catch (IOException e){ Logger.getLogger("...").log(Level.WARNING,"Reading image",e);}
11.5.3 Change Log Manager configuration
By default, the configuration file is stored in:
e/lib/logging.properties
To use your own configuration file, you need to
java -Djava.util.logging.config.file=configFile MainClass
Change the default logging level
.level=INFO
You can also change your logging level
Com.mycompany.myapp.level=fine
The console also has an output level limit
Java.util.logging.consolehandler.level=fine
Log properties are handled by the Java.util.logging.LogManager class. See the API in detail
11.5.4 localization
- I don't know much about it later.
11.5.5 processor
The logger sends the records to the parent processor first, and finally the processor has one ConsoleHandle
.
For a log record to be logged, it must have a higher logging level than the logger and processor thresholds.
To log the fine level. You must change the default logging level and processor level in the configuration file.
In addition , you can bypass the configuration file and install your own processor.
Console processor
Logger logger=Logger.getLogger("log.zhouyong");logger.setLevel(Level.FINE);logger.setUseParentHandlers(false);Handler handler = new ConsoleHandler();handler.setLevel(Level.FINE);logger.addHandler(handler);logger.log(Level.FINE,"dddd");
By default, the logger sends records to its own processor and parent processor.
The parent processor is the generic default processor, but since we have our own processor, we can turn the parent processor off. Lest the console send two records.
To send a log to another location, you need a different processor.
- Filehandler collecting logs from files
- Sockethandler. Send to a specific host and port
Filehandler
FileHandler handler = new FileHandler();handler.setLevel(Level.FINE);logger.addHandler(handler);logger.log(Level.FINE,"dddd");
The file is under user. The format is XML. For example, the following:
<?xml version="1.0" encoding="GBK" standalone="no"?
><!DOCTYPE log SYSTEM "logger.dtd"><log><record> <date>2016-03-15T23:40:17</date> <millis>1458056417956</millis> <sequence>0</sequence> <logger>log.zhouyong</logger> <level>FINE</level> <class>log</class> <method>main</method> <thread>1</thread> <message>dddd</message></record></log>
- There are a lot of other complicated ways to deal with the requirements that you want.
11.5.6 Filter
- Each logger and processor can have an optional filter to complete the additional filtering
Filter
You can define your own filters by implementing interfaces and defining the following methods
boolean isLoggable(LogRecord record)
setFilter
method to install the filter
11.5.7 Formatter
ConsoleHandler类
and FileHandler
the ability to generate text or XML-formatted log records. But you can also define your own format.
By inheriting Formatter
the class and overriding the method.
String format(LogRecord record)
Can format the recorded information according to its own intention and return the result string.
The formatter is then installed into the processor using the Setformatter method.
11.5.8 Log Record description
[Core Java Learning notes] [11th chapter Exception Assertion Log Debugging]