최근에, 내가 직업을 찾고있을 때, 심사관은 "StringBuffer와 StringBuilder의 차이, 그들의 응용 프로그램 시나리오는 무엇입니까?" 편집자의 답변은 아래에서 귀하와 공유되므로 모든 사람이 미래에 배우는 것이 편리하여 기록을 만들 수 있습니다.
실제로 Google 마스터를 찾으면 답이 있습니다. StringBuffer는 StringBuilder의 메소드 및 기능과 완전히 동일하지만 StringBuffer의 대부분의 메소드는 수정에 동기화 된 키워드를 사용하므로 스레드 안전입니다. 이 수정이 없으면 StringBuilder는 스레드-미사일로 간주 될 수 있습니다.
위의 답변을 더 잘 이해하려면 StringBuffer 및 StringBuilder의 소스 코드 구현이 더 현실적임을 직접 확인하는 것이 좋습니다. 프로그래머로서 "궁금한 점이 있으면 소스 코드를보십시오"가 올바른 방법입니다. 물론 책임감있게 말할 수 있습니다. 물론 조건이 있어야합니다!
JDK의 구현에서 StringBuffer와 StringBuilder는 모두 AbstractStringBuilder에서 상속됩니다. 멀티 스레딩의 보안 및 비 안전을 위해 StringBuffer의 동기화 된 방법을 대략적으로 이해하게됩니다.
여기서 나는 AbstractStringBuilder의 구현 원리에 대해 간단히 이야기 할 것입니다. StringBuffer를 사용하면 String Connection에 직접 +를 사용하는 경우 JVM이 여러 개의 문자열 객체를 생성하기 때문에 Java의 문자열 연결 효율을 향상시키는 것 이상이라는 것을 알고 있습니다. AbstractStringBuilder는 숯 배열을 사용하여 추가 해야하는 문자열을 저장합니다. 숯 배열의 초기 크기가 있습니다. 부록 문자열이 현재 숯 배열 용량을 초과하면 숯 배열이 동적으로 확장됩니다. 메모리 및 복사 재 할소니다. 메모리 공간에 다시 적용 할 때마다 메모리 공간이 필요한 전류보다 큰 방식으로, 즉 2 배가됩니다.
다음으로 재미있게 보내십시오!
Google의 몇 가지 정보는 다음과 같습니다.
【
StringBuffer는 JDK 1.0으로 시작했습니다
StringBuilder는 JDK 1.5로 시작했습니다
JDK 1.5에서 시작하여 문자열 변수가있는 연결 작업 (+)은 JVM에서 내부적으로 사용됩니다.
StringBuilder가 구현 되었으며이 작업은 StringBuffer를 사용하여 구현되었습니다.
】
간단한 프로그램을 통해 실행 프로세스를 살펴 봅니다.
목록 1 buffer.java
공개 클래스 버퍼 {public static void main (String [] args) {String s1 = "aaaaa"; 문자열 s2 = "bbbbbb"; 문자열 r = null; int i = 3694; R = S1 + I + S2; for (int j = 0; i <10; j ++) {r+= "23124"; }}}Javap -C 버퍼 명령을 사용하여 바이트 코드 구현을보십시오.
목록 2 버퍼 클래스 바이트 코드
해당 목록 1 및 목록 2, 목록 2의 LDC 명령어는 상수 풀에서 스택 상단으로 "AAAA"문자열을로드하고 ISTORE_1은 변수 1에 "AAAAA"를 저장합니다. 다음은 동일합니다. Sipush는 짧은 정수 상수 값 (-32768 ~ 32767)을 스택 상단으로 밀어 넣습니다. 다음은 상수 "3694"입니다. 더 많은 Java 명령어 세트는 다른 기사 "Java Instruction Set"을 확인하십시오.
13, 13 ~ 17이 StringBuffer 객체를 처음 사용하고 초기화 방법을 호출한다는 것을 직접 보자. 20 ~ 21은 먼저 변수 1을 Aload_1을 통해 스택 상단에 누릅니다. 앞에서 언급했듯이 변수 1은 문자열 상수 "aaaaa"에 넣은 다음 "aaaaa"를 함께 스플 라이스로 intruction in instruction을 통해 Stringbuffer의 부록 메소드를 호출합니다. 다음 24 ~ 30은 동일합니다. 마지막으로, 33에서, StringBuffer의 Tostring 함수는 문자열 결과를 얻기 위해 호출되고 매장을 통해 변수 3에 저장됩니다.
우리가 이것을 볼 때, 누군가는 "JVM은 StringBuffer를 사용하여 문자열을 연결하기 때문에 StringBuffer를 스스로 사용할 필요가 없으며"+"Just!" 그게 사실인가요? 물론. "존재의 이유가 있습니다"라는 말이 진행되면서 후속 루프에 해당하는 바이트 코드를 계속 살펴 보겠습니다.
37 ~ 42는 FOR 루프를 입력하기 전에 약간의 준비입니다. 37, 38 설정 j ~ 1. 44 여기서, if_icmpge는 j를 10과 비교합니다. j가 10보다 크면 73으로 직접 점프하면 리턴 문이 함수를 종료합니다. 그렇지 않으면 루프, 즉 47 ~ 66의 바이트 코드로 들어갑니다. 여기서는 "+"작업을 수행 할 때마다 "+"작업을 수행 할 때마다 새로운 StringBuffer 객체를 사용하여 문자열 연결을 처리해야하기 때문에 Code에서 StringBuffer를 사용하는 이유를 알기 위해 47 ~ 51 만 살펴 봐야합니다. 많은 문자열 연결 작업이 관련 될 때 매우 비쌉니다.