Unfortunately, you still don't seem to understand the question being
asked. You're answering the problem of how to deal with this:
public abstract class A
{
public abstract void someMethod() throws MyException;
}
public abstract class B extends A
{
public void someMethod() { ... }
}
A a = new B();
a.someMethod();
Your answer makes a lot of sense for that scenario. Unfortunately,
though, the problem being discussed is different. It looks like this:
public abstract class A
{
public abstract void someMethod() throws MyException
{
otherMethod();
}
public abstract void otherMethod() throws MyException;
}
public abstract class B extends A
{
public void otherMethod() { ... }
}
B b = new B();
b.someMethod()
or, my alternative form of the same problem from earlier in this thread
(which uses standard API classes to avoid some of the complex details):
Properties p = new Properties();
p.setProperty("a", "b");
p.setProperty("c", "d");
ByteArrayOutputStream out = new ByteArrayOutputStream();
p.store(out);
In the first case, encapsulation and such is important and nesting a
checked exception into a runtime exception is indeed dangerous and
unnecessary. In the latter case, throwing a checked exception from the
client code is not only perfectly safe, but is in fact crucial for
maintaining a level of abstraction and encapsulation that is proper for
that section of code.
You're right that there is a piece of code in all of cases that doesn't
carry knowledge that a subclass implementation is being used. In Mike's
formulation (but my code above), it's the implementation of someMethod()
in A. In my example with Properties, it's the implementation of
store(OutputStream) in Properties. Neither piece of code *should* know
about the subclass.
That doesn't change the fact that the client code should -- and in fact
DOES -- know that you're using a subclass, and therefore that the
exception will not be thrown! That leaves you with three choices:
1. Catch the checked exception and continue without throwing an
exception. This is an immensely horrible idea, and I'm sure no one is
seriously suggesting this. Just getting it out of the way.
2. Catch the checked exception and wrap it in a RuntimeException. This
is my suggestion. Frankly, I don't understand your claim that this
causes client code to have to change due to changes in implementation
detail. In fact, it prevents that problem, relative to the third choice
below...
3. Declare these false exceptions in the 'throws' clause of a method,
and leave it up to the client code to handle them. As opposed to
preserving encapsulation, this is in fact a blatant violation of it. It
exposes the implementation details of the underlying method's code
(i.e., that it uses an I/O stream to do its work, even if that I/O
stream is only used to write to memory). Because of that, it causes the
client interface to logically change as a result of changes to the
implementation details such as use of an in-memory I/O stream.
Basically, building wrong abstractions is never the way to improve code
reliability -- or do anything else except confusion for that matter.
--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation