1. 概述

Java对Unicode的支持使得处理来自不同语言和脚本的字符变得简单。

在这篇教程中,我们将探讨并学习如何在Java中通过代码点获取Unicode字符。

2. 问题介绍

Java的Unicode支持使我们能够快速构建国际化应用。让我们看几个例子:

static final String U_CHECK = "✅"; // U+2705
static final String U_STRONG = "强"; // U+5F3A

在上述示例中,复选标记“✅”和中文“强”(Strong)都是Unicode字符。

我们知道,如果字符串遵循“\u”后跟十六进制数的模式,Java可以正确表示Unicode字符。例如:

String check = "\u2705";
assertEquals(U_CHECK, check);

String strong = "\u5F3A";
assertEquals(U_STRONG, strong);

在某些情况下,我们可能会接收到“\u”后面的十六进制数,并需要获取相应的Unicode字符。例如,当我们收到字符串格式中的数字“2705”时,应该生成复选标记“✅”。

我们的第一个想法可能是将“\u”和数字连接起来,但这不起作用:

String check = "\\u" + "2705";
assertEquals("\\u2705", check);

String strong = "\\u" + "5F3A";
assertEquals("\\u5F3A", strong);

测试显示,将“\u”和一个数字,如“2705”,连接起来会产生一个字面字符串“\u2705”而不是复选标记“✅”。

接下来,我们将探讨如何将给定的数字转换为Unicode字符串。

3. 理解“\u”后的十六进制数

Unicode为每个字符分配了一个唯一的代码点,提供了一种跨不同语言和脚本的通用文本表示方式。代码点是一个数值,它在Unicode标准中唯一标识一个字符。

要在Java中创建一个Unicode字符,我们需要理解所需字符的代码点。一旦我们有了代码点,就可以使用Java的char数据类型和\u转义序列来表示Unicode字符。

在“\uxxxx”表示法中,“xxxx”是字符的十六进制代码点表示。例如,字符“A”的十六进制ASCII代码是41(十进制:65)。因此,如果我们使用Unicode表示法“\u0041”,我们可以得到字符串“A”:

assertEquals("A", "\u0041");

现在,让我们看看如何从给定的十六进制数获取目标Unicode字符。

4. 使用Character.toChars()方法

现在我们了解了\u后十六进制数的含义。当我们收到“2705”时,它是字符代码点的十六进制表示

如果我们得到代码点整数,**Character.toChars(int codePoint)方法可以给我们包含代码点Unicode表示的char数组**。最后,我们可以调用String.valueOf()来获取目标字符串:

Given "2705"
 |_ Hex(codePoint) = 0x2705
     |_ codePoint = 9989 (decimal)
         |_ char[] chars = Character.toChars(9989) 
            |_ String.valueOf(chars)
               |_"✅"

如我们所见,为了获取目标字符,我们必须首先找到代码点。

代码点整数可以通过使用十六进制(基数16)解析提供的字符串来获得,使用Integer.parseInt()方法。

接下来,让我们把所有内容整合在一起:

int codePoint = Integer.parseInt("2705", 16); // Decimal int: 9989
char[] checkChar = Character.toChars(codePoint);
String check = String.valueOf(checkChar);
assertEquals(U_CHECK, check);

codePoint = Integer.parseInt("5F3A", 16); // Decimal int: 24378
char[] strongChar = Character.toChars(codePoint);
String strong = String.valueOf(strongChar);
assertEquals(U_STRONG, strong);

值得注意的是,如果你使用的是Java 11或更高版本,可以直接从代码点整数获取字符串,使用Character.toString()方法,例如:

// For Java 11 and later versions:
assertEquals(U_STRONG, Character.toString(codePoint));

当然,我们可以将上述实现包装在一个方法中:

String stringFromCodePointHex(String codePointHex) {
    int codePoint = Integer.parseInt(codePointHex, 16);
    // For Java 11 and later versions: return Character.toString(codePoint)
    char[] chars = Character.toChars(codePoint);
    return String.valueOf(chars);
}

最后,让我们测试这个方法以确保它产生预期的结果:

assertEquals("A", stringFromCodePointHex("0041"));
assertEquals(U_CHECK, stringFromCodePointHex("2705"));
assertEquals(U_STRONG, stringFromCodePointHex("5F3A"));

5. 总结

在这篇文章中,我们首先了解了“xxxx”在“\uxxxx”表示法中的意义,然后探索了如何从给定代码点的十六进制表示获取目标Unicode字符串。

如往常一样,示例的完整源代码可以在GitHub上找到。