tags:

views:

1041

answers:

9

Hi,

Is it a good way to try something useless just to see if a particular exception is thrown by this code ?
I want to do something when the exception is thrown, and nothing otherwise.

try {  
    new BigDecimal("some string"); // This do nothing because the instance is ignored  
} catch (NumberFormatException e) {  
    return false; // OK, the string wasn't a well-formed decimal  
}  
return true;

There is too many preconditions to test, and the constructor BigDecimal() is always checking them all, so this seem the simplest method.

+39  A: 

Generally, this practice should be avoided. But since there is no utility method isValidBigDecimal(..), that's the way to go.

As Peter Tillemans noted in the comments, place this code in a utility method called isValidBigDecimal(..). Thus your code will be agnostic of the way of determining the validity, and you can even later switch to another method.

Bozho
+1, especially if you encapsulate it in a nice little function with a meaningful name!lie isValidBigDecimal) so it can be easily exchanged when a better technique comes along.
Peter Tillemans
Such little utility methods are quite handy when implemented as C# extension methods.
Developer Art
+6  A: 

There's nothing wrong with doing this; after all, proponents of a certain other language are fond of saying "it's easier to apologise than to ask permission", that is, it's easier to wait for something to fail and deal with it than it is to avoid failure altogether. In this case, since there is no alternative, absolutely go for it.

Jon Purdy
-1 for veiled negativity
Erick Robertson
There is an alternative - write a BigDecimal validator that returns false if the decimal passed is not valid. See also Boris's reply. Usually, checks /should/ be `if (x == valid) doSomething`, and the format `try x catch y` where some logic (like returning false) is found in the catch block should be avoided.
Cthulhu
There's always more than one way to do it.
Dean J
@Erick: Well, I guess I get what I get for pretending to like Python a little more than I really do for five minutes, though I'm lost as to where you think there's any negativity, however "veiled" it may appear. @Cthulhu: When I posted my answer, I was under the impression of the OP that there was no simpler alternative. @Dean: Right you are.
Jon Purdy
+26  A: 

If you dislike having a method like this one, try using BigDecimalValidator from Apache Commons Validator. In case of an invalid input String it returns null.

Boris Pavlović
+1, good find..
Bozho
well done on the Apache Commons link
Joel B
I'd lean towards the Apache Commons if performance is a concern; it takes a bit longer to instantiate the exception and throw it than it does to simply check if something is valid.
Dean J
Even without considering the performance hit, I avoid using try/catch for logical tests, because it muddies the waters in the debugger. I don't know how it is in your favorite Java debugger, but in Visual Studio, I usually run in the mode where the debugger breaks on any exception. Exceptions that are thrown in "normal" situations and expected to be caught as part of the program logic become a nuisance. Too bad Microsoft doesn't follow this advice in various parts of the .NET framework implementation.
vanmelle
+4  A: 

Performance might not be great and the syntax verbose, but the code is very precise about what it does. There is no duplication between check and use, which is always a big concern.

