2

There's some third party code that looks like the following. Assume there are two classes, classA and classB, their definitions are correct and they work as expected.

// this function does not have a *throws Exception* in its definition
public Collection<classA> doSomething(String someStr) {

    List<ClassA> ClassAList = new ArrayList<ClassA>();
    int a = 0;

    while (a < 5) {
        classAList.add(
            new classA(
                someStr,
                new Callable<classB>() {
                    public classB call() throws Exception {
                        // do some work here
                        try {
                            // try something new
                        } catch (Exception e) { // <---- THIS EXCEPTION
                            // do something exceptional
                            throw e;
                        }
                        // do more work here, because why not?
                    }
                }
            )
        );
        a++;
    }
    return classAList;
}

This is a contrived example, so it may not be completely sensible. However, it accurately reflects the code I have.

What I'm trying to figure out is, what happens if the exception is thrown? Does the exception break through, and the entire doSomething function fails? (I suspect this is the case, but the upper level function doesn't have a "throws Exception", so may be I'm wrong?)

I'm relatively new to Java, and have definitely not seen this style of programming before (also, if you know what it's called, so I can research it more, please let me know) - I have a background in C and Python, so -__(o.O)__/-

Note: this is an extension to something, and therefore cannot be run directly for debugging.

Note 2: This question was marked as a possible duplicate of this. I am not asking how this compiles without the exception thrown clause. I'm trying to figure out where/when the exception is thrown.

Sagar
  • 9,456
  • 6
  • 54
  • 96
  • Have you taken a look at [the official Oracle tutorlal](https://docs.oracle.com/javase/tutorial/essential/exceptions/)? – Turing85 Mar 16 '18 at 17:43
  • Possible duplicate of [Rethrowing an Exception: Why does the method compile without a throws clause?](https://stackoverflow.com/questions/19913834/rethrowing-an-exception-why-does-the-method-compile-without-a-throws-clause) – Thiyagu Mar 16 '18 at 17:59

3 Answers3

2

I assume the Callable type here is java.util.concurrent.Callable.

The exception will actually never be thrown on the stack frame of doSomething. This is because it is defined in an anonymous inner class that implements Callable<classB>. It is not called in doSomething at all. The instance of anonymous class is then passed into classA's constructor, creating a new instance of classA and putting it into a list. This explains why doSomething does not need throws

Now, if you were to access the list, get the Callable<classB> from the instance of classA, and call Callable.call(), you do need to handle the checked exception either by adding a ``try...catchor adding athrows` clause in the surrounding method, like this:

public void doSomethingElse() throws Exception{
    ClassAList.get(0).getCallable().call(); // exception might be thrown here!
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • yes, it is a java.util.concurrent.Callable. Also, I see. Thank you, that makes sense. So, if I understand correctly, the `call` function is just getting defined there, not actually executed. – Sagar Mar 16 '18 at 19:15
  • Thank you! That's what I wanted to know. – Sagar Mar 16 '18 at 19:20
1

This can't happen, because Exception is a checked exception. You don't have a throws clause in your method signature. My guess is that the compiler will complain about your example code.

You will either have to switch that to a RuntimeException, which is unchecked, or add the throws clause to your method signature.

Even if you do that, I'd say this is a bad design.

Catching an exception suggests that you can do something sensible to recover from it. It might be next to nothing and logging the fact, or something more substantial like cleaning up resources and ending the task gracefully.

But catching and re-throwing seems a waste to me. I'd rather add the throws clause and not catch the exception so somebody up the line can do something sensible to recover from the problem.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Compiler (from Java 7) does not complain here as it is smart enough to find no Exception is thown from the try block – Thiyagu Mar 16 '18 at 18:00
  • @duffymo - this code compiles as is, no compiler errors. Also, it's third party code, so I haven't touched it/would probably not change it, unless I was fixing issues. – Sagar Mar 16 '18 at 19:13
1

Code you provided is just defining Callable's. It does not executed in doSomething method, so it won't throw exceptions there. Exceptions can be thrown where you actually execute the Callable (via call() or submitting it to a ExecutorService).

Check out the this example https://www.journaldev.com/1090/java-callable-future-example

miskender
  • 7,460
  • 1
  • 19
  • 23