Confusing exception message in MethodHandles#tableSwitch

Hannes Greule hannesgreule at outlook.de
Fri Oct 14 14:51:28 UTC 2022


Hi, I hope this is the right mailing list.

I recently fiddled around with MethodHandles#tableSwitch and stumbled 
across a confusing exception message. As a simple example, consider 
following code:

import java.lang.invoke.*;
import static java.lang.invoke.MethodType.*;
import static java.lang.invoke.MethodHandles.*;

class TableSwitch {
         public static void main(String[] args) {
                 MethodHandle defaultCase = zero(int.class);
                 MethodHandle zero = identity(int.class);
                 MethodHandle mh = tableSwitch(defaultCase, zero);
         }
}

Executing it will cause following stacktrace:
Exception in thread "main" java.lang.IllegalArgumentException: Case 
actions must have int as leading parameter: [MethodHandle(int)int]
         at 
java.base/java.lang.invoke.MethodHandles.tableSwitchChecks(MethodHandles.java:7862)
         at 
java.base/java.lang.invoke.MethodHandles.tableSwitch(MethodHandles.java:7850)
         at TableSwitch.main(TableSwitch.java:9)

As you can see, all printed method handles *have* int as leading 
parameter. The actual issue comes from the defaultCase method handle, 
which does not take any arguments. However, it is not part of the error 
message.
Furthermore, this exception is *only* thrown if the defaultCase doesn't 
match (see [1]). If one of the other cases doesn't match, a separate 
exception is thrown.

I suggest to change the exception message to make it more clear that the 
defaultCase has the wrong type.

By the way, the exception message if the targets/caseActions array is 
empty will always print an empty array. While that's not confusing, it 
could probably improved too.

Greetings
Hannes

[1] 
https://github.com/openjdk/jdk/blob/b8b9b97a1a3e07777da2e39ac4779ef7b77434c7/src/java.base/share/classes/java/lang/invoke/MethodHandles.java#L7859


More information about the core-libs-dev mailing list