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

Reply via email to