Question

Consider the following scenario

public class A extends Throwable {}

public class B extends A {}

public class C
{
    public void f() throws A, B
    {
        // Some condition
            throw new A();

        // Some condition 
            throw new B();
    }

    void g() 
    {
        f();
    }
}

With the above code, the compiler will warn against not catching (or not declaring as throws)

C.java:17: unreported exception A; must be caught or declared to be thrown
        f();
         ^

If I fix this with changing g to

void g() throws A

then I get no more warnings (B gets implicitly caught by catching A)

Is there a way to make the compiler report all uncaught exceptions including the base class ones (like B here).

One way is to change g() and declare it as

public void f() throws B, A

In which case, the compiler will first report B & once I add B to the throw spec of g, it will report A.

But this is painful because

  • This is a 2 step process
  • I may not have control of function f to change it's throw specs.

Is there a better way to make compiler report all exceptions?

I am not saying that the compiler is doing something wrong here - what I am asking is - "Is there a way to make the compiler report all the exceptions?". Or is a there a tool which helps me get this information automatically.

The function f throws A & B under different circumstances. If I am the author of g, I don't to accidentally suppress the information that calling g may throw B - which is what will happen if I declare g as throws A instead of declaring it as throws B, A. Is there a way to ask the compiler to detect this and warn me about it.

Again, I am not saying the compiler is doing something wrong by not warning me against this. All I am asking is if there is a way to make the compiler do what I want. Or a tool which reports this?

Was it helpful?

Solution 2

This is a compiler specific behavior. When having your scenario inside Eclipse, the compiler will tell about both exceptions in the error list though only one is shown in the tool-tip. More interesting, when using the automated fix, either adding catch clauses or throws declarations, Eclipse will always add both (in other words: all exceptions) ignoring any subclass relationships between the exceptions. The order of the declarations has no impact on this behavior. So maybe you just want to use Eclipse :^).

OTHER TIPS

I am not trying to sound patronizing or anything. I will probably say a lot of stuff you already know. But bear with me, while I try to explain why solving your problem will not be possible using compiler warnings.

Deriving two classes from each other, never mind if they are exception classes or not, means, they are in a is-a relation. For example:

public class Vehicle {}

public class Car extends Vehicle {}

public class Boat extends Vehicle {}

means: Car is a Vehicle. Boat is a Vehicle.

With throws, or more to the point, catch (later on), you specify the type you want to throw/be caught. Now, assuming that Vehicle was derived from Exception, you could do this:

try
{
    // ...
}
catch (Car c)
{
    // You caught a car. Not any vehicle, a real, honking car.
}

By doing this, however:

try
{
    // ...
}
catch (Vehicle v)
{
    // You caught some vehicle. Any vehicle.
}

you specify that you do not care if you catch cars, boats, bicycles or whatever, as long as it is mobile and transports passengers or cargo. Because a car is a vehicle. And a boat is a vehicle.

To sum up, what you are trying to do goes completely against the very idea of the object oriented approach. You cannot make the compiler report any "suppressed" or "hidden" exceptions, because they really are not. With throws, they are very much defined, and with catch, they are very much handled. So the compiler does not even understand your problem, let alone offer some way to prevent it.

As the comments say, a static code analysis would pretty much be the only option to do what you want to do. Something which I have used for occasions like these, is Checkstyle. Since what you want is quite unusual, I do not think that Checkstyle has a predefined check for what you want. In fact, it DOES have a check for the exact opposite.

So you will probably have to write your own check for it, but Checkstyle allows this rather easily. I would start by reading the source code of the RedundantThrows check, then doing the opposite of what it does. This should make your custom check to fail if you do not list ALL thrown checked exceptions in the method throws signature.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top