몇 분 전에 this question을 보았고 +
연산자에 대한 오버로드가 있는지 확인하기 위해 java String 클래스를 살펴보기로 결정했습니다.+ Java의 String에 대한 연산자
는 난 아무것도 찾을 수 없습니다,하지만 난이
String ab = "ab";
String cd = "cd";
String both = ab + cd; //both = "abcd"
경우 그 구현있어 할 수있어?
몇 분 전에 this question을 보았고 +
연산자에 대한 오버로드가 있는지 확인하기 위해 java String 클래스를 살펴보기로 결정했습니다.+ Java의 String에 대한 연산자
는 난 아무것도 찾을 수 없습니다,하지만 난이
String ab = "ab";
String cd = "cd";
String both = ab + cd; //both = "abcd"
경우 그 구현있어 할 수있어?
:
Java 언어는 문자열 연결 연산자 (+)에 대한 특별 지원을 제공하고, 문자열에 다른 개체의 변환. 문자열 연결은
StringBuilder
(또는StringBuffer
) 클래스와append
메서드를 통해 구현됩니다. 문자열 변환은 Object로 정의되고 Java의 모든 클래스에서 상속되는 toString 메서드를 통해 구현됩니다. 문자열 연결 및 변환에 대한 추가 정보는 Gosling, Joy 및 Steele, Java 언어 사양을 참조하십시오.
JLS에서 String Concatenation을 참조하십시오.
컴파일러에서 처리합니다. Fine Manual에서
인상적인 대답입니다. 선생님이라고 생각 했니? – whiskeysierra
@Willi Schönborn : 간단하고 정확한 답변입니다. 필자는 필자가 글을 쓸 때 더 쓸 시간이 없었으며 컴퓨터에 돌아 왔을 때 더 자세히 설명하는 답변이 많았다. 죄송하지만, 다른 답변을 복제 할 시점이 보이지 않습니다. 자세한 정보가 필요하면 @ Sean 's 및 @ jleedev 's를 읽는 것이 좋습니다. (그렇습니다. 강의는 내 이력서에 있습니다.) – Fredrik
요점은 : 귀하의 답변은 매우 일반적이므로 거의 모든 Java 관련 질문 중 ~ 75 %에 해당됩니다. – whiskeysierra
언어 수준에서 완료되었습니다. Java 언어 사양은 very specific about what string addition must do입니다.
이것은 특수 동작으로 language specification에 설명되어 있습니다.
15.18.1 문자열 병합 연산자 +
하나의 피연산자식이 String 형의 경우, 문자열 변환이 런타임에 캐릭터 라인을 에 다른 피연산자에서 수행됩니다. 두 피연산자 문자열 연결 한합니다 ( 식 컴파일 시간 상수 식 (§15.28)이 아닌 경우, 새로 생성 된)를 결과는 문자열 객체에 대한 참조이다. 왼손 피연산자의 문자는 새로 작성된 문자열의 오른쪽 피연산자 의 자 앞에옵니다. String 유형의 피연산자 이 null 인 경우 피연산자 대신 문자열 "null"이 사용됩니다.
String both = new StringBuilder().append(ab).append(cd).toString();
편집 :
이 컴파일러는 당신이 뭔가를 쓴 것처럼 코드를 처리하는 언급을? 글쎄, 내가 컴파일하고 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
그래서 내가 말했듯이.
입니까? –
String
은 컴파일러 수준에서 int, double, float 등과 같은 표준 유형으로 정의됩니다. 기본적으로 모든 컴파일러에는 연산자 오버로드가 있습니다. 개발자 오버로드는 개발자를 위해 정의되지 않았습니다 (C++과 달리).
흥미롭게 :이 질문은 버그로 기록되었다 http://bugs.sun.com/view_bug.do?bug_id=4905919
여기에 대한 답변의 대부분은 (는 컴파일러에 의해 처리하는 것, +) (으로 .Append로 변환됩니다 ...)
올바른지 나는 모든 사람들이 String의 소스 코드를 살펴보고 어떤 시점에 추가해야한다고 덧붙이고 싶다. 꽤 인상적이다.
"a"+"b"+"c"
=
new String().append("a").append("b").append("c")
하지만 마법이 발생합니다
가 나는 같은 것을 내려왔다 생각합니다.
에 두 번째
"abc"문자열이 있고 "bc"가되는 부분 문자열을 요청하면 트릭을 만들 수 있습니다. 여기서 동일한 기본 배열을 공유 할 수 있습니다. 시작 위치, 끝 위치 및 "공유"플래그가 있음을 알 수 있습니다. 이 공유되어 있지 않은 경우는 문자열의 길이를 연장하고있는 다른 사람을 복사합니다.
지금 난 그냥 혼란되고있어하는는 사실, 그것은 가능합니다. 소스 코드를 읽으십시오 - 매우 멋집니다.
새로운 StringBuilder(). append ("a")는 append ("b"). append ("b")가 아니고 새로운 String(). * no-stringbuilder * 웨이는''a ".concat ("b "). concat ("c ")'이 될 것이고, 이것은 다음과 같이 비효율적이다. (그러나 컴파일 타임 상수와 함께 +를 사용하면이 모든 것이 이미 컴파일러에 의해 수행됩니다.) –
동기화가 중요하지 않은 경우'StringBuilder'가 선호됩니다. – gpampara
@gpampara 컴파일러는 StringBuilder를 사용합니다. StringBuffer는 StringBuilder가 도입되기 전에 이전 릴리스에서 사용되었습니다. 이 모든 것에 대한 참조는 –