There is the one true modifier order documented in the JLS and Modifier#toString(). The JDK sources should use it.
Here's my one weird hack to make it so:
#!/bin/bash
# See
# https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#toString-int-
#
# blessed-modifier-order src/java.base test/java/{util,io,lang}
set -eu
declare -ar dirs=("$@")
declare -ar modifiers=(
public protected private
abstract static final transient
volatile synchronized native strictfp
)
declare -r SAVE_IFS="$IFS"
for ((i = 3; i < "${#modifiers[@]}"; i++)); do
IFS='|'; x="${modifiers[*]:0:i}" y="${modifiers[*]:i}"; IFS="$SAVE_IFS"
if [[ -n "$x" && -n "$y" ]]; then
find "${dirs[@]}" -name '*.java' -type f | xargs perl -p -i -e \
"do {} while s/^([A-Za-z@ ]*)\b($y) +($x)\b/\1\3 \2/"
fi
done