pol*_*nts 24 java string unicode
以下是java.text.CharacterIterator文档的摘录:
这
interface定义了一个用于文本双向迭代的协议.迭代器迭代有界字符序列.[...]方法previous()和next()用于迭代.它们返回DONE[...],表示迭代器已到达序列的末尾.
static final char DONE:迭代器到达文本的结尾或开头时返回的常量.值是\uFFFF,不是任何有效的Unicode字符串中不应出现的"非字符"值.
斜体部分是我无法理解的部分,因为从我的测试来看,它看起来像Java String当然可以包含\uFFFF,并且似乎没有任何问题,除了明显的规定的CharacterIterator遍历习惯因为打破因为假阳性(例如,当它没有真正"完成"时next()返回'\uFFFF' == DONE).
这里有一个片段来说明"问题"(另见ideone.com):
import java.text.*;
public class CharacterIteratorTest {
// this is the prescribed traversal idiom from the documentation
public static void traverseForward(CharacterIterator iter) {
for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
System.out.print(c);
}
}
public static void main(String[] args) {
String s = "abc\uFFFFdef";
System.out.println(s);
// abc?def
System.out.println(s.indexOf('\uFFFF'));
// 3
traverseForward(new StringCharacterIterator(s));
// abc
}
}
Run Code Online (Sandbox Code Playgroud)
那么这里发生了什么?
\uFFFF?StringCharacterIterator实现"破",因为它并不如throw一个IllegalArgumentException如果事实上\uFFFF在有效Unicode字符串是被禁止的?\uFFFF?String包含\uFFFF?Joe*_*oey 27
EDIT(2013-12-17): Peter O.在下面提出了一个很好的观点,这使得这个答案错了.以下旧答案,历史准确性.
回答你的问题:
不,U + FFFF是所谓的非角色.从Unicode标准的第16.7节:
非字符是Unicode标准中永久保留供内部使用的代码点.它们被禁止用于Unicode文本数据的开放式交换.
...
Unicode标准留出了66个非字符代码点.每个平面的最后两个代码点都是非字符:BMP上的U + FFFE和U + FFFF,平面1上的U + 1FFFE和U + 1FFFF,依此类推,直到平面16上的U + 10FFFE和U + 10FFFF,共有34个代码点.此外,BMP中还有另外32个非字符代码点的连续范围:U + FDD0..U + FDEF.
不完全的.允许应用程序以他们想要的任何方式在内部使用这些代码点.再次引用标准:
应用程序可以在内部自由使用任何这些非字符代码点,但绝不应 尝试交换它们.如果在开放式交换中收到非字符,则不需要应用程序以任何方式解释它.但是,将它识别为非字符并采取适当的操作(例如用U + FFFD REPLACEMENT CHARACTER替换它)来表示文本中的问题是一种很好的做法.由于删除未解释的字符可能导致安全问题,因此建议不要简单地从此类文本中删除非字符代码点.
因此,虽然您永远不会遇到来自用户,其他应用程序或文件的字符串,但如果您知道自己在做什么,则可以将其放入Java字符串中(这基本上意味着您无法在该字符串上使用CharacterIterator,虽然.
如上所述,用于交换的任何字符串都不得包含它们.在您的应用程序中,您可以以任何他们想要的方式自由使用它们.
当然,Java char只是一个16位无符号整数,并不真正关心它所拥有的值.
实际上,非字符部分甚至建议使用U + FFFF作为哨兵值:
实际上,非字符可以被认为是应用程序内部的私有代码点.与第16.5节中讨论的私人使用字符不同,私人使用字符是指定字符并且打算用于公开交换,受私人协议解释,非字符永久保留(未分配),并且在外部没有任何解释他们可能的应用程序 - 内部私人用途.
U + FFFF和U + 10FFFF.这两个非特征代码点具有与特定Unicode编码形式的最大代码单元值相关联的属性.在UTF-16中,U + FFFF与最大的16位代码单元值FFFF 16相关联.U + 10FFFF与最大的合法UTF-32 32位代码单元值10FFFF 16相关联.此属性将这两个非字符代码点用作内部目的作为标记.例如,它们可能用于指示列表的结尾,表示保证高于任何有效字符值的索引中的值,依此类推.
CharacterIterator遵循这一点,因为当没有更多字符可用时它返回U + FFFF.当然,这意味着如果您在应用程序中对该代码点有另一种用途,您可以考虑为此目的使用不同的非字符,因为已经采用了U + FFFF - 至少如果您使用的是CharacterIterator.
Pet*_* O. 19
其中一些答案在此期间发生了变化.
Unicode联盟最近发布了勘误表9,阐明了非字符的作用,包括U + FFFF,在Unicode字符串中的作用.它指出虽然非字符用于内部使用,但它们可以合法地出现在Unicode字符串中.
这意味着声明"值是\ uFFFF,'不是字符'值,不应出现在任何有效的Unicode字符串中." 现在是不正确的,因为U + FFFF 可以出现在有效的Unicode字符串中.
因此:
java.lang.String"A String表示UTF-16格式的字符串" 的规范.U + FFFF在Unicode字符串中是合法的,因此Java在包含它的字符串中允许U + FFFF时不违反Unicode.