0

In Java, both checked exception and unchecked exception can be thrown explicitly, i.e, by a throw statement. Besides, unchecked exceptions like ArithmeticException and OutOfMemoryError can be triggered without any explicit throw statement like this:

public static void throwArithmeticException() {
    int i = 1;
    int j = i / 0;
}

public static void throwOutOfMemoryError() {
    List<Object> list = new ArrayList<>();
    while(true) {
        list.add(new Object());
    }
}

So my question is, is there any way to trigger an checked Exception, like IOException, implicitly, i.e. not using any throw statement?

cbcwestwolf
  • 51
  • 1
  • 7
  • Is this just purely out of interest/fun or do you have a bigger goal in mind? – Sweeper May 09 '21 at 08:41
  • There is no "*`athrow`*" instruction in the java language (it is not even a [keyword](https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.9)). Also, all `Throwable`s must be `throw`n to have an effect as exception. Otherwise, they are just normal objects. --- For me, the question is unclear. Please [edit] the post and clarify the question. – Turing85 May 09 '21 at 08:43
  • @Sweeper My research topic is exception-related, so I am interested in the mechanism of exception handling. – cbcwestwolf May 09 '21 at 09:34
  • Thanks for the suggestions from @Turing85, I've edited and clarified the question. – cbcwestwolf May 09 '21 at 09:35
  • 1
    Do you mean "without there being a `throw` anywhere? As in, `Thread.currentThread().interrupt(); Thread.sleep(1);` would result in a checked exception being thrown, but something somewhere is throwing. – Andy Turner May 09 '21 at 09:37
  • The question is still unclear. Are you talking about bytecode instructions (`athrow`) or java keywords (`throw`)? Please clarify. – Turing85 May 09 '21 at 09:39
  • @Turing85 I've removed the declaration of `athrow` instruction. Thank you! – cbcwestwolf May 09 '21 at 12:12

2 Answers2

5

You can do it, but you shouldn't1.

I assume that you are talking about the athrow bytecode instruction. (And that you really asking if you can trigger an exception from your code without using a throw statement.)

There are (at least) two ways for an application to throw an arbitrary Java exception (checked or unchecked) that don't involve an explicit athrow instruction.

  1. You can call Unsafe.throwException(Throwable).

  2. In native code, you can call the Throw or ThrowNew functions in the JNI API.

In both cases, you can circumvent the Java (compile time and verifier) checks that are intended to ensure that checked exceptions are always declared (via a throws clause) or handled.

Note using Unsafe or native code means that your code is not Pure Java. It won't be portable. Furthermore it is easy to do things that will make a JVM unstable. JVM crashes are not unusual.


In addition, the JVM will itself throw exceptions without an athrow instruction. For example, if you try to use new FileInputStream to open a file that doesn't exist and FileNotFoundException is thrown, it is being throw from native code, not from compiled Java code.

It follows that your application can use this mechanism to implicitly throw many checked and unchecked exceptions; e.g. by deliberately trying to open a non-existent file. However, the method signature for read declares that it may throw IOException, so the compiler knows about this ... from the perspective of the checked exception rules.


1 - And if you application design requires this kind of craziness, you would be advised to come up with an alternative. It is a bad idea to try to fight Java's checked exception rules. If you dislike them so much that you are contemplating this, you should pick a different programming language.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Why does using `Unsafe` make your code not pure Java? Do you mean in the sense that it is not a "standard" Java API, but a thing specific to JDK implementations? – Sweeper May 09 '21 at 09:40
  • 2
    Yes. `Unsafe` is implementation specific in its API. And on top of that there are all sorts of implementation specific aspects in using `Unsafe` "safely" ... if you get what I mean. – Stephen C May 09 '21 at 10:40
1

In java bytecode, this is only possible for exceptions the JVM can generate itself, but IOException isn't one of them. You can only use the virtual machine to throw a run-time exception which is thrown by interpreting bytecode. For example this code:

aconst_null
monitorexit

will throw a NullPointerException. This is theoretically also possible for throwables like NegativeArraySizeException, IllegalMonitorStateException, WrongMethodTypeException, BootstrapMethodError, IncompatibleClassChangeError and many other. You can find out more here

Aura Lee
  • 416
  • 3
  • 11