In JavaLanguage, exceptions are FirstClass objects. But most programmers consider Exceptions as a simple DataStructure containing only a string message.
Exceptions represent a special condition in the flow of a program. These conditions can arise either from a bug in the program or due to environment conditions that are not condusive to a normal execution. In case of Java, all exceptions must derive from the class Throwable. The following is an example of an exception class.
public class PortNotFoundException extends Exception { public PortNotFoundException() { super(); } public PortNotFoundException(String message) { super(message); } public PortNotFoundException(String message, Throwable cause) { super(message, cause); } }The exception class listed above contains an optional message and an optional cause. Other than this, there is no further information that can be displayed to the user in a structured way. The above exception is fine as long as the recepient of the message is a technically sound person. When the same message is to be displayed to an end user, we need to translate this message. The usual method of translation is as follows.
try { client_.connect(); } catch (PortNotFoundException e) { CustomResourceBundle.getString("exception.connection.error"); }Wherever we catch the above exception, we end up with a code similar to that listed above. Now, we do not know the port number to which the client was unable to connect. The port number is contained in the exception message itself. To extract the port number, we would have to parse the string, which is not reliable, as the message may change from time to time. Now, look at the following code.
public class PortNotFoundException extends Exception { private int port; public PortNotFoundException() { super(); } public PortNotFoundException(String message) { super(message); } public PortNotFoundException(String message, Throwable cause) { super(message, cause); } public void setPort(int port) { this.port = port; } public int getPort() { return port; } }The above exception class adds a member named 'port'. This variable will contain the port number to which the client was unable to connect. In addition to the standard error message, this new exception class also contains an easy-to-retrieve port number.
Translatable Exceptions
There are many situations where the user needs to be informed of exceptions. Either you can show the exception's message as it is (which is not very good practice) or you can translate the exception into a more user friendly message. Since Java exceptions are first class objects, it is easier to do so in Java.
public interface Translatable { String getKey(); } public class PortNotFoundException implements Translatable { private int port; public PortNotFoundException() { super(); } public PortNotFoundException(String message) { super(message); } public PortNotFoundException(String message, Throwable cause) { super(message, cause); } public void setPort(int port) { this.port = port; } public int getPort() { return port; } public String getKey() { return "PortNotFoundException"; }}
public class Translator { private static final ResourceBundle EXCEPTION_MESSAGES = ResourceBundle.getBundle("ExceptionMessages.properties"); public static String translate(Translatable t) { String key = t.getKey(); return EXCEPTION_MESSAGES.get(key); } }This is just an example of how exceptions can be translated using them as first class objects, and the interface Translatable might be expanded as needed.
One important point to note is that although Java exceptions are first class objects, they should not be misused to perform operations that do not fall under the natural responsibilities of exceptions. Exceptions are only carriers of information and they should contain only the information useful to the consumer catching the exception.
-- VhIndukumar