Explain the rules regarding exceptions from the perspective of API creators and API users. API (Application Program Interface) assumes public method.
A book written in the Java 6 era, a little old, but a good book. The rules are written with an emphasis on clarity and conciseness.
Exception handling is to suspend (stop) the current processing and perform another processing when some abnormality occurs while the program is executing a certain processing. The abnormality that occurs at that time is called an exception.
Wikipedia Exception Handling Quote
Checked Exception: An exception that must be caught or thrown by the caller. An exception that is not a run-time exception.
Runtime Exception: An exception that the caller does not have to check. Inherit java.lang.RuntimeException
.
Exception type structure
java.lang.Exception
- IOException
- SQLException
- RuntimeException
- NullPointerException
- IllegalArgumentException
When using the constructor of java.io.FileReader
.
throws
defines the Exception that the method throws.
public FileReader(File file) throws FileNotFoundException
What to do when calling a method that throws an Exception
try {
FileReader fr = new FileReader(file);
} catch(FileNotFoundException e) {
//...
}
throws
in method declarations.private void read(File file) throws FileNotFoundException {
FileReader fr = new FileReader(file);
}
Use the throw
reserved word.
private void read(File file) {
if (file == null) {
throw new NullPointerException("file is null");
}
}
Checked exceptions must declare throws
in the method.
No run-time exceptions (such as NullPointerException) required.
A description of checked exceptions and run-time exceptions will be given later.
Available from Java 7.
For Java 6 or earlier
catch (IOException ex) {
logger.log(ex);
throw ex;
} catch (SQLException ex) {
logger.log(ex);
throw ex;
}
For Java 7 or later
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/catch-multiple.html Reference
Ignoring is the worst. Absolutely no.
try {
...
} catch(SomeException e) {}
An empty catch block does not achieve the purpose of the exception. Its purpose is to "force the handling of exceptional conditions".
Personal view
log.error ("~ failure", e);
What's wrong? An exception is used to determine the end of the loop.
int[] array = {1,2,3,4,5};
try {
int i=0;
while(true) {
System.out.println(array[i++]);
//Other processing
}
} catch(ArrayIndexOutOfBoundsException e) {}
Exceptions, as the name implies, should only be used for exceptional conditions. It should never be used for normal control flow.
I can catch it with ʻIOException, but I catch it with
java.lang.Exception`.
File file = new File("/tmp/sample.txt");
try {
FileReader fr = new FileReader(file);
} catch(Exception e) { //IOException is appropriate
//...
}
problem
java.lang.Exception
Framework processing etc. If you don't stop the Exception propagation somewhere, your system (eg Tomcat) will go down.
The following source is where the business logic is called within the Terasoluna framework.
java:jp.terasoluna.fw.ex.aop.log.BLogicLogInterceptor.java
public Object invoke(MethodInvocation invocation) throws Throwable {
//...
try {
//Execution of business logic
result = invocation.proceed();
} catch (Throwable e) {
if (checkException(e)) {
logger.error(e); //[Exception output]
throw e;
} else {
logger.debug(e); //[Exception output]
throw e;
}
}
}
Throwable
is one level higher than java.lang.Exception
.Processing that does not throw an Exception should not be described in the try block if possible.
try {
//Processing other than files(Exception is not thrown)
initialize();
//File-related processing
File file = new File("/tmp/sample.txt");
FileReader fr = new FileReader(file);
} catch(IOException e) {
//...
}
problem
Most run-time exceptions indicate violations of preconditions. A precondition violation is that the API client simply does not adhere to the contract defined by the API specification.
Frequently seen run-time exceptions
http://qiita.com/yuba/items/d41290eca726559cd743 Reference
Exceptions that API users can avoid, API user responsibilities.
Do not use checked exceptions for situations where the caller can recover properly.
I'm not sure about the "recoverable state".
According to http://qiita.com/yuba/items/d41290eca726559cd743, "The checked exception is an abnormal system that is not the responsibility of the caller."
Frequently seen inspection exceptions
Since it cannot be avoided, API users are forced to "think about abnormal systems".
If you pass a file path that does not exist in the FileReader constructor, a FileNotFoundException will occur. Even if the existence of the file is confirmed, the file may be deleted immediately after that, so it cannot be completely avoided.
File file = new File("/tmp/sample.txt");
if (file.exists() ){
//If the file is deleted here, an Exception will occur on the next line
FileReader fr = new FileReader(file);
}
If "it is not the responsibility of the API user", it does not seem to be "the responsibility of the API creator". Maybe no one can take responsibility.
I felt that the API creator was throwing a check exception with the meaning that "even if an abnormal system occurs, this is not my responsibility".
The java.text.DateFormat # parse
method throws a checked exception ParseException
.
ParseException --If the beginning of the specified string cannot be parsed.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
try {
sdf.parse("abc"); //PrseException throw
} catch (ParseException e) {
e.printStackTrace();
}
ʻInteger.parseInt throws a runtime exception
NumberFormatException. Since
SimpleDateFormat` is not thread-safe, it may throw a checked exception.
java.lang.Exception
/**File reading*/
List<String> read(File file) throws Exception {
List<String> lines = new ArrayList<>();
FileReader fr = new FileReader(file);
//....
return lines;
}
problem
The error is represented by a return value or an output argument.
/**
* 0:success
* -1:Argument error
* -2:File related errors
* /
int read(char *file) {
//...
}
int sub(char *file) {
int rtn = read(file);
return rtn;
}
int main() {
int rtn = sub(file);
}
problem
Only Java implements checked exceptions in major languages. Either inspection exception is negative.
http://qiita.com/Kokudori/items/0fe9181d8eec8d933c98
When returning in the try-catch-finally clause, if the finally clause is set, the inside of the finally clause is always executed before returning.
source-try.java
public class Try {
public static void main(String[] args) {
String i=TryCatch();
System.out.println(i);
}
public static String TryCatch(){
System.out.println("start!");
String str = null;//Make it null
try{
str.toString(); //NullPointerException
System.out.println("Hogehoge");
return "The return from the Try clause.";
}catch(Exception e){
System.out.println("Fuga Fuga");
return "The return from the Catch clause.";
}finally{
System.out.println("The finally clause has been executed.");
}
}
}
System.out
start!
Fuga Fuga
The finally clause has been executed.
The return from the Catch clause.
Quoted from http://qiita.com/eijenson/items/7e9e112e69b37f72353c
System.exit
are prohibited in the finally clauseThese are not subject to errors or warnings when compiled with javac. However, when using Eclipse, I get a warning "finally block does not complete successfully" for break, continue, and return.
Quoted from http://www.atmarkit.co.jp/ait/articles/0611/22/news145.html
public class Try {
public static void main(String[] args) {
String i=TryCatch();
System.out.println(i);
}
public static String TryCatch(){
System.out.println("start!");
String str = null;//Make it null
try{
str.toString(); //NullPointerException
System.out.println("Hogehoge");
return "The return from the Try clause.";
}catch(Exception e){
System.out.println("Fuga Fuga");
return "The return from the Catch clause.";
}finally{
System.out.println("The finally clause has been executed.");
return "I'll squeeze the exception";//Make a return
}
}
}
System.out
start!
Fuga Fuga
The finally clause has been executed.
I'll squeeze the exception
try-with-resources
It can be used from Java 7. close unnecessary syntax
Prior to Java SE 7, you can use finally blocks to ensure that resources are closed regardless of whether the try statement ends successfully or abruptly.
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
When using the try-with-resources statement
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is BufferedReader. The declaration is in parentheses immediately after the try keyword. Starting with Java SE 7, the class BufferedReader implements the interface java.lang.AutoCloseable. The BufferedReader instance is declared with a try-with-resource statement, so it closes regardless of whether the try statement terminated successfully or abruptly (as a result of the method BufferedReader.readLine throwing an IOException). Can be done.
http://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html
[97 Things Programmers Should Know](http://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E6%9B%B8%E7%B1%8D/%E3%83%97%E3%83%AD%E3 % 82% B0% E3% 83% A9% E3% 83% 9E% E3% 81% 8C% E7% 9F% A5% E3% 82% 8B% E3% 81% B9% E3% 81% 8D97% E3% 81 % AE% E3% 81% 93% E3% 81% A8)
[Don't force the program to die](http://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3 % 82% A4 /% E6% AD% BB% E3% 81% AC% E3% 81% AF% E3% 81% 9A% E3% 81% AE% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% A0% E3% 82% 92% E7% 84% A1% E7% 90% 86% E3% 81% AB% E7% 94% 9F% E3% 81% 8B% E3% 81% 97% E3% 81% A6% E3% 81% 8A% E3% 81% 84% E3% 81% A6% E3% 81% AF% E3% 81% 84% E3% 81% 91% E3% 81% AA% E3% 81% 84)
[Don't ignore the error](http://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3% 82% A8% E3% 83% A9% E3% 83% BC% E3% 82% 92% E7% 84% A1% E8% A6% 96% E3% 81% 99% E3% 82% 8B% E3% 81% AA)
[Clearly distinguish between technical and business exceptions](http://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82 % A4 /% E6% 8A% 80% E8% A1% 93% E7% 9A% 84% E4% BE% 8B% E5% A4% 96% E3% 81% A8% E3% 83% 93% E3% 82% B8% E3% 83% 8D% E3% 82% B9% E4% BE% 8B% E5% A4% 96% E3% 82% 92% E6% 98% 8E% E7% A2% BA% E3% 81% AB% E5% 8C% BA% E5% 88% A5% E3% 81% 99% E3% 82% 8B)
[Exception handling best practices in Java] (https://moneyforward.com/engineers_blog/2014/08/22/java%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%BB%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9/)
Java checked exceptions are not the responsibility of the caller
The Deadly Sins in Exceptional Design
Recommended Posts