如果我使用33到127之间的任何ASCII字符,codePointAt
方法会给出正确的十进制值,例如:
String s1 = new String("#");
int val = s1.codePointAt(0);
这将返回35,这是正确的值。
但是,如果我尝试使用128到255之间的ASCII字符(扩展ASCII / ISO-8859-1),则此方法会给出错误的值,例如:
String s1 = new String("ƒ") // Latin small letter f with hook
int val = s1.codePointAt(0);
这应该按照this reference table返回159,而是返回409,为什么会这样?
答案 0 :(得分:5)
但是,如果我尝试使用128到255的ASCII字符
ASCII没有此范围内的值。它只使用7位。
Java字符是UTF-16(没有别的!)。如果要使用Java表示ASCII,则需要使用字节数组。
codePointAt
方法返回32位代码点。 16位字符不能包含整个Unicode范围,因此某些代码点必须分成两个字符(根据encoding scheme for UTF-16)。 codePointAt
方法有助于解决代码点的问题。
我在Java here中写了一个粗略的编码指南。
答案 1 :(得分:2)
Java字符未在ISO-8859-1中编码。它们使用UTF-16,它具有7bit ASCII字符的相同值(仅0-127的值)。
要获得ISO-8859-1的正确值,您必须使用 将字符串转换为byte []并查看字节数组。String.getBytes("ISO-8859-1");
<强>更新强>
ISO-8859-1不是extended ASCII编码,使用String.getBytes("Cp437");
来获取正确的值。
答案 2 :(得分:0)
ƒ 0x0192 LATIN SMALL LETTER F WITH HOOK
答案 3 :(得分:0)
String.codePointAt返回此指定索引处的Unicode-Codepoint。
ƒ的Unicode代码点是402,参见
http://www.decodeunicode.org/de/u+0192/properties
所以
System.out.println("ƒ".codePointAt(0));
打印402
是正确的。
如果您对其他字符集中的表示感兴趣,可以通过getBytes(String charsetName)打印出其他字符集中字符的字节表示:
final String s = "ƒ";
for (final String csName : Charset.availableCharsets().keySet()) {
try {
final Charset cs = Charset.forName(csName);
final CharsetEncoder encode = cs.newEncoder();
if (encode.canEncode(s))
{
System.out.println(csName + ": " + Arrays.toString(s.getBytes(csName)));
}
} catch (final UnsupportedOperationException uoe) {
} catch (final UnsupportedEncodingException e) {
}
}