Programing

Java에서 CharSequence와 String의 정확한 차이점

crosscheck 2020. 8. 19. 07:37
반응형

Java에서 CharSequence와 String의 정확한 차이점


나는이 이전 포스트를 읽었다 . 구현 CharSequence하는 사실 과 그것이 문자의 시퀀스 라는 사실을 제외하고와 String 의 정확한 차이점을 말할 수 있습니까 ? 예를 들면 :StringCharSequenceString

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

"안녕하세요"가 obj다시 할당 되면 str어떻게 되나요?


일반적인 차이점

CharSequence이외에도 인터페이스 를 구현하는 여러 클래스가 있습니다 String. 이들 중

  • StringBuilder 수정할 수있는 가변 길이 문자 시퀀스 용
  • CharBuffer 수정 될 수있는 고정 길이 저수준 문자 시퀀스 용

a를 받아들이는 모든 메서드 CharSequence는이 모든 것에서 똑같이 잘 작동 할 수 있습니다. String의지 만 허용하는 모든 방법 은 변환이 필요합니다. 따라서 CharSequence내부에 대해 신경 쓰지 않는 모든 곳에서 인수 유형으로 사용 하는 것은 신중합니다. 그러나 String실제로를 반환하는 경우 반환 유형으로 String사용해야합니다 String. 호출하는 메서드에 실제로 .

또한 맵 키는 변경되지 않아야하므로 맵이 String아닌 키 유형으로 CharSequence사용해야합니다. 즉, 때때로의 불변의 본성 String이 필수적입니다.

특정 코드 스 니펫

붙여 넣은 코드에 관해서는 간단히 컴파일하고를 사용하여 JVM 바이트 코드를 살펴보십시오 javap -v. obj모두 str동일한 상수 객체에 대한 참조 임을 알 수 있습니다 . a 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; dr

하나는 인터페이스 ( CharSequence)이고 다른 하나는 해당 인터페이스 ( )의 구체적인 구현입니다 String.

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

인터페이스로서 CharSequence일반적으로는보다 일반적으로 볼 수 String있지만 일부 왜곡 된 역사로 인해 구현 몇 년 후에 인터페이스가 정의 되었습니다 . 따라서 이전 API에서는 종종 String새로운 API에서 CharSequence인수 및 반환 유형을 정의하는 데 사용되는 경향이 있습니다.

세부

요즘 우리는 일반적으로 API / 프레임 워크가 주로 인터페이스를 내보내고 이차적으로 구체적인 클래스를 내보내는 데 집중해야한다는 것을 알고 있습니다. 그러나 우리는 항상이 교훈을 그렇게 잘 알지 못했습니다.

String클래스는 자바에 처음왔다. 나중에 야 전면 인터페이스 인 CharSequence.

뒤틀린 역사

약간의 역사가 이해에 도움이 될 수 있습니다.

초창기 자바는 인터넷 / 웹 매니아가 업계에 활기를 불어 넣었 기 때문에 시대에 앞서 시장에 뛰어 들었습니다. 일부 도서관은 생각보다 잘 생각하지 못했습니다. 문자열 처리는 이러한 영역 중 하나였습니다.

또한 Java는 가장 초기의 프로덕션 지향 비학 업적 객체 지향 프로그래밍 (OOP) 환경 중 하나였습니다 . 유일한 성공 실제 고무 - 만족 - 더 - 도로를 일부 제한 버전이었다 전에 OOP의 구현 스몰 토크 후, 목표 - C넥스트 스텝 / 오픈 스텝을 . 그래서 많은 실용적인 교훈이 아직 배워지지 않았습니다.

Java는 String클래스와 StringBuffer클래스로 시작되었습니다 . 그러나이 두 클래스는 관련이 없으며 상속이나 인터페이스로 서로 연결되어 있지 않습니다. 나중에 Java 팀은 ​​문자열 관련 구현을 상호 교환 할 수 있도록 통합하는 연결이 있어야한다는 것을 인식했습니다. Java 4에서 팀은 CharSequence인터페이스를 추가하고 해당 인터페이스를 String 및 String Buffer에 소급 적으로 구현하고 다른 구현을 추가했습니다 CharBuffer. 나중에 Java 5에서 그들은 StringBuilder기본적으로 동기화되지 않은 StringBuffer.

