24

我正在为一个包设计一个公共接口(API)。我想知道,我应该CharSequence一般使用而不是String. (我主要是在谈论公共接口)。

这样做有什么缺点吗?它被认为是一种好的做法吗?

将它用于类似标识符的目的(当值与基于散列的容器中的集合匹配时)怎么样?

4

5 回答 5

34

CharSequence在通用库中很少使用。当您的主要用例是字符串处理(操作、解析等)时,通常应该使用它。

一般来说,你可以用 a 做任何你可以用 a 做CharSequence的事情String(很简单,因为你可以将 every 转换CharSequence为 aString)。但是有一个重要的区别:不能保证ACharSequence是不可变的!每当您处理 aString并在两个不同的时间点检查它时,您可以确定它每次都具有相同的值。

但对于一个CharSequence这不一定是真的。例如,有人可以将 a 传递StringBuilder到您的方法中并在您对其执行某些操作时对其进行修改,这可能会破坏许多正常的代码。

考虑这个伪代码:

public Object frobnicate(CharSequence something) {
  Object o = getFromCache(something);
  if (o == null) {
    o = computeValue(something);
    putIntoCache(o, something);
  }
  return o;
}

这看起来很无害,如果你在String这里使用过它,它大部分都可以工作(除了这个值可能会被计算两次)。但是如果something是 aCharSequence那么它的内容可能会在getFromCache调用和computeValue调用之间发生变化。或者更糟:在computeValue通话和putIntoCache通话之间!

因此:只有CharSequence在有很大的优点并且知道缺点的情况下才接受。

如果您接受CharSequence,您应该记录您的 API 如何处理可变CharSequence对象。例如:“在方法执行时修改参数会导致未定义的行为。”

于 2012-11-05T15:10:57.347 回答
6

这确实取决于您的需要,但是我想说明 的两个优点String

来自CharSequence的文档

每个对象都可以由不同的类实现,并且不能保证每个类都能够测试其实例与其他类的实例是否相等。因此,将任意 CharSequence 实例用作集合中的元素或映射中的键是不合适的。

因此,无论何时您需要一个Map或可靠的equals/ hashCode,您都需要将实例复制到一个String(或其他)中。

此外,我认为CharSequence没有明确提到实现必须是不可变的。您可能需要进行防御性复制,这可能会减慢您的实现速度。

于 2012-11-05T15:11:58.213 回答
5

JavaCharSequence是一个接口。正如 API 所说,CharSequence已在CharBuffer, Segment, String, StringBuffer,StringBuilder类中实现。因此,如果您想从所有这些类访问或接受您的 API,那么CharSequence您可以选择。如果不是,那么String对于公共 API 来说非常好,因为它非常容易并且每个人都知道它。记住CharSequence只给你4个方法,所以如果你CharSequence通过一个方法接受一个对象,那么你的输入操作能力就会受到限制。

于 2012-11-05T15:07:04.923 回答
4

如果参数在概念上是一个字符序列,请使用 CharSequence。

从技术上讲,字符串是一系列字符,但大多数情况下我们不会这样想。字符串更具原子性/整体性,我们通常不关心单个字符。

想想 int - 虽然 int 在技术上是一个位序列,但我们通常不关心单个位。我们将整数作为原子事物进行操作。

因此,如果您要对参数执行的主要工作是遍历其字符,请使用 CharSequence。如果要将参数作为原子操作,请使用 String。

于 2012-11-05T16:08:04.713 回答
0

您可以实施CharSequence以保存您的密码,因为不鼓励使用String。实现应该有一个 dispose 方法来清除纯文本数据。

于 2012-11-12T12:37:14.410 回答