我读了这个previous post。任何人都可以说CharSequence
和String之间的确切区别是什么,String
实现CharSequence
而String
是一个字符序列的事实?例如:
CharSequence obj = "hello";
String str = "hello";
System.out.println("output is : " + obj + " " + str);
将“hello”分配给obj
并再次分配给str
时会发生什么?
答案 0 :(得分:95)
除了CharSequence
之外,有几个类实现了String
接口。其中有
StringBuilder
用于可修改的可变长度字符序列CharBuffer
用于可修改的固定长度低级字符序列任何接受CharSequence
的方法都可以同样适用于所有这些方法。任何只接受String
的方法都需要转换。因此,在您不关心内部的所有地方使用CharSequence
作为参数类型是谨慎的。但是,如果实际返回String
,则应使用String
作为返回类型,因为如果调用方法确实需要String
,则可以避免返回值的可能转换。
另请注意,地图应使用String
作为键类型,而不是CharSequence
,因为地图键不得更改。换句话说,有时String
的不可变性是必不可少的。
至于您粘贴的代码:只需编译它,然后使用javap -v
查看JVM字节码。在那里,您会注意到obj
和str
都是对同一个常量对象的引用。由于String
是不可变的,这种共享是可以的。
+
的{{1}}运算符被编译为各种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
可能通过一次方法调用更有效。
答案 1 :(得分:84)
一个是接口(CharSequence
),而另一个是该接口的具体实现(String
)。
CharSequence animal = "cat" // `String` object presented as the interface `CharSequence`.
作为一个接口,通常CharSequence
比String
更常见,但是一些扭曲的历史导致接口在实施后定义。因此,在较旧的API中,我们经常看到String
,而在较新的API中,我们倾向于看到CharSequence
用于定义参数和返回类型。
如今我们知道API /框架通常应该主要关注导出接口,其次是具体类。但我们并不总是很清楚这一课。
String
类在Java中排在第一位。直到后来他们才放置了一个面向前的界面CharSequence
。
一点历史可能有助于理解。
早期,由于互联网/网络狂热使该行业充满活力,Java急于推出市场。有些图书馆并没有像他们应该的那样经过深思熟虑。字符串处理是其中一个领域。
此外,Java是最早的以生产为导向的非学术Object-Oriented Programming (OOP)环境之一。在此之前,OOP唯一成功的现实橡胶实现道路实施是SmallTalk的一些限制版本,然后是Objective-C和NeXTSTEP / OpenStep。因此,许多实践课程尚未学习。
Java以String
类和StringBuffer
类开头。但是这两个类是无关的,没有通过继承和接口相互联系。后来,Java团队认识到字符串相关实现之间应该存在统一的联系,以使它们可以互换。在Java 4中,团队添加了CharSequence
接口,并在String和String Buffer上追溯实现了该接口,并添加了另一个实现CharBuffer
。后来在Java 5中,他们添加了StringBuilder
,基本上是StringBuffer
的非同步版本,因此速度更快。
所以这些面向字符串的类有点混乱,而且有点混乱。构建了许多库和接口来获取和返回String
个对象。现在通常应该构建这样的库以期望CharSequence
。但是(a)String
似乎仍然主导着思维空间,并且(b)在混合各种CharSequence
实现时可能存在一些微妙的技术问题。事后看来,我们可以看到所有这些字符串的东西可以更好地处理,但我们在这里。
理想情况下,Java应该从一个接口和/或超类开始,这些接口和/或超类将在我们现在使用String
的许多地方使用,就像我们使用Collection
或List
接口一样ArrayList
或LinkedList
实施的位置。
关于CharSequence
的主要区别在于它是interface,而不是implementation。这意味着您无法直接实例化CharSequence
。而是实例化实现该接口的类之一。
例如,我们x
看起来像CharSequence
,但下面实际上是StringBuilder
对象。
CharSequence x = new StringBuilder( "dog" );
使用String文字时,这变得不那么明显了。请记住,当您看到源代码只包含字符周围的引号时,编译器会将其转换为String对象。
CharSequence y = "cat"; // Looks like a CharSequence but is actually a String instance.
"cat"
和new String("cat")
之间存在一些细微的差异,如this other Question中所述,但在此处无关紧要。
此类图可能有助于指导您。我注意到它的Java版本,它们似乎展示了通过这些类和接口产生了多少变化。
除了越来越多的emoji以及Unicode支持的连续版本附带的其他字符之外,近年来Java在处理文本方面没有太大变化......直到Java 13.
Java 13可能会提供新功能的预览:文本块。这将使编写嵌入式代码字符串(如SQL)更加方便。请参阅JEP 355。
答案 2 :(得分:21)
CharSequence
是合约(interface),String
是此合约的implementation。
public final class String extends Object
implements Serializable, Comparable<String>, CharSequence
CharSequence
的{{3}}是:
CharSequence是char值的可读序列。这个界面 提供对许多不同类型的char的统一,只读访问 序列。 char值表示Basic中的字符 多语种飞机(BMP)或代理人。请参阅Unicode字符 代表细节。
答案 3 :(得分:11)
除了String实现CharSequence并且String是一个字符序列。
您的代码中会发生以下几件事:
CharSequence obj = "hello";
这会创建一个String
文字"hello"
,这是一个String
对象。作为实现String
的{{1}},它也是CharSequence
。 (例如,您可以阅读this post about coding to interface。)
下一行:
CharSequence
有点复杂。 Java中的String str = "hello";
文字保存在池中(实习),因此此行上的String
与第一行上的"hello"
是同一个对象(标识)。因此,此行仅将"hello"
字面值分配给String
。
此时,str
和obj
都是对str
文字String
的引用,因此"hello"
,equals
和他们是==
和String
。
我建议你测试一下这段代码,然后展示我刚写的内容:
CharSequence
答案 4 :(得分:2)
我知道它有点明显,但CharSequence是一个接口,而String是一个具体的类:)
java.lang.String是此接口的实现...
答案 5 :(得分:2)
考虑使用UTF-8。在UTF-8中,Unicode代码点由一个或多个字节构成。封装UTF-8字节数组的类可以实现CharSequence接口,但最明显不是String。当然,你无法传递一个UTF-8字节数组,其中需要一个String,但是当放宽合约以允许CharSequence时,你当然可以传递一个实现CharSequence的UTF-8包装器类。在我的项目中,我正在开发一个名为CBTF8Field(压缩二进制传输格式 - 八位)的类,为xml提供数据压缩,我希望使用CharSequence接口实现从CBTF8字节数组到字符数组(UTF-16)的转换)和字节数组(UTF-8)。
我来到这里的原因是为了完全理解后续合同。
答案 6 :(得分:1)
来自CharSequence的Java API:
CharSequence是一个可读的字符序列。该接口提供对许多不同类型字符序列的统一,只读访问。
然后String,CharBuffer和StringBuffer使用此界面来保持所有方法名称的一致性。
答案 7 :(得分:0)
在charSequence中,您没有可用于String的非常有用的方法。如果您不想查看文档,请键入: OBJ。 和 海峡。
并了解您的compilator为您提供的方法。这对我来说是个基本的区别。