java中CharSequence和String之间的确切区别

时间:2012-07-04 07:00:36

标签: java string charsequence

我读了这个previous post。任何人都可以说CharSequence和String之间的确切区别是什么,String实现CharSequenceString是一个字符序列的事实?例如:

CharSequence obj = "hello";
String str = "hello";
System.out.println("output is : " + obj + "  " + str);

将“hello”分配给obj并再次分配给str时会发生什么?

8 个答案:

答案 0 :(得分:95)

一般差异

除了CharSequence之外,有几个类实现了String接口。其中有

  • StringBuilder用于可修改的可变长度字符序列
  • CharBuffer用于可修改的固定长度低级字符序列

任何接受CharSequence的方法都可以同样适用于所有这些方法。任何只接受String的方法都需要转换。因此,在您不关心内部的所有地方使用CharSequence作为参数类型是谨慎的。但是,如果实际返回String,则应使用String作为返回类型,因为如果调用方法确实需要String,则可以避免返回值的可能转换。

另请注意,地图应使用String作为键类型,而不是CharSequence,因为地图键不得更改。换句话说,有时String的不可变性是必不可少的。

特定代码段

至于您粘贴的代码:只需编译它,然后使用javap -v查看JVM字节码。在那里,您会注意到objstr都是对同一个常量对象的引用。由于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)

TL;博士

一个是接口(CharSequence),而另一个是该接口的具体实现(String)。

CharSequence animal = "cat"  // `String` object presented as the interface `CharSequence`.

作为一个接口,通常CharSequenceString更常见,但是一些扭曲的历史导致接口在实施后定义。因此,在较旧的API中,我们经常看到String,而在较新的API中,我们倾向于看到CharSequence用于定义参数和返回类型。

详细

如今我们知道API /框架通常应该主要关注导出接口,其次是具体类。但我们并不总是很清楚这一课。

String类在Java中排在第一位。直到后来他们才放置了一个面向前的界面CharSequence

扭曲历史

一点历史可能有助于理解。

早期,由于互联网/网络狂热使该行业充满活力,Java急于推出市场。有些图书馆并没有像他们应该的那样经过深思熟虑。字符串处理是其中一个领域。

此外,Java是最早的以生产为导向的非学术Object-Oriented Programming (OOP)环境之一。在此之前,OOP唯一成功的现实橡胶实现道路实施是SmallTalk的一些限制版本,然后是Objective-CNeXTSTEP / OpenStep。因此,许多实践课程尚未学习。

Java以String类和StringBuffer类开头。但是这两个类是无关的,没有通过继承和接口相互联系。后来,Java团队认识到字符串相关实现之间应该存在统一的联系,以使它们可以互换。在Java 4中,团队添加了CharSequence接口,并在String和String Buffer上追溯实现了该接口,并添加了另一个实现CharBuffer。后来在Java 5中,他们添加了StringBuilder,基本上是StringBuffer的非同步版本,因此速度更快。

所以这些面向字符串的类有点混乱,而且有点混乱。构建了许多库和接口来获取和返回String个对象。现在通常应该构建这样的库以期望CharSequence。但是(a)String似乎仍然主导着思维空间,并且(b)在混合各种CharSequence实现时可能存在一些微妙的技术问题。事后看来,我们可以看到所有这些字符串的东西可以更好地处理,但我们在这里。

理想情况下,Java应该从一个接口和/或超类开始,这些接口和/或超类将在我们现在使用String的许多地方使用,就像我们使用CollectionList接口一样ArrayListLinkedList实施的位置。

界面与班级

关于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版本,它们似乎展示了通过这些类和接口产生了多少变化。

diagram showing the various string-related classes and interfaces as of Java 8

文本块

除了越来越多的emoji以及Unicode支持的连续版本附带的其他字符之外,近年来Java在处理文本方面没有太大变化......直到Java 13.

Java 13可能会提供新功能的预览:文本块。这将使编写嵌入式代码字符串(如SQL)更加方便。请参阅JEP 355

这项工作之前是JEP 326: Raw String Literals (Preview)

答案 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

此时,strobj都是对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是一个可读的字符序列。该接口提供对许多不同类型字符序列的统一,只读访问。

然后StringCharBufferStringBuffer使用此界面来保持所有方法名称的一致性。

答案 7 :(得分:0)

在charSequence中,您没有可用于String的非常有用的方法。如果您不想查看文档,请键入:    OBJ。 和    海峡。

并了解您的compilator为您提供的方法。这对我来说是个基本的区别。