这个问题已经在这里有一个答案:
- CharSequence的VS字符串在Java中? 9个回答
- 为什么StringBuilder的时候有字符串? 9个回答
- CharSequence的和字符串之间选择一个API [复制] 1个回答
我读这以前的帖子 。 任何一个可以说什么之间的确切差CharSequence
和字符串是比其他事实String
实现CharSequence
和String
是字符的序列? 例如:
CharSequence obj = "hello";
String str = "hello";
System.out.println("output is : " + obj + " " + str);
当“你好”被分配到会发生什么obj
并再次str
?
一般差异
有其实施的几个类CharSequence
除了界面String
。 其中有
-
StringBuilder
用于可变长度的字符序列,其可以被修改 -
CharBuffer
固定长度的低级字符序列可以被修饰
它接受的任何方法CharSequence
可以在所有的这些同样良好地操作。 只接受一个任意方法String
将需要转换。 因此,使用CharSequence
作为,你不关心内部的所有地方的参数类型是稳健的。 然而,你应该使用String
作为返回类型,如果你真的返回一个String
,因为这避免了返回的值可能的转换如果调用方法实际上确实需要一个String
。
还要注意的是地图应该使用String
作为键类型,而不是CharSequence
,作为地图键不能改变。 换句话说,有时不可变的性质String
是必不可少的。
具体的代码段
至于你的代码粘贴:只需使用编译,并看看在JVM字节码javap -v
。 在那里,你会发现两者obj
和str
是相同的常量对象的引用。 作为一个String
是不可改变的,这种共享是所有权利。
在+
运营商String
被编译成不同的调用StringBuilder.append
电话。 因此,它是相当于
System.out.println(
(new StringBuilder())
.append("output is : ")
.append((Object)obj)
.append(" ")
.append(str)
.toString()
)
我必须承认我有点惊讶,我的编译器javac 1.6.0_33
编译+ obj
使用StringBuilder.append(Object)
,而不是StringBuilder.append(CharSequence)
。 前者可能涉及到一个呼叫toString()
对象的方法,而后者应以更有效的方式是可行的。 在另一方面, String.toString()
只返回String
本身,所以很少有罚。 所以StringBuilder.append(String)
可能是大约一个方法调用的效率更高。
TL;博士
一个是界面( CharSequence
),而另一种是具体实现该接口(的String
)。
CharSequence animal = "cat" // `String` object presented as the interface `CharSequence`.
作为一个接口,正常情况下CharSequence
会更常见比String
,但有些扭曲的历史造成了接口的实现年之后被定义。 因此,在旧的API的我们经常看到String
,而在新的API,我们往往看到CharSequence
用来定义参数和返回值。
细节
现在我们知道,一般的API /框架应侧重于主要出口接口和具体类其次。 但是,我们并不总是知道这节课这么好。
该String
类是先在Java中。 直到后来他们才将前置接口CharSequence
。
扭曲历史
一个小历史可以帮助理解。
在成立初期,爪哇被送往超越时代的市场了一下,由于互联网/网络狂热的动画产业。 一些图书馆都没有经过深思熟虑的,因为他们本来应该。 字符串处理是这些领域之一。
此外,Java的是最早的生产型非学术的一个面向对象编程(OOP)的环境。 唯一成功的现实世界橡胶满足路线的OOP的之前实现了一些有限的版本Smalltalk的 ,那么Objective-C的与NeXTSTEP的 / OpenStep的 。 所以,很多实际的经验教训仍有待了解。
Java的开始与String
类和StringBuffer
类。 但是,这两个类是不相关的,而不是通过继承和接口绑在一起。 后来,Java团队认识到,应该有字符串相关的实现,以使得它们可以互换之间的统一纽带。 在Java中4队增加了CharSequence
接口追溯和对实施和字符串的缓冲区接口,以及添加另一种实现方式CharBuffer
。 后来在Java 5中添加他们StringBuilder
,基本上一个不同步,因此略快版StringBuffer
。
因此,这些面向字符串的类是有点乱,有点混乱了解。 许多图书馆和接口建成采取并返回String
对象。 如今这样的库一般应建造期望CharSequence
。 但是,(一) String
似乎依然主宰拉巴威斯汀,和(b)混合各种时可能会有一些细微的技术问题CharSequence
实现。 随着20/20事后看来,我们可以看到,所有这串东西本来可以更好的处理,但我们在这里。
理想情况下的Java会已经开始与一个接口和/或超将在很多地方使用,我们现在使用String
,就像我们使用Collection
或List
界面替代的ArrayList
或LinkedList
实现。
接口对战类
有关的主要区别CharSequence
是,它是一个接口 ,而不是实现 。 这意味着你不能直接实例化CharSequence
。 而是你实例化一个实现该接口的类之一。
例如,我们在这里有x
,看起来像一个CharSequence
但骨子里其实是一个StringBuilder
对象。
CharSequence x = new StringBuilder( "dog" );
使用字符串文字时变得不那么明显。 请记住,当你看到源代码,只需报个字符左右的标记,编译器转换到这一个String对象。
CharSequence y = "cat"; // Looks like a CharSequence but is actually a String instance.
有一些细微的差异"cat"
和new String("cat")
在讨论这个问题等 ,但这里无关紧要。
类图
这个类图可以对您有所帮助。 我注意到了Java的版本中,他们似乎表现出多大的变化已经通过这些类和接口搅动。
原始字符串字面量
除了越来越多的表情符号和其他字符已经配备的连续版本的Unicode支持,近几年没有太大的在Java中改变了文字工作......直到Java的12或13。
Java的12可能会或可能不会提供新功能的预览: 原始字符串字面量 。 这将使编写嵌入式代码串,如SQL更方便。 见JEP 326 。
这JEP提出了一种新的文字,原始字符串字面量,其留出既逃脱的Java和Java行结束符规范,以提供在很多情况下比现有传统字符串文字可读性和可维护性的字符序列。
有关详细讨论,请参阅这篇文章 ,并看到这个帖子由戈茨, 原始字符串字面量-我们在哪里,我们在这里是如何得到 。 和维基百科有一个Blurb的 。
CharSequence
是一个合同( 接口 ),和String
是一个实施本合同。
public final class String extends Object
implements Serializable, Comparable<String>, CharSequence
该文档为CharSequence
是:
甲的CharSequence是char值的可读序列。 该接口提供均匀的,只读到许多不同种类的字符序列的访问。 char值表示在基本多语种平面(BMP)或替代一个字符。 请参阅Unicode字符表示的详细信息。
比字符串实现的CharSequence和该字符串是字符序列中的事实其他。
有几件事情发生在你的代码:
CharSequence obj = "hello";
创建一个String
字面, "hello"
,这是一个String
对象。 作为一个String
,它实现CharSequence
,它也是一个CharSequence
。 (你可以阅读这篇文章关于编码接口为例)。
下一行:
String str = "hello";
是有点复杂。 String
在Java中的文字是在游泳池举行(实习),所以"hello"
这条线是相同的对象(标识)的"hello"
的第一行。 因此,该行只分配相同的String
字面来str
。
在这一点上,两者obj
和str
是引用String
字面"hello"
,因此equals
, ==
,他们都是一个String
和一个CharSequence
。
我建议你测试此代码,显示在行动我只是写:
public static void main(String[] args) {
CharSequence obj = "hello";
String str = "hello";
System.out.println("Type of obj: " + obj.getClass().getSimpleName());
System.out.println("Type of str: " + str.getClass().getSimpleName());
System.out.println("Value of obj: " + obj);
System.out.println("Value of str: " + str);
System.out.println("Is obj a String? " + (obj instanceof String));
System.out.println("Is obj a CharSequence? " + (obj instanceof CharSequence));
System.out.println("Is str a String? " + (str instanceof String));
System.out.println("Is str a CharSequence? " + (str instanceof CharSequence));
System.out.println("Is \"hello\" a String? " + ("hello" instanceof String));
System.out.println("Is \"hello\" a CharSequence? " + ("hello" instanceof CharSequence));
System.out.println("str.equals(obj)? " + str.equals(obj));
System.out.println("(str == obj)? " + (str == obj));
}
我知道这是一种明显的,但CharSequence的是一个接口,而String是一个具体的类:)
java.lang.String中是这个接口的实现...
考虑UTF-8。 在UTF-8 Unicode码点是从一个或多个字节建造。 一类封装UTF-8字节阵列可实现的CharSequence接口但最决然不是字符串。 当然,你不能传递一个UTF-8字节数组,其中一个String预期,但你一定能传递实现CharSequence的当合同放宽到允许的CharSequence一个UTF-8封装类。 在我的项目,我开发了一个名为CBTF8Field类(压缩的二进制传输格式 - 第8位),以提供对XML数据的压缩,我期待使用的CharSequence接口从CBTF8字节数组实现转换到/从字符数组(UTF-16 )和字节阵列(UTF-8)。
我来到这里的原因是得到子合同的完整理解。
从Java API中的CharSequence :
甲CharSequence的是字符的可读序列。 该接口提供均匀的,只读到许多不同类型的字符序列的访问。
此接口则使用字符串 , 为CharBuffer和StringBuffer的保持一致性,所有的方法名。
在CharSequence的你没有非常有用的方法,其可用于字符串。 如果你不想在文档类型看:OBJ。 和STR。
看看有什么方法你compilator为您提供。 这对我来说最根本的区别。