Java: using a RuntimeException to escape from a Visitor - java

I am being powerfully tempted to use an unchecked exception as a short-circuit control-flow construct in a Java program. I hope somebody here can advise me on a better, cleaner way to handle this problem.
The idea is that I want to cut short the recursive exploration of sub-trees by a visitor without having to check a "stop" flag in every method call. Specifically, I'm building a control-flow graph using a visitor over the abstract syntax tree. A return statement in the AST should stop exploration of the sub-tree and send the visitor back to the nearest enclosing if/then or loop block.
The Visitor superclass (from the XTC library) defines
Object dispatch(Node n)
which calls back via reflection methods of the form
Object visitNodeSubtype(Node n)
dispatch is not declared to throw any exceptions, so I declared a private class that extends RuntimeException
private static class ReturnException extends RuntimeException {
}
Now, the visitor method for a return statement looks like
Object visitReturnStatement(Node n) {
// handle return value assignment...
// add flow edge to exit node...
throw new ReturnException();
}
and every compound statement needs to handle the ReturnException
Object visitIfElseStatement(Node n) {
Node test = n.getChild(0);
Node ifPart = n.getChild(1);
Node elsePart = n.getChild(2);
// add flow edges to if/else...
try{ dispatch(ifPart); } catch( ReturnException e ) { }
try{ dispatch(elsePart); } catch( ReturnException e ) { }
}
This all works fine, except:
I may forget to catch a ReturnException somewhere and the compiler won't warn me.
I feel dirty.
Is there a better way to do this? Is there a Java pattern I am unaware of to implement this kind of non-local flow-of-control?
[UPDATE] This specific example turns out to be somewhat invalid: the Visitor superclass catches and wraps exceptions (even RuntimeExceptions), so the exception throwing doesn't really help. I've implemented the suggestion to return an enum type from visitReturnStatement. Luckily, this only needs to be checked in a small number of places (e.g., visitCompoundStatement), so it's actually a bit less hassle than throwing exceptions.
In general, I think this is still a valid question. Though perhaps, if you are not tied to a third-party library, the entire problem can be avoided with sensible design.

I think this is a reasonable approach for a few reasons:
You are using a 3rd party and are unable to add the checked exception
Checking return values everywhere in a large set of visitors when it's only necessary in a few is an unnecessary burden
Also, there are those that have argued that unchecked exceptions aren't all that bad. Your usage reminds me of Eclipse's OperationCanceledException which is used to blow out of long-running background tasks.
It's not perfect, but, if well documented, it seems ok to me.

