2010-02-24 4 views
7

몇 분 전에 this question을 보았고 + 연산자에 대한 오버로드가 있는지 확인하기 위해 java String 클래스를 살펴보기로 결정했습니다.+ Java의 String에 대한 연산자

는 난 아무것도 찾을 수 없습니다,하지만 난이

String ab = "ab"; 
String cd = "cd"; 
String both = ab + cd; //both = "abcd" 

경우 그 구현있어 할 수있어?

답변

12

:

Java 언어는 문자열 연결 연산자 (+)에 대한 특별 지원을 제공하고, 문자열에 다른 개체의 변환. 문자열 연결은 StringBuilder (또는 StringBuffer) 클래스와 append 메서드를 통해 구현됩니다. 문자열 변환은 Object로 정의되고 Java의 모든 클래스에서 상속되는 toString 메서드를 통해 구현됩니다. 문자열 연결 및 변환에 대한 추가 정보는 Gosling, Joy 및 Steele, Java 언어 사양을 참조하십시오.

JLS에서 String Concatenation을 참조하십시오.

+0

동기화가 중요하지 않은 경우'StringBuilder'가 선호됩니다. – gpampara

+0

@gpampara 컴파일러는 StringBuilder를 사용합니다. StringBuffer는 StringBuilder가 도입되기 전에 이전 릴리스에서 사용되었습니다. 이 모든 것에 대한 참조는 –

2

컴파일러에서 처리합니다. Fine Manual에서

+1

인상적인 대답입니다. 선생님이라고 생각 했니? – whiskeysierra

+0

@Willi Schönborn : 간단하고 정확한 답변입니다. 필자는 필자가 글을 쓸 때 더 쓸 시간이 없었으며 컴퓨터에 돌아 왔을 때 더 자세히 설명하는 답변이 많았다. 죄송하지만, 다른 답변을 복제 할 시점이 보이지 않습니다. 자세한 정보가 필요하면 @ Sean 's 및 @ jleedev 's를 읽는 것이 좋습니다. (그렇습니다. 강의는 내 이력서에 있습니다.) – Fredrik

+0

요점은 : 귀하의 답변은 매우 일반적이므로 거의 모든 Java 관련 질문 중 ~ 75 %에 해당됩니다. – whiskeysierra

2

이것은 특수 동작으로 language specification에 설명되어 있습니다.

15.18.1 문자열 병합 연산자 +

하나의 피연산자식이 String 형의 경우, 문자열 변환이 런타임에 캐릭터 라인을 에 다른 피연산자에서 수행됩니다. 두 피연산자 문자열 연결 한합니다 ( 식 컴파일 시간 상수 식 (§15.28)이 아닌 경우, 새로 생성 된)를 결과는 문자열 객체에 대한 참조이다. 왼손 피연산자의 문자는 새로 작성된 문자열의 오른쪽 피연산자 의 자 앞에옵니다. String 유형의 피연산자 이 null 인 경우 피연산자 대신 문자열 "null"이 사용됩니다.

String both = new StringBuilder().append(ab).append(cd).toString(); 

편집 :

7

이 컴파일러는 당신이 뭔가를 쓴 것처럼 코드를 처리하는 언급을? 글쎄, 내가 컴파일하고 OP의 코드를 디 컴파일하면 얻을 :

0: ldC#2; //String ab 
2: astore_1 
3: ldC#3; //String cd 
5: astore_2 
6: new #4; //class java/lang/StringBuilder 
9: dup 
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V 
13: aload_1 
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
17: aload_2 
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
24: astore_3 
25: return 

그래서 내가 말했듯이.

+1

입니까? –

0

String은 컴파일러 수준에서 int, double, float 등과 같은 표준 유형으로 정의됩니다. 기본적으로 모든 컴파일러에는 연산자 오버로드가 있습니다. 개발자 오버로드는 개발자를 위해 정의되지 않았습니다 (C++과 달리).

흥미롭게 :이 질문은 버그로 기록되었다 http://bugs.sun.com/view_bug.do?bug_id=4905919

2

여기에 대한 답변의 대부분은 (는 컴파일러에 의해 처리하는 것, +) (으로 .Append로 변환됩니다 ...)

올바른지 나는 모든 사람들이 String의 소스 코드를 살펴보고 어떤 시점에 추가해야한다고 덧붙이고 싶다. 꽤 인상적이다.

"a"+"b"+"c" 

=

new String().append("a").append("b").append("c") 

하지만 마법이 발생합니다

가 나는 같은 것을 내려왔다 생각합니다.

  • 가 제 위치로 길이의 문자열 배열 3
  • 복사본을 작성이로 변한다. 세 번째
  • 대부분의 사람들이 그 다음, "AB"를 만들 수는 "ABC"를 만들 때 그것을 버릴 것이라고 믿는다 반면

에 두 번째

  • 복사 C에 B
  • 사본. 그것은 실제로 그것이 연결되어 있고 약간 조작을한다는 것을 이해합니다.

    "abc"문자열이 있고 "bc"가되는 부분 문자열을 요청하면 트릭을 만들 수 있습니다. 여기서 동일한 기본 배열을 공유 할 수 있습니다. 시작 위치, 끝 위치 및 "공유"플래그가 있음을 알 수 있습니다. 이 공유되어 있지 않은 경우는 문자열의 길이를 연장하고있는 다른 사람을 복사합니다.

    지금 난 그냥 혼란되고있어하는

    는 사실, 그것은 가능합니다. 소스 코드를 읽으십시오 - 매우 멋집니다.

  • +1

    새로운 StringBuilder(). append ("a")는 append ("b"). append ("b")가 아니고 새로운 String(). * no-stringbuilder * 웨이는''a ".concat ("b "). concat ("c ")'이 될 것이고, 이것은 다음과 같이 비효율적이다. (그러나 컴파일 타임 상수와 함께 +를 사용하면이 모든 것이 이미 컴파일러에 의해 수행됩니다.) –