1. Exception Handling
Unforeseen errors can occur at any time. Our programs must be prepared for them and be able to handle this situation. The next exercises will be about catching exceptions, handling them, and even reporting problems via exceptions.
Requirements
understand the need for exceptions
distinguish between checked and unchecked exceptions
catch exceptions with
try
-catch
know exception forwarding with `throws
be able to throw exceptions with `throw
be able to write your own exception classes
be able to close resources with
try
-with-resources
Data types used in this chapter:
1.1. Catching exceptions
Checked exceptions must be caught or passed up to the caller. For checked exceptions the compiler forces us to do this, for unchecked exceptions, this is not mandatory — however, if we do not handle a RuntimeException
this will cause the executing thread to abort. Therefore, it is recommended to always catch and at least log even unchecked exceptions.
1.1.1. Get the longest line of a file ⭐
Successful pirates must have a good memory, and Captain CiaoCiao wants to test if everyone can think like a whiz. He reads a list of names to everyone for a test. At the end of the list, everyone must be able to recite the longest name. But since Captain CiaoCiao is too busy reading aloud, he wants software to output the longest name at the end.
Task:
The file http://tutego.de/download/family-names.txt contains family names. Save the file locally on your file system.
Create a new class
LongestLineInFile
with amain(..)
method.Put the
Files.readAllLines(…)
into themain(…)
method.Which exception(s) must be caught?
What is the longest name (according to the
string
length()
) in the file?Bonus: What are the two longest names in the file?
You can read a file in Java like this:
|
1.1.2. Identify exceptions, laughing all the time ⭐
Developers must remember which language constructs, constructors, and methods can throw exceptions. While IDEs provide hints for checked exceptions, they may not provide warnings for every situation where an exception could potentially occur, such as with array access, where an ArrayIndexOutOfBoundsException
can be thrown.
Task:
What exceptions do we need to catch if we want to compile the following block? Use only the Javadoc to find out.
Clip clip = AudioSystem.getClip(); clip.open( AudioSystem.getAudioInputStream( new File("") ) ); clip.start(); TimeUnit.MICROSECONDS.sleep( clip.getMicrosecondLength() + 50 ); clip.close();
Can/should exceptions be grouped together?
Optional task: find some laughter files on the Internet (at https:// soundbible.com/tags-laugh.html, for example, there are free WAV files). Save the WAV files locally. Play random laughs one after the other in an endless loop.
1.1.3. Convert string array to int array and be lenient on non-numbers ⭐
The Integer.parseInt(String)
method converts a string
to an integer of type int
and throws a NumberFormatException
if no such conversion is possible, such as for Integer.parseInt("0x10")
or Integer.parseInt(null)
. The Java library does not provide a method for converting a string array of numbers to an int
array.
Task:
Write a new method
static int[] parseInts(String... numbers)
that converts all given strings to integers.The number of strings passed determines the size of the return array.
If a string in the array cannot be converted at a position, a
0
comes at the position.null
as an argument is allowed and results in0
.Calling
parseInts()
with no arguments is fine, butparseInts(null)
must result in an exception.
Example:
String[] strings = { "1", "234", "333" };
int[] ints1 = parseInts( strings ); // [1, 234, 333]
int[] ints2 = parseInts( "1", "234", "333" ); // [1, 234, 333]
int[] ints3 = parseInts( "1", "ll234", "3", null, "99" ); // [1, 0, 3, 0, 99]
int[] ints4 = parseInts( "Person", "Woman", "Man", "Camera, TV" ); // [0, 0, 0, 0]
1.2. Throwing custom exceptions
Exceptions originate in:
incorrect use of certain language constructs, such as integer division by 0, dereferencing via a
null
reference, impossible type matching for objects, incorrect array access, etc.explicitly generated exceptions by the keyword
throw
.
Behind throw
there is a reference to an exception object. This object is usually constructed with new
. The types either come from libraries, like IOException
, but they can also be our own exception classes, which have to be derived from Throwable
but are typically subclasses of Exception
.
1.3. Writing your own exception classes
Java SE provides numerous exception types, but they are usually technology-dependent, such as when there is a network timeout or the SQL command is wrong. This is fine for low-level functionality, but the software is built in layers, and the outermost layer is more about the consequence of these low-level events: there was an IOException
→ configuration could not be loaded; there was an SQLException
→ customer data could not be updated, etc. These exceptions are modeled by new semantic exception classes.
1.3.1. Show impossible Watt with own exception ⭐
Electrical devices without power consumption do not exist, just like negative wattage values.
Task:
Create your own exception class
IllegalWattException
. Derive the class fromRuntimeException
.The exception should be thrown whenever
setWatt(watt)
has a wattage less than or equal to zero.Test the exception occurrence by catching it.
1.4. try-with-resources
An important guideline is: If you open something, you close it afterward. It is easy to forget this, and then there are unclosed resources that can lead to problems. These include data loss and memory issues. To make it as easy as possible for developers to close resources, there is a special interface called AutoCloseable
and a language construct that helps make closing short and simple. This reduces the number of lines of code and avoids bugs, for example, when exceptions are thrown again during the closing process itself.
1.4.1. Write current date to file ⭐
A java.io.PrintWriter
is a simple class for writing text documents and can also write directly into files.
Task:
Study the Javadoc of
PrintWriter
.Find out how to connect a
PrintWriter
to an output file. The character encoding should be of the platform.Close the
PrintWriter
correctly withtry
-with-resources.The Java program should write the string representation of
LocalDateTime.now()
to the text file.
1.4.2. Read notes and write them to a new ABC file ⭐⭐
Renowned composer Amadeus van Trout discusses his latest works over the phone. Captain CiaoCiao is a big fan of the composer and secretly obtains an audio recording, which is delivered as a transcribed text file. It contains all the notes one below the other, such as:
C D C
The assignment is divided into two parts.
Task part A, reading from a file:
java.util.Scanner
is a simple class for reading and processing text resources. Study the constructors in the Javadoc.In the
Scanner
constructor, various sources can be specified, includingPath
. Open aScanner
, and pass a file in the constructor viaPaths.get("file.txt")
. Close theScanner
correctly withtry
-with-resources.The
hasNextLine()
andnextLine()
methods are of most interest. Read a text file line by line, and output all lines to the console. For example, if the input file contains the linesC, d d'
the output on the screen is
C, d d'
Extend the program to include only the lines with content. For example, if the file contains a blank line or a line with only white space, i.e., spaces or tab characters, it will not be included. Example:
C, d
leads to
C, d
Only valid notes are allowed, these are:
C, D, E, F, G, A, B, C D E F G A B c d e f g a b c' d' e' f' g' a' b'
Keep in mind that the comma on the uppercase letters is not a separator, but part of the note indication, as is the apostrophe on the lowercase letters of the last octave.
Captain CiaoCiao wants to listen to the new composition and see it on a sheet of music. Here the notation ABC is suitable; a file with notes from C
, to b'
looks like this:
M:C L:1/4 K:C C, D, E, F, G, A, B, C D E F G A B c d e f g a b c' d' e' f' g' a' b'
The first three lines are a header and contain metadata for ABC. At https://www.abcjs.net/abcjs-editor.html you can display the ABC file and even play it.
The basic idea of the algorithm is the following: we go through the file line by line using the class |
The program for reading in the notes is to be supplemented by a writing part.
Task part B, write to file:
Open a second file for writing with
PrintWriter
; in the constructor, you can pass a file name directly. Attention: Choose a different file name than the source file because otherwise the file will be overwritten!Continue to read the file from the first part of the task, but write the output to the new file instead of to the console, so that a valid ABC file is created. The
PrintWriter
provides theprint(String)
andprintln(String)
methods known fromSystem.out
.Note: Both resources can (and should) be in a common
try
with resources.