Throwing a runtime exception as control logic is definitely a bad idea. The reason you feel dirty is that you're bypassing the type system, i.e. the return type of your methods is a lie.
You have several options that are considerably more clean.
1. The Exceptions Functor
A good technique to use, when you're restricted in the exceptions you may throw, if you can't throw a checked exception, return an object that will throw a checked exception. java.util.concurrent.Callable is an instance of this functor, for example.
See here for a detailed explanation of this technique.
For example, instead of this:
public Something visit(Node n) {
if (n.someting())
return new Something();
else
throw new Error("Remember to catch me!");
}
Do this:
public Callable<Something> visit(final Node n) {
return new Callable<Something>() {
public Something call() throws Exception {
if (n.something())
return new Something();
else
throw new Exception("Unforgettable!");
}
};
}
2. Disjoint Union (a.k.a. The Either Bifunctor)
This technique lets you return one of two different types from the same method. It's a little bit like the Tuple<A, B> technique that most people are familiar with for returning more than one value from a method. However, instead of returning values of both types A and B, this involves returning a single value of either type A or B.
For example, given an enumeration Fail, which could enumerate applicable error codes, the example becomes...
public Either<Fail, Something> visit(final Node n) {
if (n.something())
return Either.<Fail, Something>right(new Something());
else
return Either.<Fail, Something>left(Fail.DONE);
}
Making the call is now much cleaner because you don't need try/catch:
Either<Fail, Something> x = node.dispatch(visitor);
for (Something s : x.rightProjection()) {
// Do something with Something
}
for (Fail f : x.leftProjection()) {
// Handle failure
}
The Either class is not very difficult to write, but a full-featured implementation is provided by the Functional Java library.
3. The Option Monad
A little bit like a type-safe null, this is a good technique to use when you do not want to return a value for some inputs, but you don't need exceptions or error codes. Commonly, people will return what's called a "sentinel value", but Option is considerably cleaner.
You now have...
public Option<Something> visit(final Node n) {
if (n.something())
return Option.some(new Something());
else
return Option.<Something>none();
}
The call is nice and clean:
Option<Something> s = node.dispatch(visitor));
if (s.isSome()) {
Something x = s.some();
// Do something with x.
}
else {
// Handle None.
}
And the fact that it's a monad lets you chain calls without handling the special None value:
public Option<Something> visit(final Node n) {
return dispatch(getIfPart(n).orElse(dispatch(getElsePart(n)));
}
The Option class is even easier to write than Either, but again, a full-featured implementation is provided by the Functional Java library.
See here for a detailed discussion of Option and Either.

Is there a reason you aren't just returning a value? Such as NULL, if you really want to return nothing? That would be a lot simpler, and wouldn't risk throwing an unchecked runtime exception.

I see the following options for you:
Go ahead and define that RuntimeException subclass. Check for serious problems by catching your exception in the most general call to dispatch and reporting that one if it gets that far.
Have the node processing code return a special object if it thinks searching should end abruptly. This still forces you to check return values instead of catching exceptions, but you might like the look of the code better that way.
If the tree walk is to be stopped by some external factor, do it all inside a subthread, and set a synchronized field in that object in order to tell the thread to stop prematurely.

Why are you returning a value from your visitor? The appropriate method of the visitor is called by classes that are being visited. All work done is encapsulated within the visitor class itself, it should return nothing and handle it's own errors. The only obligation required of the calling class is to call the appropriate visitXXX method, nothing more. (This assumes you are using overloaded methods as in your example as opposed to overriding the same visit() method for each type).
The visited class should not be changed by the visitor or have to have any knowledge of what it does, other than it allows the visit to happen. Returning a value or throwing an exception would violate this.
Visitor Pattern

Do you have to use Visitor from XTC? It's a pretty trivial interface, and you could implement your own which can throw checked ReturnException, which you would not forget to catch where needed.

I've not used the XTC library you mention. How does it supply the complementary part of the visitor pattern - the accept(visitor) method on nodes? Even if this is a reflection based dispatcher, there must still be something that handles recursion down the syntax tree?
If this structural iteration code is readily accessible, and you're not already using the return value from your visitXxx(node) methods, could you exploit a simple enumerated return value, or even a boolean flag, telling accept(visitor) not to recurse into child nodes?
If:
accept(visitor) isn't explicitly implemented by nodes (there's some field or accessor reflection going on, or nodes just implement a child-getting interface for some standard control-flow logic, or for any other reason...), and
you don't want to mess with the structural iterating part of the library, or it's not available, or it's not worth the effort...
then as a last resort I guess that exceptions might be your only option whilst still using the vanilla XTC library.
An interesting problem though, and I can understand why exception-based control flow makes you feel dirty...

Related

Use try-catch to avoid lengthy null checking? [duplicate]

