Working with Exceptions |
Suppose you're calling a method that throws an exception, and you want to display the exception's message when an error occurs. If this method belongs to a class in a package written by someone else, you won't have any control over the message text unless you have access to the source code. This can be a problem if the message text has been hardcoded, because then it can't be translated into other languages. In the following code example, we encounter this problem when opening a file that does not exist:The catch clause of thestatic public void defaultMessage() { try { FileInputStream in = new FileInputStream("vapor.txt"); } catch (FileNotFoundException e) { System.out.println("e.getMessage = " + e.getMessage()); System.out.println("e.getLocalizedMessage = " + e.getLocalizedMessage()); System.out.println("e.toString = " + e.toString()); } }defaultMessage
method generates the following output:The messages printed are inadequate, for several reasons. First, the message text is hardcoded in thee.getMessage = vapor.txt e.getLocalizedMessage = vapor.txt e.toString = java.io.FileNotFoundException: vapor.txtFileNotFoundException
class and cannot be localized. We tried printing theString
returned bygetLocalizedMessage
, but becausegetLocalizedMessage
hasn't been implemented, it merely returns the same message as thegetMessage
method. Besides,getMessage
only returns the file name, which by itself is not a translatable message. Although we may find the file name useful during debugging, our end-users will need a more informative message.In general, the messages provided by subclasses of the
Exception
class, such asFileNotFoundException
, are meant for programmers, not for end-users. For example, a word processor should not display, "java.io.FileNotFoundException: vapor.txt," when the user tries to open a file that does not exist. This message, though technically correct, doesn't make sense to most people. Instead, when the word processor catches theFileNotFoundException
, it should display a message like: "Cannot find the file named vapor.txt. Make sure the file exists."In an application such as a word processor, the text returned by
FileNotFoundException.getMessage
is not appropriate for end-users. We should provide a message that is easier to understand, and that can be translated. We'll show you how to do this in the example that follows.Since the message text needs to be translated, we'll isolate it in a
ResourceBundle
. We're going to store our messages in properties files, which will back up aResourceBundle
namedExceptionBundle
. The message in theExceptionBundle_en_US.properties
file is as follows:In the following code example, we display a locale-sensitive message when thetemplate = Cannot find the file named {0}. Make sure the file exists.FileNotFoundException
is caught. First, we create aResourceBundle
for the properLocale
. Next, we retrieve the translated message pattern from theResourceBundle
. Finally, we apply the format pattern to insert the file name into the message.The output of thestatic public void customMessage(Locale currentLocale) { System.out.println("Locale: " + currentLocale.toString()); String fileName = "vapor.txt"; try { FileInputStream in = new FileInputStream(fileName); } catch (FileNotFoundException e) { ResourceBundle messages = ResourceBundle.getBundle("ExceptionBundle",currentLocale); Object[] messageArguments = {fileName}; MessageFormat formatter = new MessageFormat(""); formatter.setLocale(currentLocale); formatter.applyPattern(messages.getString("template")); String errorOut = formatter.format(messageArguments); System.out.println(errorOut); } }customMessage
method follows. It's quite an improvement over, "java.io.FileNotFoundException: vapor.txt."Locale: en_US Cannot find the file named vapor.txt. Make sure the file exists. Locale: de_DE Die Datei vapor.txt konnte nicht gefunden werden. Stellen Sie sicher, daß die Datei existiert.
Working with Exceptions |