(Note, this particular sort of conversion to and from strings is really for debugging and internal configuration. It doesn't handle locales and other human-oriented consideration. Use in file formats and wire protocols introduces a strong dependency to the representation used by the class.)

Tom Hawtin - tackline
Actually, the performance difference between preconditions (check for valid input, then execute) and exception handling (execute, catch exception when input is invalid) is almost equal, especially if the input is correct in the majority of cases. This is, of course, debatable.
Cthulhu
@Cthulhu If every case is a happy case, it'll probably be faster. At least until some tries a DoS on your server. *Performance for sad case is Bad.* Though unlikely to be a problem if it is a real human typing.
Tom Hawtin - tackline
Tom: Have you tried it? The last time somebody asked about this, the try/catch case was actually faster than the pre-validation case.
Gabe
@Gabe I believe you are confusing this with the case of exception generated by the JVM, which may be optimised away. For exceptions generated by library code this will not happen (although it is theoretically possible).
Tom Hawtin - tackline
Tom: By all means, prove me wrong. The case I remember had somebody who wanted to validate a `float` and the running the regex to validate it was slower than just handling the exception.
Gabe
@Gabe I am not going to waste my time with something you misremember. If you're really sure, I suggest writing a microbenchmark yourself, or even just finding your original source.
Tom Hawtin - tackline
Tom: If you haven't tried it, all you're doing is passing on superstition. BTW, the benchmark I saw was here: http://stackoverflow.com/questions/3133770/how-to-find-out-if-the-value-contained-in-a-string-is-double-or-not/3134533#3134533 The upshot was that the 250-character regex was only a couple microseconds faster than catching an exception -- hardly worthy of being called *Bad Performance*.
Gabe
@Gabe Thanks for finding the original source. `java.util.regex` as currently implemented in the Sun/Oracle Java library doesn't have great performance. In the cited benchmark, the regex comes out over twice as fast. Without regexs, running an equivalent of the code in the `BigDecimal` constructor without exceptions is hundreds of times faster, unsurprisingly. Construction exceptions in code is expensive. **Bad Performance** (in general in situations where it is done excessively). No superstition.
Tom Hawtin - tackline
Tom: The link I posted showed that you can throw hundreds of thousands of exceptions per second, which I do *not* consider to be **Bad Performance**. The link *does not* say that the constructor is hundreds of times faster when exceptions aren't thrown, so please tell me how you know this statistic.
Gabe
+1  A: 

Yeah this certainly is in contention with the Pragmatic Programmer notion of "Exceptions for exceptional cases" but you recognize what you're doing so there's no problem IMO

brown.2179
Martin Fowler also has a Refactoring called "Replace Exception with Test" where he makes the same argument.
Javid Jamae
+5  A: 

There's two known method to "check" preconditions.

LBYL : Look before you leap

This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.

EAFP : Easier to ask for forgiveness than permission.

This common coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

EAFP is always a good idea for language that have duck typing.

It clearly depends on what you want to do... If you are not sure of the kind of the object to manipulate, use EAFP.

ohe
+1  A: 

A comment on kriss' answer: I don't see a "superb memory leak" here. There is no reference to the created BigDecimal. As soon as this method completes, and we go out of scope, the object is eligible for garbage collection.

Memory leaks occur when we hold references we no longer need so the object can't be garbage collected.

gfidler
in C++ this is a memory leak :) but not in Java indeed...
ohe
+1  A: 

Try / Catch blocks should never be used for logic.

Chris Ballance
And the word "never" should NEVER be used so emphatically and absolutely when talking about programming style.
Tesserex
@Tesserex When should Try / Catch blocks be used for logic?
Chris Ballance
@Tesserex it has nothing to do with style, everything to do with performance. If your application isn't so big you can afford to be lazy and use exceptions to avoid properly handling data, then go for it.
Rex M
@Chris Rex's comment is the answer to yours. And so is the highest voted answer to this question.
Tesserex
A: 

Sure, why not. This is what we do to check if an email address specified by the customer is properly formatted:

try
{
    MailMessage m = new MailMessage(from, to, subject, body);
    return true;
}
catch(SmtpFailedRecipientsException ex)
{
    return false;
}

Now, people may argue about the performance or appropriateness of the structure, but they forget the trade-offs in simplicity:

  • Above code will trap the EXACT data formats accepted by .NET. Anyone who has parsed email addresses will know that there's a lot of variance about what's considered a properly formatted email address structure. This code guarantees to validate email address structures the way that .NET likes, not the way that I think it should be.
  • The exception traps multiple use-cases, not just the correctness of a basic data structure. It will validate multiple users in the CC, BCC and TO fields, which starts to get unwieldy to do with handwritten code.

As others discuss above, this code is best abstracted into a separate utility class rather than mixed in with your main code.

Simon @ http://LabSlice.com

Simon Ellis