[In-house study session] Java exception handling (2017/04/26)

0. Introduction


Target person


What i want to tell

Explain the rules regarding exceptions from the perspective of API creators and API users. API (Application Program Interface) assumes public method.


Reference books

Effective Java 2nd Edition

参考図書.jpg

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.


table of contents

  1. Exception summary
  2. Exception rules for API users
  3. Exception rules for API authors
  4. Appendix

1. Exception summary


What are exceptions?

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 exceptions and run-time exceptions

Exception type structure


java.lang.Exception
 -  IOException
 -  SQLException
 -  RuntimeException
     - NullPointerException
     - IllegalArgumentException

Exception handling syntax (call method to throw)

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) {
  //...
}
private void read(File file) throws FileNotFoundException {
    FileReader fr = new FileReader(file);  
}

Exception handling syntax (explicitly throws Exception)

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.


Exception handling syntax (multi-catch)

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


2. Exception rules for API users


Do not ignore exceptions (item 65)

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


Use exceptions only for exceptional conditions (item 57)

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.


[Personal view] Catch with appropriate exceptions

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


If you can catch it with 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;
            }
        }
}        

[Personal view] The range of try blocks is not too wide

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


3. Exception rules for API authors


Use runtime exceptions for programming errors (item 58)

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.


Use checked exceptions (checked exceptions) for recoverable states (item 58)

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".


Is IOException really unavoidable in the first place?

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);
}  

My view

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".


Is there a check exception even at the API user's 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.


[Personal opinion] Do not throw 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


4. Appendix


C language with no exception handling mechanism

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


Pros and cons of inspection exceptions

Only Java implements checked exceptions in major languages. Either inspection exception is negative.

http://qiita.com/Kokudori/items/0fe9181d8eec8d933c98


finally clause and return

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


Break, continue, return, System.exit are prohibited in the finally clause

These 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" about Exceptions

[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)

プログラマが知るべき.jpg


Reference site

[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

History of error handling

The Deadly Sins in Exceptional Design


end

Recommended Posts

[In-house study session] Java exception handling (2017/04/26)
Java exception handling?
[Java] Exception handling
☾ Java / Exception handling
Java exception handling
Java exception handling
Summary of in-house newcomer study session [Java]
[Java] Practice of exception handling [Exception]
[Java] About try-catch exception handling
Java exception handling usage rules
Exception handling techniques in Java
[In-house study session] Basics of Java annotation (2017/11/02) ~ Under construction ~
[Study session memo] Java Day Tokyo 2017
Exception handling
Step-by-step understanding of Java exception handling
[For Java beginners] About exception handling
Exception handling Exception
[In-house study session] Introduction of "Readable Code"
Java (exception handling, threading, collection, file IO)
try-catch-finally exception handling How to use java
About exception handling
About exception handling
Let's study Java
ruby exception handling
[Java] Exception instance
Ruby exception handling
[Java] Study notes
Java 8 study (repeatable)
Java study memorandum
Java session scope
Study Java Silver 1
Study session memo: Kansai Java Engineers Association 8/5 --Selenium
Questions in java exception handling throw and try-catch
About Ruby exception handling
Exception handling practice (ArithmeticException)
[Ruby] Exception handling basics
Java Silver Study Day 1
[java] throw an exception
[Java ~ Method ~] Study memo (5)
Spring Boot exception handling
Javasilver study session memorandum
Java study # 1 (typical type)
[Java ~ Array ~] Study memo 4
My Study Note (Java)
[Java Silver] (Exception handling) About try-catch-finally and try-with-resource statements
Study session memo: Kansai Java Engineers Association [Osaka] 7/12 --Cloud Native
Study Java # 2 (\ mark and operator)
Classes that require exception handling
Java basic learning content 7 (exception)
Java's first exception handling (memories)
Study java arrays, lists, maps
Java Silver Study Method Memo
[Java ~ Boolean value ~] Study memo (2)
[Ruby] Exception handling in functions
Java study # 7 (branch syntax type)
Java study memo 2 with Progate
Study Java with Progate Note 1
[Milight Design In-house Study Session # 5] Read docker-compose.yml and Dockerfile line by line
(Learning memo) Java 2nd grade measures: Q4 main points (exception handling)
[Introduction to Java] About exception handling (try-catch-finally, checked exception, unchecked exception, throws, throw)
A story about writing a ratio calculation at an in-house study session