The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex
Exceptions are a special case. In their case, the inheritance is not to add new functionality, but to add new classes of errors. This lets your code catch particular kinds of errors while ignoring others.
ReplyDeleteSay you are writing a large project. You have a Data component, and you have a Display component. They can both fail in various ways, and you want to throw exceptions for these failures. The Display component doesn't care about exceptions arising from the Data component, though, and vice versa. If all the classes just threw Exception, there'd be no way to figure out where the exception came from. However, if you subclass Exception with DataException and GraphicsException, even though they don't add new functionality, you can now throw and catch those particular types of exceptions, i.e. a graphics component can catch GraphicsException and not have to deal with data exceptions.
You can catch exceptions by type, and having an exception of a particular type that is otherwise identical to the base Exception class allows you to be precise in your exception handling.
ReplyDeleteI would argue that it does add new functionality directly by increasing the specificity of exception handling code.
Use a new exception type when you want to provide error handling for a certain condition. Take a look at java.io.IOException and you will see the following subclasses:
ReplyDeleteChangedCharSetException
CharacterCodingException
CharConversionException
ClosedChannelException
EOFException
FileLockInterruptionException
FileNotFoundException
FilerException
HttpRetryException
IIOException
InterruptedIOException
InvalidPropertiesFormatException
JMXProviderException
JMXServerErrorException
MalformedURLException
ObjectStreamException
ProtocolException
RemoteException
SaslException
SocketException
SSLException
SyncFailedException
UnknownHostException
UnknownServiceException
UnsupportedDataTypeException
UnsupportedEncodingException
UTFDataFormatException
ZipException
Say you want to read from a file, you could get a generic IOException, a FileNotFoundException, and an EOFException. You may want to handle each of those cases differently. If all you had was IOException you would have to do something like look at the error message and then do an if/else statement to figure out what the actual error was so you can display a sensible message to the user. With a hierarchy of exceptions you can deal with those situations much easier.
In this case the functionality that inheritance adds is in regards to the catch statement, which can distinguish by type. Normally distinguishing subclasses by type is considered a bad practice, but exception handling is, well, an exception.
ReplyDeleteIt definitely leads to odd situations (such as multiple catch statements that have the same logic) as you would expect when things are distinguished by type, but that is a limitation of the language.
I would recommend reading all, or most, of Chapter 9 of Effective Java. Especially Item 60: "Favor the use of standard exceptions" and Item 61: "Throw exceptions appropriate to the abstraction".
ReplyDeleteEDIT 1: Or Items 42 and 43 in the first edition.
This renaming occurs to remove ambiguity wrt. the error that has occurred. e.g.
ReplyDeleteFoo getFoo() throws FooNotFoundException
will be explicit in indicating that a Foo cannot be found, as opposed to (what?) some illegal state, or a database connection error or similar, and you can choose to code (or not) for that particular error. If you choose to throw a more generic exception, it's less clear (programatically) what's occurred.
It's bad form to just catch any exception because not only will you not know where it came from, but you may be preventing yourself from handling errors correctly when they happen. If you just catch any type exception and handle it the same generic way, you may be hiding other problems in your software, or even introducing new ones. So, technically speaking, subclassing Exception does add new functionality.
ReplyDeleteCreating an exception for any type is really dumb. Maybe you should create an exception for different layer (DAO, Service, etc) or different action (create record, duplicate record, etc).
ReplyDeleteIf you need or want to differentiate the particular error situation from other errors in code, then it makes sense to subclass the appropriate exception. You should NOT need to peek at the error message to determine what went wrong - that is for human eyes only.
ReplyDeleteAlso note, that a properly named exception may be enough for a maintainers eye to deduce what went wrong when having to diagnose a stack trace. A typical example is ArrayOutOfBoundsException.
You add a new exception class when a user of your API might need to catch it conditionally (or, for checked exceptions specify different, specific types in a throws).
ReplyDelete