tags:

views:

61

answers:

2

Note: although seemingly similar, this is not a duplicate of http://stackoverflow.com/questions/1520859/overriding-fillinstacktrace-for-a-standard-jvm-exceptions

What are your thoughts on overriding fillInStackTrace on checked exceptions to return null?

The advantages are:

  1. you can use said exception for control flow without the performance penalty of filling in a stack trace.
  2. You can pass an arbitrary object back to the caller as a property of the exception, regardless of the signature of the method that throws said exception. (e.g. an error message, a partly-initialed value, etc.)

The biggest disadvantage is simply that this is not standard practice.

But the only way of doing something similar is:

  1. returning null, or a "special value" back (e.g. -1) to signify something went wrong.
  2. changing the callee to return a composite object of the value & error code, and having the caller inspect this object to see what happened.

I'm looking for an arguments that are extremely convincing for or against the practice of overriding fillInStackTrace, or an argument that shows it's no big deal either way.

Apparently RIFE uses this technique:

http://www.rifers.org/
http://cretesoft.com/archive/newsletter.do?issue=129

Below is a standard way of doing something, and a contrived example using this technique.

    //standard
    int i = "foo".indexOf('f');
    if (i<0){
      System.out.println("found f");
    } else {
      System.out.println("no f here");
    }
    //example
    try {
      "foo".indexOf('f');
      System.out.println("found f");
    } catch (NotFound e) {
      System.out.println("no f here");
    }
+1  A: 

If you think you have to do that, you could probably use from a good refactoring.

My general thought would be that there is a state of failure that you are trying to return up the tree. If that state was set in a common object, then the state would just be there to be queried.

Are you sure that each object is doing just a single thing? Are your objects valid in any state that they can possibly attain?

As a goal, if your objects are more than 10 methods, with most methods being 1 or 2 lines and a few methods being a screen-full or so, you probably need more classes, and as I said, if you actually had enough classes and they had a consistent state, this problem would almost certainly go away.

Example from comments: In the comment, the asker used indexOf as an example--the way it returns two values in an int. This will always lead to some pretty straight-forward code:

int pos=str.indexOf('a');
if(pos < 0) // Not obvious from code--should comment...
    System.out.println("Fail");
else
    //Do something with pos...

He suggests solving this with an exception which would lead to code like this:

try {
    int pos=str.indexOf('a');
    //Do something with pos...
} catch(CharacterNotFoundInStringException e) {
    System.out.println("Fail");
}

Which has the advantage of being more self documenting because of the new exception type created but has some unusual syntax and requires the creation of a new class (the exception).

My suggestion might be to make a new class as well, but code it this way:

Position pos=str.indexOf('a');
if(!pos.characterFound())
    System.out.println("Fail");
else
    // do something with pos.location();

Self documenting, quicker (stack pops with exceptions are always slower), etc.

But as I was saying originally, the biggest advantage is the new class "pos". It will probably turn out to be quite useful. In fact, instead of using pos.location, you may actually move the code from the "else" clause inside of a method in "pos", removing it completely.

Since it could contain business logic, that method in Position may actually be executed by the .indexOf call itself, eliminating the if statement around the call completely.

This doesn't really make much sense for "Generic" library methods like indexOf, it's kind of a pity but SDK methods are really difficult to implement in proper OO, but in your own business logic, you would almost certainly find this new "Position" class very useful in the future.

Bill K
None of that is the issue. Consider what "".indexOf returns. It doesn't return the index of a character. It returns a number, and if that number is >=0, then you have the index. If the number is <0, then you didn't find what you were looking for. This is a very simple example where a method returns a "special" value to indicate "I can't give you what you're asking for". Other options for "I can't give you what you're asking for"? are 1) throw a full exception, 2) return other "special values" (e.g. null). I'm just adding another way of doing things.
z5h
The indexOf thing is a bit of a hack. They are hacking additional data into an int. Although this makes things simpler sometimes, it can be replaced by two mechanisms--you can break it into two calls (test to see if it exists, then get the index) or you can return an object with an index and a boolean. Both will absolutely be clearer and less code than dealing with an exception, and honestly both are probably clearer than the current indexOf implementation with the exception that the current keeps all the info in one call (which has some advantages when trying to comprehend the SDK)
Bill K
All good points. I've accepted your answer now that it contains more info. As mentioned in my post, I have been thinking about creating a generic Result class with value and (error) status for use in cases like this.
z5h
A: 

I think it is all right. Sometimes you have no choice. But I find code of "if-else on return value" is generally easier to write and read than code of "try-catch on exception".

irreputable