На самом деле, это тоньше, чем кажется.
Приведенный выше код даст неправильный ответ для символа нижнего регистра, кодовая точка которого была выше U + FFFF (например, U + 1D4C3, МАТЕМАТИЧЕСКИЙ СКРИПТ МАЛЫЙ N) String.charAt будет возвращать суррогатную пару UTF-16, которая, так сказать, не символ, а половина. Поэтому вы должны использовать String.codePointAt, который возвращает int выше 0xFFFF (не символ). Вы бы сделали:
Character.isUpperCase(s.codePointAt(0));
Не расстраивайся из-за этого; почти все Java-кодеры плохо справляются с UTF-16, потому что терминология вводит в заблуждение, заставляя вас думать, что каждое значение "char" представляет символ. UTF-16 отстой, потому что это почти фиксированная ширина, но не совсем. Так что случаи краев не фиксированной ширины, как правило, не проходят проверку. Пока однажды не придет какой-нибудь документ, содержащий символ типа U + 1D4C3, и вся ваша система взорвется.