何时在API中使用CharSequence
我正在为包设计一个公共接口(API)。 我想知道,我应该使用CharSequence
而不是String
。 (我主要谈的是公共接口)。
这样做有什么缺点吗? 它被认为是一种好习惯吗?
如何将它用于类似标识符的目的(当值与基于散列的容器中的集合匹配时)?
CharSequence
很少用于通用库。 当你的主要用例是字符串处理(操作,解析,……)时,通常应该使用它。
一般来说,你可以使用CharSequence
做任何事情,你可以用String
做(很简单,因为你可以将每个CharSequence
转换为String
)。 但是有一个重要的区别: CharSequence
不能保证不变! 无论何时处理String
并在两个不同的时间点检查它,您都可以确保它每次都具有相同的值。
但对于CharSequence
,这不一定是真的。 例如,有人可以将StringBuilder
传递给您的方法并在您使用它时对其进行修改,这可能会破坏很多合理的代码。
考虑这个伪代码:
public Object frobnicate(CharSequence something) { Object o = getFromCache(something); if (o == null) { o = computeValue(something); putIntoCache(o, something); } return o; }
这看起来很无害,如果你在这里使用了String
,那么它几乎可以工作(除非可能会计算两次值)。 但是如果something
是CharSequence
那么它的内容可能会在getFromCache
调用和computeValue
调用之间发生变化。 或者更糟:在computeValue
调用和putIntoCache
调用之间!
因此: 只有接受CharSequence
如果有很大的优势 ,你知道缺点 。
如果接受CharSequence
,则应记录API如何处理可变的CharSequence
对象。 例如:“在方法执行时修改参数会导致未定义的行为。”
这取决于你需要什么,我想说明String
两个优点。
来自CharSequence
的文档 :
每个对象可以由不同的类实现,并且不能保证每个类能够测试其实例与另一个的实例是否相等。 因此,将任意CharSequence实例用作集合中的元素或映射中的键是不合适的。
因此,无论何时需要Map
或可靠的equals
/ hashCode
,都需要将实例复制到String
(或其他)中。
此外,我认为CharSequence
没有明确提到实现必须是不可变的。 您可能需要进行防御性复制 ,这可能会降低您的实施速度。
Java CharSequence
是一个接口。 正如API所说, CharSequence
已经在CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
类中实现。 因此,如果您想要从所有这些类访问或接受您的API,那么CharSequence
是您的选择。 如果没有那么String
对于公共API非常好,因为它很容易并且每个人都知道它。 记住CharSequence
只给你4个方法,所以如果你通过一个方法接受一个CharSequence
对象,那么你的输入操作能力将受到限制。
如果参数在概念上是一系列字符,请使用CharSequence。
字符串在技术上是一系列字符,但大多数情况下我们并不这样认为; 一个字符串更primefaces/整体,我们通常不关心个别字符。
想想int – 虽然int在技术上是一个位序列,但我们通常不关心单个位。 我们将int作为primefaces事物来操纵。
因此,如果您要对参数执行的主要工作是迭代其字符,请使用CharSequence。 如果要将参数作为primefaces操作,请使用String。
您可以实现CharSequence
来保存您的密码,因为不鼓励使用String
。 实现应该有一个dispose方法来清除纯文本数据。