5

Please, tell me difference between the next situations :

public class Test {
    private static < T extends Throwable > void doThrow(Throwable ex) throws T {
        throw (T) ex;
    }

    public static void main(String[] args) {
        doThrow(new Exception()); //it's ok
    }
}

There is no compilation error in this case

AND

public class Test {
    private static < T extends Throwable > void doThrow(Throwable ex) throws Throwable {
        throw (T) ex;
    }

    public static void main(String[] args) {
        doThrow(new Exception()); //unhandled exception
    }
}

There is compilation error

Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • 1
    What does the compilation error say? – Woodchuck Jul 17 '20 at 16:55
  • It's advised to not throw a Throwable. This is because Throwable contains both the Exception and Error class. You don't want to handle an Error in your code. Throws Exception is what you probably want. – bdehmer Jul 17 '20 at 17:03
  • @ЛешаПакки Based on your example cause of compilation error has nothing to do with the body of the method so I simplified your example to skip it and focus on main difference which is `throws T` vs `throws Throwable`. If you don't agree with that change let me know so I can revert it. – Pshemo Jul 17 '20 at 17:08
  • 2
    I could swear the question looked completely different the last time I saw it. And both methods had ``. It was also pretty understandable. (Not saying it's worse now.) – akuzminykh Jul 17 '20 at 17:17
  • @akuzminykh True, in original version second case also contained `` in method declaration but since `T` isn't used there in `throws` leaving it in example IMO would only add unnecessary confusion. – Pshemo Jul 17 '20 at 17:30
  • Sorry i did a rollback, my intention is to maintain the code in different blocks rather than in same block, but the tittle now is like meaningless @Pshemo – Ryuzaki L Jul 17 '20 at 17:32
  • @Deadpool Yes, title was the reason why I *started* editing, but I don't want to get involved in rollback-war. OP should decide which version (s)he prefers. – Pshemo Jul 17 '20 at 17:36
  • @akuzminykh "you also basically threw the initial state out of the window and rewrote it" yes, that was to make it simpler since removed parts ware irrelevant to error which OP is asking about. My rationale is: we see two versions of *same class* where only difference is `throws T` vs `throws Throwable` in `doThrow` method. In main method compiler doesn't care if/when method throws exception (it can also never throw it), so method body can also be removed from this example, making `` irrelevant for second case. – Pshemo Jul 17 '20 at 17:53

1 Answers1

3

The way you have it right now in the question, makes it works because T is inferred to be a RuntimeException( I remember this because of @SneakyThrows):

private static < T extends Throwable > void doThrow(Throwable ex) throws T {
     throw (T) ex;
}

Basically the JLS says that if you declare a method that has throws XXX, where the upper bound of XXX is Exception or Throwable, the XXX is inferred to a RuntimeException.

Eugene
  • 117,005
  • 15
  • 201
  • 306