A. Introduction
While the program works, there may be many errors. Some simple, predictable errors such as invalid input, divided by 0, out-of-array access, etc., we can quickly fix by adding a few if statements to validate and notify. back to the user.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token comment">// Validate chia cho 0</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> <span class="token function">println</span> <span class="token punctuation">(</span> <span class="token string">"Không thể chia cho 0"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> <span class="token function">println</span> <span class="token punctuation">(</span> a <span class="token operator">/</span> b <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Validate tuổi nhập sai</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> age <span class="token operator"><</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> <span class="token function">println</span> <span class="token punctuation">(</span> <span class="token string">"Tuổi phải lớn hơn 0"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Validate truy cập ngoài mảng</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> pos <span class="token operator">>=</span> a <span class="token punctuation">.</span> <span class="token function">length</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> <span class="token function">println</span> <span class="token punctuation">(</span> <span class="token string">"Chỉ số bạn nhập vượt ra ngoài mảng"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
However, there are many other unpredictable errors, and the number of errors is quite large so it is impossible to validate each case. Therefore, a better mechanism for handling them is called, exception handling.
An error is called as an exception. When an error occurs, the corresponding exception is “thrown”, and the exception can be “caught” for handling. That is the general mechanism, we will go into more depth in the following sections.
The advantages of exception handling are as follows:
- Able to catch all errors arising
- Classify and deal with each type of error
- Better code architecture, more concise
- Provides advanced actions such as forwarding errors to other exception handlers.
In addition to the default exceptions, programmers can define their own exceptions to use.
B. Try catch finally
1. Overview
Java provides a try catch finally
structure to “catch” exceptions thrown (by the system or by the code itself).
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// Các lệnh có thể gây lỗi</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">ExceptionA</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khi ExceptionA ném ra thì thực hiện...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">ExceptionB</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khi ExceptionB ném ra thì thực hiện...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">Exception</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Các exception còn lại được ném ra, thì thực hiện...</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token comment">// Thực hiện anh này cuối cùng</span> <span class="token punctuation">}</span> |
Looking at the code above, it is clear that the try catch finally
structure consists of 3 parts:
- The
try
part (required): the code is capable of causing errors, rather than throwing an exception, put here. catch
section (may or may not have anycatch
): eachcatch
comes with an exception type. When the exception thrown matches the type defined in whichcatch
, then the code in that catch executes. If there is no match, then the lastcatch
of the Exception class will be called (if any).- The
finally
section (can be ignored): this section, if any, will always be called at the last, even if the return method or break (unless the program is stopped).
Note, if written in a form without catch
, there must be finally
.
1 2 3 4 5 6 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> |
2. Flow
Following is the flow of the try catch finally
block:
- The code in
try
is executed - If there are no errors, then jump to
finally
(if any) and execute, then done. - If a statement in
try
throws an error, then thetry
stops immediately (stops running), and jumps to the correspondingcatch
block (just one block). - The
catch
block corresponding to the exception class thrown will be executed, then jump tofinally
(if any), finally finished.
Super simple always, just remember to try
execute the code, if you have an error then jump into the corresponding catch
, otherwise go ahead. The finally
block (if any) is always run last, regardless of the error result.
C. Throw
1. Throw keyword
When the method executes an error, it can throw an exception, to notify that it has an error and the result fails.
Throwing an exception is done with the throw keyword (no s). And throw an exception object, so we usually use throw new Exception
as follows.
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">class</span> <span class="token class-name">TinhToan</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">double</span> <span class="token function">chia</span> <span class="token punctuation">(</span> <span class="token keyword">double</span> a <span class="token punctuation">,</span> <span class="token keyword">double</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token comment">// Ném ra lỗi với message</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span> <span class="token punctuation">(</span> <span class="token string">"Không thể chia cho 0"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">return</span> a <span class="token operator">/</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
2. Throws keyword
The chia()
method can throw an exception, or it has a throw
statement inside it, so we need to mark it as a Throwable method. The code modifies the declaration a bit as follows.
1 2 3 4 5 | <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">double</span> <span class="token function">chia</span> <span class="token punctuation">(</span> <span class="token keyword">double</span> a <span class="token punctuation">,</span> <span class="token keyword">double</span> b <span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> |
The keyword throws
(note the s
) behind the method’s params list, along with a list of exception classes, will indicate that this method will be able to throw one of the specified exceptions. For example.
1 2 3 4 5 | <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">doSomeThing</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">FileNotFoundException</span> <span class="token punctuation">,</span> <span class="token class-name">NetworkErrorException</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> |
The above doSomeThing()
method will throw one of the two exceptions, FileNotFoundException
or NetworkErrorException
.
The exception thrown can be an existing exception class, or defined by the programmer.
D. Exception class
1. Exception & error
Exception represents an error that occurs when the program operates. In essence, an exception is just an object of the Exception class or inherits from it.
There are 2 types of exceptions:
- Checked: exceptions are not RuntimeException and Error. Tested at compile time.
- Unchecked: exception inherits from RuntimeException. Not checked at compile time but at runtime.
In addition to the exception, there are errors, the difference is that the error is usually more serious, and should not be captured or handled. The program should be stopped to ensure safety.
Both Exception and Error inherit from Throwable class. See the diagram below for a better understanding.
2. Exception members
There are two commonly used methods of exception object. The first is getMessage()
to get the message string of the exception.
1 2 3 | <span class="token class-name">String</span> <span class="token function">getMessage</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">printStackTrace</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The second method is printStackTrace()
, used to print out the call stack, which is simply understood as the order of the statements leading to the exception (this order goes backwards, from the faulty command back).
3. My exception
From the above base exceptions, you can create your own custom exceptions by inheriting the above Exception classes and overriding the constructor as follows.
1 2 3 4 5 6 7 8 | <span class="token keyword">class</span> <span class="token class-name">MyException</span> <span class="token keyword">extends</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">public</span> <span class="token class-name">MyException</span> <span class="token punctuation">(</span> <span class="token class-name">String</span> message <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">(</span> message <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
E. Assertion
Another good debugging technique is assertion. Basically, we assign an expression (variable, constant, …) a condition that we are sure of. When running to that location, if the condition returns false, the code is false. An error with the name AssertionError was thrown.
For example the following code checks whether the sum()
function is working properly or not.
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">sum</span> <span class="token punctuation">(</span> <span class="token keyword">int</span> a <span class="token punctuation">,</span> <span class="token keyword">int</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Mình cố ý làm sai</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token class-name">String</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> args <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">assert</span> <span class="token function">sum</span> <span class="token punctuation">(</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">5</span> <span class="token operator">:</span> <span class="token string">"Hàm sum() có bug"</span> <span class="token punctuation">;</span> <span class="token comment">// Điều kiện trên nếu code đúng sẽ luôn đúng, vì 2 + 3 = 5</span> <span class="token comment">// nếu khi chạy điều kiện trên sai, thì chứng tỏ code sai</span> <span class="token punctuation">}</span> |
When running the above code, the assert condition result is false, so the problem is inferred and the result is an exception as follows.
1 2 3 | Exception in thread "main" java.lang.AssertionError: Hàm sum() có bug; |
Note that assertion is not enabled by default. To enable it, add the -ea
(enable assertion) flag to the java command at runtime.
1 2 | java -ea Program |
Most of the IDEs for java support this parameter, either in the form of flags attached or directly into the settings. You can learn more about configuring specific IDEs on google.