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

Ami*_*ith 100 java string charsequence

我读过上一篇文章.任何人都可以说CharSequence和String 之间的确切区别是什么,除了String实现的事实CharSequence和那String是一个字符序列?例如:

CharSequence obj = "hello";
String str = "hello";
System.out.println("output is : " + obj + "  " + str);
Run Code Online (Sandbox Code Playgroud)

当"hello"分配给obj和再次分配时会发生什么str

MvG*_*MvG 99

一般差异

除此之外还有几个实现CharSequence接口的类String.其中有

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

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

另请注意,地图应该String用作键类型,而不是CharSequence因为地图键不能更改.换句话说,有时不可改变的本质String是必不可少的.

具体代码段

至于您粘贴的代码:只需编译它,并查看使用的JVM字节码javap -v.在那里,你会发现这两个objstr是同一个常量对象的引用.作为一个String不可改变的,这种分享是可以的.

编译器的+运算符String被编译为各种StringBuilder.append调用的调用.所以它相当于

System.out.println(
  (new StringBuilder())
  .append("output is : ")
  .append((Object)obj)
  .append(" ")
  .append(str)
  .toString()
)
Run Code Online (Sandbox Code Playgroud)

我必须承认,我有点惊讶我的编译器javac 1.6.0_33编译+ obj使用StringBuilder.append(Object)而不是StringBuilder.append(CharSequence).前者可能涉及toString()对对象方法的调用,而后者应该以更有效的方式进行.另一方面,String.toString()简单地返回String自己,所以那里没有什么惩罚.因此, StringBuilder.append(String)通过一个方法调用可能会更有效.


Bas*_*que 85

TL;博士

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

CharSequence animal = "cat"  // `String` object presented as the interface `CharSequence`.
Run Code Online (Sandbox Code Playgroud)

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

细节

现在我们知道API /框架通常应该主要关注导出接口,其次是具体类.但我们并不总是如此了解这一课.

String课程首先在Java中出现.后来他们才放置了一个面向前方的界面CharSequence.

扭曲的历史

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

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

此外,Java是最早面向生产的非学术性面向对象编程(OOP)环境之一.OOP之前唯一成功的现实橡胶 - 道路实现OOP是一些有限版本的SmallTalk,然后是带有NeXTSTEP/OpenStep的Objective-C.因此,许多实践课程尚未学习.

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在于它是一个接口,而不是一个实现.这意味着你无法直接实例化CharSequence.而是实例化实现该接口的类之一.

例如,这里我们x看起来像一个CharSequence但下面实际上是一个StringBuilder对象.

CharSequence x = new StringBuilder( "dog" );
Run Code Online (Sandbox Code Playgroud)

使用String文字时,这变得不那么明显了.请记住,当您看到源代码只包含字符周围的引号时,编译器会将其转换为String对象.

CharSequence y = "cat";  // Looks like a CharSequence but is actually a String instance.
Run Code Online (Sandbox Code Playgroud)

有一些细微的差异"cat",并new String("cat")在讨论这个问题的其他,但这里无关紧要.

类图

此类图可能有助于指导您.我注意到它的Java版本,它们似乎展示了通过这些类和接口产生了多少变化.

该图显示了Java 8中各种与字符串相关的类和接口

原始字符串文字

除了越来越多的表情符号和其他带有连续版本的Unicode支持的角色之外,近年来Java在处理文本方面没有太大变化......直到Java 12或13.

Java 12可能会也可能不会提供新功能的预览:原始字符串文字.这将使编写嵌入式代码字符串(如SQL)更加方便.见JEP 326.

这个JEP提出了一种新的文字,一种原始字符串文字,它将Java转义和Java行终止符规范放在一边,以提供在许多情况下比现有传统字符串文字更易读和可维护的字符序列.

有关更多讨论,请参阅此文章,并阅读Goetz撰写的这篇文章,Raw字符串文字 - 我们在哪里,我们如何到达这里.和维基百科有一个Blurb的.

  • 旧的好学​​校 (2认同)

Fra*_*eth 21

CharSequence是一个合同(接口),String是这个合同的一个实现.

public final class String extends Object 
    implements Serializable, Comparable<String>, CharSequence
Run Code Online (Sandbox Code Playgroud)

文件CharSequence方法是:

CharSequence是char值的可读序列.此接口提供对许多不同类型的char序列的统一,只读访问.char值表示Basic Multilingual Plane(BMP)中的字符或代理项.有关详细信息,请参阅Unicode字符表示.


ass*_*ias 12

除了String实现CharSequence并且String是一个字符序列的事实.

您的代码中会发生以下几件事:

CharSequence obj = "hello";
Run Code Online (Sandbox Code Playgroud)

这创建了一个String文字,"hello"这是一个String对象.作为一个String,它实现CharSequence,它也是一个CharSequence.(你可以阅读这篇关于编码到界面的文章).

下一行:

String str = "hello";
Run Code Online (Sandbox Code Playgroud)

有点复杂.StringJava中的文字保存在池中(实习),因此"hello"此行上的对象(标识)"hello"与第一行中的对象(标识)相同.因此,此行仅指定相同的String文字str.

在这一点上,无论是objstr是引用String的文字"hello",因此equals,==他们均为StringCharSequence.

我建议你测试这段代码,在行动中显示我刚写的内容:

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));
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

112052 次

最近记录:

6 年,5 月 前