Improved Emoji Support in Java 21 - Sip of Java

Great news, Java developers, support for emojis has been improved in Java 21. Let’s take a look!

Emojitional Support

Before Java 21, there was no standard API for evaluating if a Character was an emoji, even though this information was available in the CLDR data included in the JDK. As the usage of emojis has become increasingly common, JDK-8303018 was created to add API to java.lang.Character to give Java developers the ability to check if emojis were being used.

Character API Updates

JDK-8303018 added six new methods to java.lang.Character:

public static boolean isEmoji(int codePoint)
public static boolean isEmojiPresentation(int codePoint)
public static boolean isEmojiModifier(int codePoint)
public static boolean isEmojiModifierBase(int codePoint)
public static boolean isEmojiComponent(int codePoint)
public static boolean isExtendedPictographic(int codePoint)

All six of the new methods are static, take a character’s int codePoint value, and return a boolean value. At the base level, isEmoji(int) can be used to check if a Character is an emoji; the other methods can be used to provide information on how an emoji should be rendered.

Using the Emoji API

The new emoji API can be used directly, like in the example code below transforming a String into an IntStream and evaluating if it contains an emoji:

String welcomeMsg = "Hey Java Developers! ☕️";

if(welcomeMsg.codePoints().anyMatch(Character::isEmoji)) {
	System.out.println("Message contains an emoji!");
}

isEmojiModifierBase and isEmojiModifier can be used to see if an emoji can be modified and if it has been modified; in this example, the emoji “🙋🏻‍♂️” is a base emoji that has had a modification applied to it: ️

String welcomeMsg = "Hey Java Developers! 🙋🏻‍♂️";

OptionalInt emojiOptional = welcomeMsg.codePoints().filter(Character::isEmoji).findFirst();

if (emojiOptional.isPresent()) {
	int emojiCodePoint = emojiOptional.getAsInt();
	if (Character.isEmojiModifierBase(emojiCodePoint)) {
		System.out.println("Emoji can be modified");
		if (Character.isEmojiModifier(emojiCodePoint)) {
			System.out.println("Emoji is modified");
		} else {
			System.out.println("Emoji has not been modified");
		}
	} else {
		System.out.println("Emoji cannot be modified");
	}
} else {
	System.out.println("No emoji");
}

Emoji API Support in Regex

These new methods can also be accessed in regex through the property construct \p{IsXXXX} like in this example:

String welcomeMsg = "Hey Java Developers! ☕️";

Matcher matcher = Pattern.compile("\\p{IsEmoji}").matcher(welcomeMsg);

if(matcher.find()) {
	System.out.println("Message contains an emoji!");
}

Note the property construct uses a modified snake case to reference the methods, as seen in this example:

String welcomeMsg = "Hey Java Developers! 🙋‍♂️";

Matcher matcher = Pattern.compile("\\p{IsEmoji_Modifier_Base}").matcher(welcomeMsg);

if(matcher.find()) {
	System.out.println("Message contains an emoji modifier base!");
}

Additional Reading

JBS Issue JDK-8303018

JDK 21 JavaDoc for java.lang.Character

Unicode® Technical Standard #51

Happy coding!