Sometimes I face I must write a piece of code like this (usually it have more nested if and more complex structure but for the example is enought)
public void printIt(Object1 a){
if (a!=null){
SubObject b= a.getB();
if (b!=null){
SubObject2 c=b.getC();
if(c!=null){
c.print();
}
}
}
}
when I dont need to know what failed and if something is null do nothing, an approach could be
public void printIt(Object1 a){
try{
a.getB().getC().print();
}catch (NullPointerException e) {
}
}
Is there something wrong in this second form like performance or other kind of issues?
The exception version (similar to chains using Groovy's safe-navigation operator ?.) makes it really easy to take the Law of Demeter (or as I call it, Demeter's Strongly-Worded Suggestion) and make it your plaything for the night.
Similarly, deeply-nested if-statements leads to difficult-to-read code, and underneath it all, the same "violation" exists, and the cyclomatic complexity of such methods is high.
public void printIt(Object1 a) {
if (null == a) {
return;
}
SubObject b = a.getB();
if (null == b) {
return;
}
SubObject2 c = b.getC();
if (null == c) {
return;
}
c.print();
}
I'd rather see LAMs (Little Auxiliary Methods) in appropriate places that encapsulate the checks and pretty much eliminate the need for the question altogether.
Yes. The second version will have terrible performance.
Don't use exceptions for normal control flow. Effective Java item 57: use exceptions only for exceptional situations.
==UPDATE==
Even ignoring performance issues (exceptions are faster than they once were, according to my benchmark, but not nearly as fast as a simple if check), it's really code-smelly to use exceptions for standard program flow like this. JVM bytecode has special optimizations it can do for null checks, even in if statements. The first code sample is vastly preferred.
public void printIt(Object1 a){
if(a==null){
throw new IllegalArgumentException("a was null, but this is not allowed here."),
}
[...]
Fail fast and fail hard. If a shoud not be null, throw an Exception. This will make your code more stable and reliable.
So if I would have to decide between your a) and your b), I would choose a). But if a mustn't be null there, you would hide an error-situation.
The wrongest part of the second version is that when a NPE happens inside the getB(), getC() it will be silently ignored. As already mentioned, exceptions are for exceptional cases.
Using exceptions is always a bad idea in terms of performance, no matter how slow the mechanism used to be and is now. Whenever an exception is thrown, the full stack will be unrolled to create the stack trace. Thus, like Lois Wasserman said, you should not rely on them for (regular) program flow but for exceptional cases.
The nested ifs aren't the definition of beauty, but will give you the ability to print additional information like 'B is null' etc.
The answer is use version A.
It is generally considered "bad design" to use Exceptions for flow control. Exceptions are for the "exceptional", especially NPEs which are totally avoidable using null checks. Further, using null checks, you can tell (ie log) which term is null (you won't know where the null is with your version B).
Note that performance is not an issue any more throwing exceptions (the stack trace for example is only built if you use it). It's a matter of clean code.
However, there are some case where using exceptions for flow control is unavoidable, for example the exceptions thrown from SimpleDateFormat.parse(), because there isn't a reasonable way to tell before making the call that your input is not parsable.
Definitely (a) but you should restructure the method to avoid nesting the if statements as mentioned in a previous answer. Exceptions are not the performance hit they once were but are still much slower than checking for null and should never be used for program flow control like this. If an object can be null you should check for it but if it is not allowed you should fail fast at the point you assign the object reference. In many circumstances you can have default implementations (empty list is a good example) to avoid nulls altogether which results in much cleaner code. Avoid nulls whenever you can.
Using Java 8 optional:
Optional.ofNullable(a)
.map(Object1::getB)
.map(SubObject::getC)
.ifPresent(Object2::print);
If you migrate to Java 8 you can use Optional and Lambdas. First, you need to rewrite your classes to return Optional of each type:
class Object1 {
private SubObject b;
Optional<SubObject> getB() {
return Optional.ofNullable(b);
}
}
class SubObject {
private SubObject2 c;
Optional<SubObject2> getC() {
return Optional.ofNullable(c);
}
}
class SubObject2 {
#Override
public String toString() {
return "to be printed";
}
}
Now, you can chain the calls without the risk of NullPointerExceptions in a concise way:
a.getB()
.flatMap(SubObject::getC)
.ifPresent(System.out::println);
See the Oracle's article Tired of Null Pointer Exceptions? Consider Using Java SE 8's Optional! for more information.
A code should never include exception handlers for unchecked exceptions. A null check should always be used for an object reference which has a chance of being null.

Why not have Jave methods return a tuple instead of an object reference (or null)?

Typically Java methods look like:
public <U,V> U doSomething(V aReference) {
// Do something
}
This typically means that the method doSomething() returns a null if it
fails (for whatever reason) or a valid object reference. In some cases the
"valid object reference" may itself be null. For example, the method
aMap.get(k) may return null if there is no key k or if there is a key
k but its corresponding value is null. Confusion!
Not to mention NullPointerExceptions if 50% of your LOC isn't just
null-checking.
What's wrong with methods looking like this:
public <T> ReturnTuple<T> doSomething(V aReference) {
T anotherObjRef = getValidObjT();
if (successful) {
return ReturnTuple.getSuccessTuple(anotherObjRef);
} else {
return ReturnTuple.getFailureTuple("aReference can't be null");
}
}
where the class ReturnTuple<T> is defined something like:
class ReturnTuple<T> {
private boolean success;
// Read only if success == true
private T returnValue;
// Read only if success == false
private String failureReason;
// Private constructors, getters, setters & other convenience methods
public static <T> ReturnTuple<T> getSuccessTuple(T retVal) {
// This code is trivial
}
public static <T> ReturnTuple<T> getFailureTuple(String failureReason) {
// This code is trivial
}
}
Then the calling code will look like:
ReturnTuple<T> rt = doSomething(v);
if (rt.isSuccess()) {
// yay!
} else {
// boo hoo!
}
So, my question is: why isn't this pattern more common? What is wrong with it?
Keep in mind I am not asking for a critique of this exact code, but for a
critique of this general idea.
Please note: the point here is not to get the code above to compile, just to
discuss an idea. So please don't be too pedantic about code correctness :-).
Edit 1: Motivation
I guess I should have added this section from the beginning, but better late
than never...
Ever wished a method could return two values at once? Or that the returning
of a value could be de-linked from the ability to indicate success or
failure?
This could also promote the idea of a method being a neat-and-clean
self-contained unit (low coupling and high cohesion): handle all (or most)
exceptions generated during it's execution (not talking about exceptions
like IllegalArgumentException), discreetly log failure reasons (rather
than the ugly stack trace of an uncaught exception) and only bother the
caller with exactly the information required. IMHO this also promotes
information-hiding and encapsulation.
Done your best with testing, but when the code is deployed to the customer,
an uncaught exception's ugly stack trace makes it all look so
unprofessional.
Similar to the point above: you may have code that could possibly generate
20 different exceptions but you're catching only 5-7 of those. As we all
know, customers do the damndest things: rely on them to cause all the other
uncaught 13-15 exceptions :-). You end up looking bad when they see a big
stack trace (instead of a discrete failure reason added to the logs).
This is the difference (for example) between showing a stack trace to a
user in a web app vs. showing them a nicely formatted 5xx error page saying
something like: "There was an error and your request couldn't be completed.
Admins have been notified and will fix as soon as possible." etc.
This idea isn't entirely without merit as Java 8 provides the
Optional
class (as pointed out by #JBNizet) and Google's
Guava library also has an
Optional
class. This just takes that a little further.
This typically means that the method doSomething() returns a null if it fails
No, it does not mean that. It means that the method doSomething() may sometimes legally return null, without a failure. Java provides a powerful system for handling failures - namely, exception handling. This is how the API should indicate failures.
why isn't this [return a tuple] pattern more common? What is wrong with it?
The primary thing that is wrong with this pattern is that it is using a mechanism of reporting failures in a way that is foreign to Java. If your API runs into a failure, throw an exception. This saves you from creating twice as many objects as needed in "mainstream" cases, and keeps your APIs intuitively understandable to people who learned the Java class library well.
There are situations when returning a null can be interpreted both ways - as a failure, and as a legitimate return value. Looking up objects in associative containers provide a good example: when you supply a key that is not in the map, one could claim that that is a programming error and throw an exception (.NET class library does that) or claim that when the key is missing, the corresponding spot in the map contains the default value, i.e. a null - the way this is done in Java. In situations like that it is entirely acceptable to return a tuple. Java's Map decided against this, most likely to save on creating additional objects every time an object is requested from a Map.

Pros and cons of casting vs. providing a method that returns the required type (Java)

I'm doing a bit of playing about to learn a framework I'm contributing to, and an interesting question came up. EDIT: I'm doing some basic filters in the Okapi Framework, as described in this guide, note that the filter must return different event types to be useful, and that resources must be used by reference (as the same resource may be used in other filters later). Here's the code I'm working with:
while (filter.hasNext()) {
Event event = filter.next();
if (event.isTextUnit()) {
TextUnit tu = (TextUnit)event.getResource();
if (tu.isTranslatable()) {
//do something with it
}
}
}
Note the cast of the resource to a TextUnit object on line 4. This works, I know it's a TextUnit because events that are isTextUnit() will always have a TextUnit resource. However, an alternative would be to add an asTextUnit() method to the IResource interface that returns the event as a TextUnit (as well as equivalent methods for each common resource type), so that the line would become:
TextUnit tu = event.getResource().asTextUnit;
Another approach might be providing a static casting method in TextUnit itself, along the lines of:
TextUnit tu = TextUnit.fromResource(event.getResource());
My question is: what are some arguments for doing it one way or the other? Are there performance differences?
The main advantage I can think of with asTextUnit() (or .fromResource) is that more appropriate exceptions could be thrown if someone tries to get a resource as the wrong type (i.e. with a message like "Cannot get this RawDocument type resource as a TextUnit - use asRawDocument()" or "The resource is not a TextUnit").
The main disadvantages I can think of with .asTextUnit() is that each resource type would then have to implement all the methods (most of which will just throw an exception), and if another major resource type is added there would be some refactoring to add the new method to every resource type (although there's no reason the .asSomething() methods would have to be defined for every possible type, the less common resources could just be cast, although this would lead to inconsistency of approach). This wouldn't be a problem with .fromResource() since it's just one method per type, and could be added or not per type depending on preference.
If the aim is to test an object's type and cast it, then I don't see any value in creating / using custom isXyz and asXyz methods. You just end up with a bunch of extra methods that make little difference to code readability.
Re: your point about appropriate exception messages, I would say that it is most likely not worth it. It is reasonable to assume that not having a TextUnit when a TextUnit is expected is symptom of a bug somewhere. IMO, it is not worthwhile trying to provide "user friendly" diagnostics for bugs. The person that the information is aimed at is a Java programmer, and for that person the default message and stacktrace for a regular ClassCastException (and the source code) provides all of the information required. (Translating it into pretty language adds no real value.)
On the flip-side, the performance differences between the two forms are not likely to be significant. But consider this:
if (x instanceof Y) {
((Y) x).someYMethod();
}
versus
if (x.isY()) {
x.asY().someYMethod();
}
boolean isY(X x) { return x instanceof Y; }
Y asY(X x) { return (Y) x; }
The optimizer might be able to do a better job of the first compared with the second.
It might not inline the method calls in the second case, especially if it is changed to use instanceof and throw a custom exception.
It is less likely to figure out that only one type test is really required in the second case. (It might not in the first case either ... but it is more likely to.)
But either way, the performance difference is going to be small.
Summary, the fancy methods are not really worth the effort, though they don't do any real harm.
Now if the isXyz or asXyz methods were testing the state of the object (not just the object's Java type), or if the asXyz was returning a wrapper, then the answers would be different ...
You could also just go
if (event instanceof TextUnit) {
// ...
}
and save yourself the trouble.
To answer your question regarding whether to go asTextUnit() vs. TextUnit.fromResource, the performance difference would depend upon how you actually implement these methods.
In the case of the static converter you would have a to create and return a new object of type TextUnit. However, in the case of the member function you could simply return this casted or you could create an return a new object - depends upon your use case.
Either ways, seems like instanceof is probably the cleanest way here.
What if your filter were extended - or wrapped - to return only text unit events? In fact, what if it returned only the resources of text unit events? Then your loop would be much simpler. I would think the clean way to do this would be a second filter, which simply returned just the text unit events, followed by, let's say, an Extractor, which returned the properly cast resource.
If you have a common base class, you can have a single asXMethod there for every derived class, and needn't refactor all derived classes:
abstract class Base {
A asA () { throw new InstantiationException ("not an A"); }
B asB () { throw new InstantiationException ("not an B"); }
C asC () { throw new InstantiationException ("not an C"); }
// much more ...
}
class A extends Base {
A asA () { /* hard work */ return new A (); }
// no asB, asC requiered
}
class B extends Base {
B asB () { /* hard work */ return new B (); }
// no asA, asC required
}
// and so on.
looks pretty clever. For a new Class N, just add a new Method to Base, and all derived classes get it. Just N needs to implement asN.
But it smells.
Why should a B have a method asA if it will always fail? That's not a good design. Exceptions in the generator are cheap, if they aren't triggered. Only thrown exceptions might be costly.
Yes, there are differences. Creating new immutable elements is better then casting. Pass all serializable data (non transient or computable data) to a Builder and build appropriate class.

java: combined instanceof and cast?

(Please no advise that I should abstract X more and add another method to it.)
In C++, when I have a variable x of type X* and I want to do something specific if it is also of type Y* (Y being a subclass of X), I am writing this:
if(Y* y = dynamic_cast<Y*>(x)) {
// now do sth with y
}
The same thing seems not possible in Java (or is it?).
I have read this Java code instead:
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
Sometimes, when you don't have a variable x but it is a more complex expression instead, just because of this issue, you need a dummy variable in Java:
X x = something();
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
// x not needed here anymore
(Common thing is that something() is iterator.next(). And there you see that you also cannot really call that just twice. You really need the dummy variable.)
You don't really need x at all here -- you just have it because you cannot do the instanceof check at once with the cast. Compare that again to the quite common C++ code:
if(Y* y = dynamic_cast<Y*>( something() )) {
// ...
}
Because of this, I have introduced a castOrNull function which makes it possible to avoid the dummy variable x. I can write this now:
Y y = castOrNull( something(), Y.class );
if(y != null) {
// ...
}
Implementation of castOrNull:
public static <T> T castOrNull(Object obj, Class<T> clazz) {
try {
return clazz.cast(obj);
} catch (ClassCastException exc) {
return null;
}
}
Now, I was told that using this castOrNull function in that way is an evil thing do to. Why is that? (Or to put the question more general: Would you agree and also think this is evil? If yes, why so? Or do you think this is a valid (maybe rare) use case?)
As said, I don't want a discussion whether the usage of such downcast is a good idea at all. But let me clarify shortly why I sometimes use it:
Sometimes I get into the case where I have to choose between adding another new method for a very specific thing (which will only apply for one single subclass in one specific case) or using such instanceof check. Basically, I have the choice between adding a function doSomethingVeryVerySpecificIfIAmY() or doing the instanceof check. And in such cases, I feel that the latter is more clean.
Sometimes I have a collection of some interface / base class and for all entries of type Y, I want to do something and then remove them from the collection. (E.g. I had the case where I had a tree structure and I wanted to delete all childs which are empty leafs.)
Starting Java 14 you should be able to do instanceof and cast at the same time. See https://openjdk.java.net/jeps/305.
Code example:
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
The variable s in the above example is defined if instanceof evaluates to true. The scope of the variable depends on the context. See the link above for more examples.
Now, I was told that using this castOrNull function in that way is an evil thing do to. Why is that?
I can think of a couple of reasons:
It is an obscure and tricky way of doing something very simple. Obscure and tricky code is hard to read, hard to maintain, a potential source of errors (when someone doesn't understand it) and therefore evil.
The obscure and tricky way that the castOrNull method works most likely cannot be optimized by the JIT compiler. You'll end up with at least 3 extra method calls, plus lots of extra code to do the type check and cast reflectively. Unnecessary use of reflection is evil.
(By contrast, the simple way (with instanceof followed by a class cast) uses specific bytecodes for instanceof and class casting. The bytecode sequences can almost certainly will be optimized so that there is no more than one null check and no more that one test of the object's type in the native code. This is a common pattern that should be easy for the JIT compiler to detect and optimize.)
Of course, "evil" is just another way of saying that you REALLY shouldn't do this.
Neither of your two added examples, make use of a castOrNull method either necessary or desirable. IMO, the "simple way" is better from both the readability and performance perspectives.
In most well written/designed Java code the use of instanceof and casts never happens. With the addition of generics many cases of casts (and thus instanceof) are not needed. They do, on occasion still occur.
The castOrNull method is evil in that you are making Java code look "unnatural". The biggest problem when changing from one language to another is adopting the conventions of the new language. Temporary variables are just fine in Java. In fact all your method is doing is really hiding the temporary variable.
If you are finding that you are writing a lot of casts you should examine your code and see why and look for ways to remove them. For example, in the case that you mention adding a "getNumberOfChildren" method would allow you to check if a node is empty and thus able to prune it without casting (that is a guess, it might not work for you in this case).
Generally speaking casts are "evil" in Java because they are usually not needed. Your method is more "evil" because it is not written in the way most people would expect Java to be written.
That being said, if you want to do it, go for it. It isn't actually "evil" just not "right" way to do it in Java.
IMHO your castOrNull is not evil, just pointless. You seem to be obsessed with getting rid of a temporary variable and one line of code, while to me the bigger question is why you need so many downcasts in your code? In OO this is almost always a symptom of suboptimal design. And I would prefer solving the root cause instead of treating the symptom.
I don't know exactly why the person said that it was evil. However one possibility for their reasoning was the fact that you were catching an exception afterwards rather than checking before you casted. This is a way to do that.
public static <T> T castOrNull(Object obj, Class<T> clazz) {
if ( clazz.isAssignableFrom(obj.getClass()) ) {
return clazz.cast(obj);
} else {
return null;
}
}
Java Exceptions are slow. If you're trying to optimize your performance by avoiding a double cast, you're shooting yourself in the foot by using exceptions in lieu of logic. Never rely on catching an exception for something you could reasonably check for and correct for (exactly what you're doing).
How slow are Java exceptions?

What is a good "Error Checking" Pattern (Java)?

I'll explain what I mean by input error checking.
Say you have a function doSomething(x).
If the function completes successfully doSomething does something and returns nothing. However, if there are errors I'd like to be notified. That is what I mean by error checking.
I'm looking for, in general, the best way to check for errors. I've thought of the following solutions, each with a potential problem.
Flag error checking. If doSomething(x) completes successfully return null. Otherwise, it returns a boolean or an error string. Problem: Side effects.
Throwing an exception. Throw an exception if doSomething(x) encounters an error. Problem: If you are performing error checking for parameters only, throwing an IllegalArgumentExceptionseems inappropriate.
Validating input prior to function call. If the error checking is only meant for the parameters of the function, then you can call a validator function before calling the doSomething(x) function. Problem: What if a client of the class forgets to call the validator function before calling doSomething(x)?
I often encounter this problem and any help or a point in the right direction would be much appreciated.
Throw an exception is the best way.
If you are performing error checking for parameters only, throwing an
IllegalArgumentException seems inappropriate.
Why? That's the purpose of this Exception.
Flag error checking
This is appropriate in some cases, depending on what you mean by an "error".
An example from the API: If you try to add an object to a Set, which already contains another object which equals the new object, the add method sort of "fails" and indicates this by returning false. (Note that we're on a level at which it's technically not even an "error"!)
2.Throwing an exception
This is the default option.
Question is now, should you go for a checked exception (which you need a throws declaration or try/catch clauses) or an unchecked exception (an exception that extends RuntimeException). There are a few rules of thumbs here.
From Java Practices -> Checked versus unchecked exceptions:
Unchecked exceptions: Represent defects in the program (bugs) - often invalid arguments passed to a non-private method.
Checked exceptions: Represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files)
Note that IllegalArgumentException is an unchecked exception, perfectly suitable for throwing when arguments are not as they should be.
If you want to throw a checked exception, you could A) roll your own by extending Exception, B) use some existing checked exception or C) "chain" a runtime exception in, for instance, an IOException: throw new IOException(new IllegalArgumentException("reason goes here..."));
3.Validating input prior to function call
Relying on the fact that the client should have sanitized / checked his arguments before the call seems like a bad idea to me.
Your second suggestion ("Throwing an exception") is the best choice. The other two options rely on the invoker either doing something before ("Validating input prior to function call") or after ("Flag error checking") the call to the method. Either way, the extra task is not mandated by the compiler so someone invoking the function isn't forced to call the "extra thing" so problems are not spotted till run-time.
As for "Throwing an Exception" and your suggested 'problem', well the answer is throw appropriate exception types for the code. If the input parameters are invalid, then throw an InvalidArgumentException (since that's the appropriate error). If the exception is for functionality (e.g. cannot open network connection), use another exception type or create your own.
I agree with throwing exceptions. I want to add another option that combines #2 and #3 - the proxy pattern. That way your code stays fairly cohesive - validation in one place and business logic in another. This makes sense if you have a large set of calls that need to be validated.
Create a proxy to handle validation. Have it delegate all calls to the actual implementation of your business logic interface after it validates, otherwise it can throw exceptions if something does not validate.
I decide which method to use usually on the type of interface.
User interface (GUI): I validate before calling business methods, because the user wants to know what was wrong.
On technical interfaces between components or systems, the interface should have been tested and work properly in this case I throw exceptions.
Exceptions is the way to go. Your stated problem with exceptions can be mitigated by the proper implementation of exception throwing / handling. Use exceptions to your advantage by validating parameters at the lowest level that you need them and throwing an exception if the validation fails. This allows you to avoid redundantly checking for validity at multiple levels in the call stack. Throw the exception at the bottom and let the stack unroll to the appropriate place for handling the error.
The method you choose depends on the situation, and they are not mutually exclusive so you can mix them all in the same solution (although whether that's a good idea really depends on your situation).
Choose this method if you want a very simple method for handling errors. This method might be OK for situations where the calling function can accept any value the called function returns. There might be situations where business logic dictates this as an OK choice, such as returning a specific message string when a resource cannot be properly located, or a server does not respond. Generally, I don't use this or see this technique in Java very much, as exceptions are a better mechanism for error handling.
Throw an exception when your function runs into un defined behaviour. If you have a math function that can only operate on positive integers and someone passes -1, you should thrown an InvalidArguementException. If your function is given the ID of a product in a database, but the product cannot be found by a query, you could throw a custom ProductNotFound exception.
Validating input is a good idea, I would say it should be done by the called function, rather than the caller - unless the caller can avoid an exception from the callee by validating the input before passing it. If you work in a language that supports Design By Contract, validating input would be done as the function's precondition.
I usually use #2 and #3. I haven't written code with error flags for a while. The exception to that might be a function that returned an enum, where one possible value indicated an error code. That was driven more by a business rule than anything else.
And generally, try to keep it simple.
Throw a custom checked exception.
doSomething(WithX x ) throws BusinessRuleViolatedException
Input validation is surprisingly complicated and all three of the suggested approaches in the original post are needed and sometimes more. Exceptions are appropriate when input is outside the bounds of business logic, if it is corrupt or cannot be read for example.
Flag checking quickly becomes an anti-pattern if you have more than one or two flags to check, and can be replaced with a slightly specialized version of the visitor pattern. I do not know the exact name of this specific pattern, but I'll informally call it the "validator list pattern" and will describe it in more detail below.
Checking input early and failing fast is usually good, but not always possible. Often there is a lot of input validation, all input received from outside of your control should be treated as hostile and requires validation. Good program design and architecture will help make it clear when exactly this needs to happen.
'The Validator List Pattern'
As an example, let's first describe in code the "Validation Flag" anti-pattern, and then we'll transform it to the "validation list" pattern.
public Optional<String> checkForErrorsUsingFlags(
ObjectToCheck objToCheck ) {
// the small series of checks and if statements represent the
// anti-pattern. Hard to test and many other problems crop up.
String errMsg = checkForError1( objToCheck );
if(errMsg != null ) {
return Optional.of(errMsg);
}
errMsg = checkForError2( objToCheck );
if(errMsg != null ) {
return Optional.of(errMsg);
}
return Optional.empty();
}
/**** client usage ****/
ObjectToCheck obj = doSomethingToReadInput(obj);
Optional<String> error = checkForErrors( obj);
if (error.isPresent()) {
// invalid input, throw object away and request input again
} else {
// do stuff, we have a valid input
}
To fix, start by creating a common interface that will represent a single validator. Then each check is converted to a validator instance. Finally we create a list of validators and pass it to the validator code.
/** The common validator interface each validator will use */
private interface MyValidator {
public boolean isValid(ObjectToCheck obj);
public String getErrorMessage(ObjectToCheck obj);
}
// this method should look familiar to the above, now we
// have a list of validators as an additional parameter
public Optional<String> checkForErrors( ObjectToCheck objToCheck,
List<MyValidator> validators ) {
for(MyValidator validator : validators ) {
if (!validator.isValid(objToCheck)) {
String errMsg = validator.getErrorMessage(objToCheck);
return Optional.of(errMsg);
}
}
return Optional.empty();
}
/****** client usage *****/
// now in this pattern, the client controls when the validators
// are created, and which ones are used.
MyValidator validator1 = new MyValidator() {
#Override
public boolean isValid(ObjectToCheck obj) {
return checkForError1( objToCheck ) != null;
}
#Override
public boolean getErrorMessage(ObjectToCheck obj) {
return checkForError1( objToCheck );
}
}
// note: above we call checkForError1 twice, not optimal.
// typical in real examples this can be avoided,
// and the error message generation logic split from the detection
// logic often simplifies things.
MyValidator validator2 = new MyValidator() { ... }
List<MyValidator> validators =
ImmutableList.of( validator1, validator2);
Optional<String> error = checkForErrors(objToCheck, validators);
if (error.isPresent()) {
// invalid input, throw object away and request input again
} else {
// do stuff, we have a valid input
}
Now to test, create a series of mock validators and check that each one has their validate called. You can stub validator results and ensure the correct behavior is taken. Then you also have access to each validator individually so you can test them one by one on their own.
Cheers - hope that helps, happy coding.

Categories