Android에서 프로그래밍하면 대부분의 텍스트 값이로 예상됩니다 CharSequence
.
왜 그런 겁니까? 장점은 무엇이며, CharSequence
over 를 사용할 때의 주된 영향은 String
무엇입니까?
주요 차이점은 무엇이며 어떤 문제를 사용하고 서로 변환하면서 어떤 문제가 예상됩니까?
답변
문자열은 CharSequences 이므로 문자열을 사용할 수 있으며 걱정할 필요가 없습니다. Android는 StringBuffers와 같은 다른 CharSequence 객체도 지정할 수 있도록함으로써 도움을 주려고합니다.
답변
CharSequence
= 인터페이스
String
= 구체적인 구현
CharSequence
인 인터페이스 .- 여러 클래스 가이 인터페이스를 구현 합니다.
String
의 하나의 구체적인 구현입니다CharSequence
.
당신은 말했다 :
하나에서 다른 것으로 변환
에서 변환하는 것이 없습니다 String
.
- 모든
String
대상 는 입니다CharSequence
. - 모든
CharSequence
생산할 수 있습니다String
. 전화하십시오CharSequence::toString
.CharSequence
발생하는 경우String
메서드는 자체 객체에 대한 참조를 반환합니다.
다시 말해 모든 String
것이 a CharSequence
이지만 모든 CharSequence
것이 a는 아닙니다 String
.
인터페이스 프로그래밍
안드로이드 프로그래밍, 대부분의 텍스트 값은 CharSequence에서 예상됩니다.
왜 그런 겁니까? CharSequence over String을 사용하면 어떤 이점이 있습니까?
일반적으로 인터페이스 프로그래밍은 구체적인 클래스 프로그래밍보다 낫습니다. 이는 유연성을 제공하므로 다른 코드를 손상시키지 않고 특정 인터페이스의 구체적인 구현간에 전환 할 수 있습니다.
API를 개발할 때다양한 상황에서 다양한 프로그래머가 사용할 를 가능한 가장 일반적인 인터페이스를 제공하고 사용하도록 코드를 작성하십시오. 이것은 호출 프로그래머에게 해당 인터페이스의 다양한 구현을 자유롭게 사용할 수 있도록합니다. 구현은 특정 상황에 가장 적합합니다.
예를 들어, Java Collections Framework를보십시오 . 당신의 API가 제공 또는 객체의 정렬 된 컬렉션을 소요하는 경우, 사용과 같이 메소드를 선언 List
하기보다는 ArrayList
, LinkedList
또는 다른 어떤 제 3 자 구현 List
.
여러 장소에서 사용되는 API를 작성하는 것과 달리 특정 장소에서 코드 만 사용하는 빠르고 더러운 작은 방법을 작성할 때 특정 콘크리트가 아닌 일반적인 인터페이스를 사용하는 데 신경 쓰지 않아도됩니다. 수업. 그러나 그럼에도 불구하고 가능한 가장 일반적인 인터페이스를 사용하는 것은 상처를줍니다.
주요 차이점은 무엇이며 예상되는 문제는 무엇입니까?
String
당신은 전적으로 메모리에 하나의 텍스트가 있고 불변 이라는 것을 알고 있습니다.- 를 사용
CharSequence
하면 구체적인 구현의 특정 기능이 무엇인지 알 수 없습니다.
CharSequence
객체는 텍스트의 거대한 덩어리를 나타내고, 따라서 메모리 의미를 가지고 있습니다. 또는를 호출 할 때 함께 스티칭해야 toString
하므로 성능 문제가 있는 별도의 추적 된 텍스트 덩어리가있을 수 있습니다. 구현시 원격 서비스에서 텍스트를 검색 할 수도 있으므로 대기 시간에 영향을 미칩니다.
서로 변환합니까?
일반적으로 앞뒤로 변환하지 않습니다. A String
는 입니다 CharSequence
. 메소드가을 사용한다고 선언 CharSequence
하면 호출 프로그래머가 String
객체를 전달 StringBuffer
하거나 a 또는와 같은 다른 것을 전달할 수 있습니다 StringBuilder
. 메소드의 코드는 전달 된 모든 것을 사용하여 CharSequence
메소드를 호출합니다 .
변환에 가장 가까운 것은 코드에 a가 수신되고 a CharSequence
가 필요한 경우 String
입니다. 아마도 당신은 인터페이스에 쓰여지지 String
않고 클래스에 쓰여진 오래된 코드와 인터페이스하고있을 것입니다 CharSequence
. 또는 반복적으로 반복하거나 분석하는 것과 같이 코드에서 텍스트를 집중적으로 사용할 수 있습니다. 이 경우 가능한 성능 저하를 한 번만 수행하려고합니다.toString
. 그런 다음 완전히 기억에 담긴 단일 텍스트로 알고있는 것을 사용하여 작업을 진행하십시오.
뒤틀린 역사
허용 된 답변 에 대한 의견을 적어 둡니다 . CharSequence
인터페이스는 기존의 클래스 구조로 개조, 그래서 몇 가지 중요한 미묘이 (가 equals()
& hashCode()
). 클래스 / 인터페이스에 태그가 지정된 다양한 버전의 Java (1, 2, 4 및 5)에 주목하십시오. 이상적으로 CharSequence
처음부터 자리 잡았을 것입니다.
아래의 클래스 다이어그램은 Java 7/8에서 문자열 유형의 큰 그림을 보는 데 도움이 될 수 있습니다. 이 모든 것이 Android에 있는지 확실하지 않지만 전반적인 컨텍스트가 여전히 유용 할 수 있습니다.
답변
CharSequence를 사용하는 것이 가장 좋습니다. 그 이유는 String이 CharSequence를 구현하기 때문에 CharSequence에 String을 전달할 수 있지만 CharSequence는 String을 구현하지 않기 때문에 CharSequence를 String에 전달할 수 없다는 것입니다. 또한 Android에서이 EditText.getText()
메소드는 Editable을 리턴합니다. 이 메소드는 CharSequence도 구현하며 쉽게 문자열로 전달되지 않고 하나에 전달 될 수 있습니다. CharSequence는 모든 것을 처리합니다!
답변
일반적으로 인터페이스를 사용하면 최소한의 부수적 피해로 구현을 변경할 수 있습니다. java.lang.String은 매우 인기가 있지만 특정 상황에서 다른 구현을 사용하고 싶을 수도 있습니다. 문자열이 아닌 CharSequences를 중심으로 API를 빌드하면 코드에서이를 수행 할 수 있습니다.
답변
이것은 거의 확실하게 성능상의 이유입니다. 예를 들어 문자열이 포함 된 500k ByteBuffer를 통과하는 파서를 상상해보십시오.
문자열 내용을 반환하는 방법에는 3 가지가 있습니다.
-
구문 분석시 한 번에 한 문자 씩 String []을 작성하십시오. 시간이 많이 걸립니다. 캐시 된 참조를 비교하기 위해 .equals 대신 ==를 사용할 수 있습니다.
-
구문 분석시 오프셋을 사용하여 int []를 빌드 한 다음 get ()이 발생할 때 동적으로 문자열을 빌드하십시오. 각 문자열은 새 객체이므로 반환 값을 캐싱하지 않고 ==
-
구문 분석시 CharSequence []를 빌드하십시오. 바이트 버퍼로의 오프셋 이외의 새로운 데이터가 저장되지 않기 때문에 구문 분석은 # 1보다 훨씬 낮습니다. 얻을 때 String을 만들 필요가 없으므로 기존 객체에 대한 참조 만 반환하므로 성능은 # 1과 동일합니다 (# 2보다 훨씬 낫습니다).
CharSequence를 사용하면 얻을 수있는 처리 이점 외에도 데이터를 복제하지 않음으로써 메모리 공간을 줄일 수 있습니다. 예를 들어, 3 개의 텍스트 단락이 포함 된 버퍼가 있고 3 개 또는 단일 단락을 모두 반환하려는 경우이를 나타내려면 4 개의 문자열이 필요합니다. CharSequence를 사용하면 데이터가 포함 된 1 개의 버퍼와 시작 및 길이를 추적하는 CharSequence 구현의 4 개 인스턴스 만 필요합니다.
답변
실제 Android 코드에서 발생하는 문제는 CharSequence.equals와 비교하는 것이 유효하지만 반드시 의도 한대로 작동하지는 않는다는 것입니다.
EditText t = (EditText )getView(R.id.myEditText); // Contains "OK"
Boolean isFalse = t.getText().equals("OK"); // will always return false.
비교는
("OK").contentEquals(t.GetText());
답변
CharSequence
A CharSequence
는 실제 클래스가 아닌 인터페이스입니다. 인터페이스는 인터페이스를 구현하는 경우 클래스에 포함해야하는 일련의 규칙 (방법)입니다. Android에서 a CharSequence
는 다양한 유형의 텍스트 문자열을위한 우산입니다. 다음은 일반적인 것들입니다.
String
(스타일 범위가없는 불변 텍스트)StringBuilder
(스타일 범위가없는 변경 가능한 텍스트)SpannableString
(스타일링 범위가있는 불변 텍스트)SpannableStringBuilder
(스타일 범위가있는 변경 가능한 텍스트)
( 여기 에서 차이점에 대한 자세한 내용은 여기를 참조하십시오 .)
CharSequence
객체 가 있으면 실제로 구현하는 클래스 중 하나의 객체입니다 CharSequence
. 예를 들면 다음과 같습니다.
CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
일반적인 우산 유형과 같은 장점은 CharSequence
단일 방법으로 여러 유형을 처리 할 수 있다는 것입니다. 예를 들어 CharSequence
매개 변수로 a를 사용 하는 메서드가 있으면 a String
또는 a를 전달할 수 있으며 SpannableStringBuilder
둘 중 하나를 처리합니다.
public int getLength(CharSequence text) {
return text.length();
}
끈
a String
는 단지 한 종류 일 뿐이라고 말할 수 CharSequence
있습니다. 그러나와 달리 CharSequence
실제 클래스이므로 객체를 만들 수 있습니다. 그래서 당신은 이것을 할 수 있습니다 :
String myString = new String();
그러나 당신은 이것을 할 수 없습니다 :
CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated
준수하는 CharSequence
규칙 목록 일 뿐이 므로 String
다음을 수행 할 수 있습니다.
CharSequence myString = new String();
즉, 메소드가을 요청할 때마다을 지정하는 CharSequence
것이 String
좋습니다.
String myString = "hello";
getLength(myString); // OK
// ...
public int getLength(CharSequence text) {
return text.length();
}
그러나 그 반대는 사실이 아닙니다. 메소드가 String
매개 변수를 사용 하는 경우 CharSequence
실제로는 SpannableString
또는 다른 종류 일 수 있기 때문에 일반적으로로만 알려진 것을 전달할 수 없습니다 CharSequence
.
CharSequence myString = "hello";
getLength(myString); // error
// ...
public int getLength(String text) {
return text.length();
}