따라서 이러한 문자열 지향 클래스는 약간 엉망이고 배우기에는 약간 혼란 스럽습니다. 많은 라이브러리와 인터페이스가 String객체 를 가져오고 반환하도록 구축되었습니다 . 오늘날 이러한 라이브러리는 일반적으로 예상대로 구축되어야합니다 CharSequence. 그러나 (a) String여전히 마인드 스페이스를 지배하는 것처럼 보이며 (b) 다양한 CharSequence구현을 혼합 할 때 미묘한 기술적 문제가있을 수 있습니다 . 20/20의 뒤늦은 비전을 통해 우리는이 모든 문자열이 더 잘 처리 될 수 있음을 알 수 있지만 여기에 있습니다.

이상적으로 Java는 또는 구현 대신에 또는 인터페이스를 String사용하는 것처럼 현재 우리가 사용하는 많은 곳에서 사용되는 인터페이스 및 / 또는 수퍼 클래스로 시작했을 것 입니다.CollectionListArrayListLinkedList

인터페이스 대 클래스

The key difference about CharSequence is that it is an interface, not an implementation. That means you cannot directly instantiate a CharSequence. Rather you instantiate one of the classes that implements that interface.

For example, here we have x that looks like a CharSequence but underneath is actually a StringBuilder object.

CharSequence x = new StringBuilder( "dog" );

This becomes less obvious when using a String literal. Keep in mind that when you see source code with just quote marks around characters, the compiler is translating that into a String object.

CharSequence y = "cat";  // Looks like a CharSequence but is actually a String instance.

There are some subtle differences between "cat" and new String("cat") as discussed in this other Question, but are irrelevant here.

Class Diagram

This class diagram may help to guide you. I noted the version of Java in which they appeared to demonstrate how much change has churned through these classes and interfaces.

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

Text Blocks

Other than more and more emoji and other characters that have come with successive versions of Unicode support, in recent years not much has changed in Java for working with text… until Java 13.

Java 13 may offer a preview of the new feature: text blocks. This would make writing embedded code strings such as SQL more convenient. See JEP 355.

This effort was preceded by JEP 326: Raw String Literals (Preview).


CharSequence is a contract (interface), and String is an implementation of this contract.

public final class String extends Object 
    implements Serializable, Comparable<String>, CharSequence

The documentation for CharSequence is:

A CharSequence is a readable sequence of char values. This interface provides uniform, read-only access to many different kinds of char sequences. A char value represents a character in the Basic Multilingual Plane (BMP) or a surrogate. Refer to Unicode Character Representation for details.


other than the fact that String implements CharSequence and that String is a sequence of character.

Several things happen in your code:

CharSequence obj = "hello";

That creates a String literal, "hello", which is a String object. Being a String, which implements CharSequence, it is also a CharSequence. (you can read this post about coding to interface for example).

The next line:

String str = "hello";

is a little more complex. String literals in Java are held in a pool (interned) so the "hello" on this line is the same object (identity) as the "hello" on the first line. Therefore, this line only assigns the same String literal to str.

At this point, both obj and str are references to the String literal "hello" and are therefore equals, == and they are both a String and a CharSequence.

I suggest you test this code, showing in action what I just wrote:

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));
}

I know it a kind of obvious, but CharSequence is an interface whereas String is a concrete class :)

java.lang.String is an implementation of this interface...


Consider UTF-8. In UTF-8 Unicode code points are built from one or more bytes. A class encapsulating a UTF-8 byte array can implement the CharSequence interface but is most decidedly not a String. Certainly you can't pass a UTF-8 byte array where a String is expected but you certainly can pass a UTF-8 wrapper class that implements CharSequence when the contract is relaxed to allow a CharSequence. On my project, I am developing a class called CBTF8Field (Compressed Binary Transfer Format - Eight Bit) to provide data compression for xml and am looking to use the CharSequence interface to implement conversions from CBTF8 byte arrays to/from character arrays (UTF-16) and byte arrays (UTF-8).

The reason I came here was to get a complete understanding of the subsequence contract.


From the Java API of CharSequence:

A CharSequence is a readable sequence of characters. This interface provides uniform, read-only access to many different kinds of character sequences.

This interface is then used by String, CharBuffer and StringBuffer to keep consistency for all method names.


In charSequence you don't have very useful methods which are available for String. If you don't want to look in the documentation, type: obj. and str.

and see what methods your compilator offers you. That's the basic difference for me.

참고URL : https://stackoverflow.com/questions/11323962/exact-difference-between-charsequence-and-string-in-java

반응형