Answers:
字符串是CharSequences,因此您可以只使用String而不用担心。Android只是通过允许您还指定其他CharSequence对象(例如StringBuffers)来尝试提供帮助。
CharSequence
javadoc的警告:此接口不会完善equals
and hashCode
方法的常规协定。因此,比较两个实现的对象的结果CharSequence
通常是undefined。每个对象都可以由不同的类实现,并且不能保证每个类都能够测试其实例与另一个实例的相等性。因此,将任意CharSequence
实例用作集合中的元素或用作映射中的键是不合适的。
CharSequence
是JDK 1.4的一种改进,目的是向包含字符序列的对象引入有限用途的通用接口。这些对象中的某些包含其他状态,因此将其定义Object.equals
为“包含相同的字符序列” 可能没有意义。NIO CharBuffer
,例如,仅公开其字符之间position
并limit
作为CharSequence
,尽管可能持有许多其他字符。
equals
/ hashCode
上Object
摆在首位....
Object
或中都没有设计错误CharSequence
,不需要接口来实现实现之间的平等。不需要两个Collection
提供Collection
接口之间的相等性,但是如果愿意的话,它们可以。恕我直言,CharSequence
应仅限于输入,并较少用于返回类型。
CharSequence
=接口String
=具体实施CharSequence
是一个接口。String
是此类之一,是的具体实现CharSequence
。你说:
从一个转换为另一个
没有从转换String
。
String
对象都是一个CharSequence
。CharSequence
都能产生一个String
。致电CharSequence::toString
。如果CharSequence
碰巧是一个String
,则该方法返回对其自身对象的引用。换句话说,每个String
都是a CharSequence
,但不是每个CharSequence
都是a String
。
在Android中编程时,大多数文本值应在CharSequence中使用。
这是为什么?在String上使用CharSequence有什么好处?主要影响是什么?
通常,对接口进行编程比对具体类进行编程要好。这产生了灵活性,因此我们可以在不破坏其他代码的情况下在特定接口的具体实现之间进行切换。
当开发供各种程序员在各种情况下使用的API时,编写代码以提供和采用最通用的接口。这使调用程序的程序员可以自由使用该接口的各种实现,无论哪种实现最适合其特定的上下文。
例如,查看Java Collections Framework。如果您的API给或采取对象的有序集合,如使用声明你的方法List
,而不是ArrayList
,LinkedList
或任何其他第三方实现List
。
当编写一个仅在一个特定位置仅由您的代码使用的快捷方法时,与编写在多个位置中使用的API相对,您不必费心使用更通用的接口而不是特定的具体方法类。但是即使那样,使用您可以使用的最通用的界面也确实有害。
使用它们时,主要区别是什么?预期会出现什么问题,
String
您知道只有一条文本完全在内存中,并且是不可变的。CharSequence
,您可能不知道具体实现的特定功能。该CharSequence
对象可能代表大量文本,因此具有内存含义。或者,可能是许多单独跟踪的文本块在您调用时需要缝合在一起toString
,因此存在性能问题。该实现甚至可能正在从远程服务中检索文本,因此具有延迟隐患。
并从一个转换为另一个?
您通常不会来回转换。A String
是一个CharSequence
。如果您的方法声明采用a CharSequence
,则调用程序的程序员可能会传递一个String
对象,也可能传递诸如a StringBuffer
或的其他内容StringBuilder
。您方法的代码将仅使用传递的任何内容,并调用任何CharSequence
方法。
最接近转换的是,如果代码收到,CharSequence
并且您知道需要String
。也许您正在与写入String
类而不是写入接口的旧代码CharSequence
交互。也许您的代码将与文本紧密协作,例如重复循环或进行其他分析。在这种情况下,您只希望对性能造成任何影响,因此请toString
提前致电。然后使用您知道的完全在内存中的单个文本继续进行工作。
注意对已接受答案的评论。该CharSequence
接口已改型为现有的类结构,因此存在一些重要的细微之处(equals()
&hashCode()
)。请注意在类/接口上标记的Java的各种版本(1、2、4和5),这些年来有些翻腾。理想情况下CharSequence
,从一开始就应该存在,但这就是生活。
下面的类图可以帮助您了解Java 7/8中字符串类型的概况。我不确定所有这些内容是否都存在于Android中,但是整体上下文可能仍然对您有用。
我相信最好使用CharSequence。原因是String实现了CharSequence,因此您可以将String传递给CharSequence,但是您不能将CharSequence传递给String,因为CharSequence不实现String。另外,在Android中,该EditText.getText()
方法返回一个Editable,该方法也实现了CharSequence,可以轻松地传递给一个,而不容易传递给String。CharSequence处理所有操作!
charSequence.toString()
通常,使用接口可使您以最小的附带损害来改变实施方式。尽管java.lang.String非常流行,但在某些情况下可能需要使用另一种实现。通过围绕CharSequences而不是Strings构建API,代码使人们有机会做到这一点。
这几乎可以肯定是性能原因。例如,假设有一个解析器经过一个包含字符串的500k ByteBuffer。
有三种返回字符串内容的方法:
在解析时构建一个String [],一次构建一个字符。这将花费大量时间。我们可以使用==代替.equals来比较缓存的引用。
在解析时构建具有偏移量的int [],然后在发生get()时动态构建String。每个String将是一个新对象,因此不会缓存返回值并使用==
在解析时构建一个CharSequence []。由于没有存储任何新数据(字节缓冲区中的偏移量除外),因此解析比#1低得多。在获取时间,我们不需要构建String,因此get性能等于#1(比#2更好),因为我们只返回对现有对象的引用。
除了使用CharSequence获得的处理优势外,还通过不复制数据来减少内存占用。例如,如果您有一个包含3个文本段落的缓冲区,并且想要返回全部3个或单个段落,则需要4个字符串来表示此内容。使用CharSequence时,您只需要1个数据缓冲区和4个CharSequence实现实例来跟踪起始和长度。
CharSequence
实现。
CharSequence
是一个接口 –根据定义,它没有您讨论的实现细节,因为它没有自己的实现。A String
是实现接口的几种具体类之一CharSequence
。所以a String
是一个CharSequence
。您可以比较String
vs StringBuffer
vs的性能细节StringBuilder
,但不能比较CharSequence
。编写“使用CharSequence获得的处理收益”是没有意义的。
A CharSequence
是接口,而不是实际的类。接口只是类在实现接口时必须包含的一组规则(方法)。在Android中,a CharSequence
是各种类型的文本字符串的保护伞。这是一些常见的:
String
(不带样式跨度的不可变文本)StringBuilder
(无样式跨度的可变文本)SpannableString
(具有样式范围的不可变文本)SpannableStringBuilder
(具有样式范围的可变文本)(您可以在此处详细了解它们之间的区别。)
如果您有一个CharSequence
对象,那么它实际上是实现的类之一的对象CharSequence
。例如:
CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
拥有像这样的通用伞类型的好处CharSequence
是您可以用一种方法处理多种类型。例如,如果我有一个将a CharSequence
作为参数的方法,则可以传入a String
或a SpannableStringBuilder
,它将处理其中一个。
public int getLength(CharSequence text) {
return text.length();
}
您可以说a String
只是一种CharSequence
。但是,与不同CharSequence
,它是一个实际的类,因此您可以从中创建对象。因此,您可以这样做:
String myString = new String();
但您不能这样做:
CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated
由于CharSequence
只是String
符合条件的规则列表,因此您可以执行以下操作:
CharSequence myString = new String();
这意味着,只要方法要求CharSequence
,就可以给它一个String
。
String myString = "hello";
getLength(myString); // OK
// ...
public int getLength(CharSequence text) {
return text.length();
}
但是,事实并非如此。如果该方法采用String
参数,则无法传递通常只被称为a的参数CharSequence
,因为它实际上可能是a SpannableString
或某种其他类型的CharSequence
。
CharSequence myString = "hello";
getLength(myString); // error
// ...
public int getLength(String text) {
return text.length();
}
CharSequence是实现String的char值的可读序列。它有4种方法
请参阅文档CharSequence文档
CharSequence
没有实现String
。相反,这是正确的。