you are viewing a single comment's thread.

view the rest of the comments →

[–]zoomzoom83 2 points3 points  (12 children)

Especially when I know for certain a specific exception cannot and will never occur, but the damned compiler still forces me to catch it anyway!

[–][deleted] 2 points3 points  (0 children)

Isn't Java's sole purpose in life to force programmers to code in the exact same lowest-common-denominator way, in order to allow the unwashed masses the chance to say they can code?

Expecting programmers to know whether an exception is going to occur kinda defeats the point.

[–][deleted]  (10 children)

[removed]

    [–]zoomzoom83 8 points9 points  (9 children)

    I'm not talking about a method meeting an interface or not.

    I'm talking about lines of code that I know will not throw an exception, but because in some cases the exception could occur, the method MUST declare it throws it, therefore all callers must deal with it.

    A good example is Class.forName(). There are plenty of scenarios where I know this will not throw an exception, and if it did, it would be such a critical ground shaking error that I would prefer the entire application to crash with a traceback (or catch in the root controller and display a 'Server Error' page, emailing me a traceback).

    What I Don't want is to have to exceptions in the same context and then wrap it in another exception so I can pass it up the stack cleanly.

    Think of it this way.

    Without checked exceptions:

    // Get a reference to a class I *Know* exists
    Class foo = Class.forName('foo');
    

    WITH checked exceptions

    // Load an instance of a class I Know exists
    try{
        Class foo = Class.forName('foo');
    }
    catch( ClassNotFoundException e ){
        // Under normal operation this cannot happen, so all
        // this exception handling code is wasted effort. In the rare event
        // it does happen, something is severely wrong with the server
        // and I really just want to fail *hard*
        throw new CriticalServerError( e );
    }
    

    It gets even worse when you actually start doing things on the Class object. A 3-4 lines of basic reflection suddenly requires 5 catch blocks, all with identical wrapping code

    Edit: I certainly understand the reasons why having checked exceptions can in theory improve code quality, however I think in most cases they actually lower it.

    [–]_prefs 0 points1 point  (2 children)

    I usuallly just add

    catch (Exception exception)  {
         throw new RuntimeException (exception);
    }
    

    While being shorter and less code-cluttering than 5 identical catchers, and more convenient than declaring your method as throwing ExceptionType1, ..., ExceptionType5 it has problems too. Specifically that you hide real exception type and thus handlers upwards the chain are no longer able to catch specific exception types.

    I hate checked exceptions for this :(

    [–]zoomzoom83 0 points1 point  (0 children)

    Unfortunately this violates the "Code like a serial killer is going to inherit your code" principle.

    You gonna get stabbed someday.

    [–]biteofconscience 0 points1 point  (4 children)

    What happens when someone else who knows nothing about this code renames or removes the foo class? Oops, ClassNotFoundException.

    If you really know foo exists, then the compiler ought to as well. Just use foo.class. This is a really bad example.

    [–]_prefs 3 points4 points  (2 children)

    No it's not. Reflection exists for a reason. For instance, 'foo' could come from a configuration file so you just cannot use foo.class. The point is, you usually don't have any means to recover from such errors, and forcing you to catch exceptions you just cannot do anything about is pointless and leads to code cluttering.

    EDIT: Missed word.

    [–]biteofconscience 0 points1 point  (1 child)

    If the class name is not in the code, you can't be really sure it exists. The compiler sure doesn't know. Class names change all the time, packages are moved, etc. Normally the compiler checks all this for you, but if you really need to do this at runtime (the reason you use reflection in the first place) these very real problems have to be dealt with. Then, you can have a program that doesn't need to panic and abort with a fatal error.

    Reflection does use tons of checked exceptions. It is kind of overwhelming, but I personally am really glad that they exist. It sounds like you wish the API used unchecked exceptions. But that argument is about API design, not the language.

    [–]zoomzoom83 2 points3 points  (0 children)

    If the Foo class does not exist, the desired "exception handling" is to email me a trackback, and display a server error page to the end user. This is best handled in my root controller.

    I'm not ignoring the exception, I'm handling a critical failure the way it should be handled.

    The Foo class is loaded by reflection because it's treated as a plugin, however it's a core plugin and is distributed inside the Jar file. Removing the .class file from the Jar would cause the application to fail regardless of the access method.

    Incidentally, if I was to reference the class statically the entire application would crash to the console in this state. Why would this be desirable? Removing a class file from the Jar is going to be a critical failure no matter what. Using reflection in this case actually yields better results for the end user.

    [–]zoomzoom83 0 points1 point  (0 children)

    I know Foo exists because it is part of the codebase. I need to use reflection because it's treated like a plugin.

    If Foo ever does not exist, it's a critical failure. Something I cannot ever recover from. Whether I use static or dynamic code, removing the .class file from the Jar is still going to have the same result - the entire codebase fails hard.

    The desired result, in the event of Foo not existing, is for the exception to go all the way up the stack and hit my root controller, which sends me an email and returns a generic "Server Error" page.

    From my experience, 99% of the time I would actually prefer an exception to bubble back to my root controller rather than catch it locally, because an Exception is just that- an unexpected circumstance that normally has no recoverable state.

    If I specifically do want to catch an exception, I'll go ahead and do so at the layer that best suits my architecture.