Java: 不同String 相加在内存里的分布?
迷茫
迷茫 2017-04-18 10:30:17
0
3
811
    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";
    String str4 = new String("a");
    String str5 = new String("b");
    String str6= new String("ab");
    
    
    String plus1 = str1 + str2; 
    String plus2 = str1 + "b"; 
    String plus3 = str4 + "b";
    String plus4 = "a" + "b";
    String plus5 = str4 + str5;
    String plus6 = str4 + str2;

string相加有上面的6种情况
我想弄清楚各种情况的区别,我知道的是plus4都是在栈区,所以结果是一个字符串常量池里的常量,但是其他情况呢?
另外,我打印plus1~plus6的地址或者hashcode,发现都是一样的,怎么回事?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

모든 응답(3)
Ty80

1층 답변은 너무 일반적이고, JVM, JDK 버전에 상관없이 메모리 할당을 논하는 것은 엉터리입니다.

질문을 예로 들어보겠습니다.

으아악

이런 종류의 문자열 직접 정의에서는 JVM이 해당 문자열을 메소드 영역의 상수 풀에 직접 할당하기 때문에 문자열을 불변, 즉 스레드로부터 안전한 것으로 간주합니다.

으아악

에는 이 문자열이 힙에 할당되었음을 나타내는 새 키워드가 있습니다. 다음 방법을 사용하여 확인할 수 있습니다. 으아악

plus1~6의 해시코드가 동일한 이유는 String의 해시코드 방식을 다시 작성하지 않았기 때문입니다. String의 기본 해시코드 구현은 다음과 같습니다.

으아악

리터럴 상수만 처리되며, plus1~6의 리터럴 상수는 동일하므로 해시코드 값은 당연히 동일합니다. 그런 다음 해시 코드는 일관성이 있습니다. 이는 jvm에서 할당된 메모리 주소가 일관성이 있다는 의미는 아닙니다.

左手右手慢动作

메모리에 동일한 문자열의 인스턴스가 하나만 있습니다

----------------------구분선------------ --- -

이 답변은 너무 일반적이고 오해의 소지가 있습니다. 이 형제님의 답변을 참고하세요

大家讲道理

위에서 말씀하신 내용이 맞습니다. 동일한 문자열 리터럴은 메서드 영역에서 하나의 값만 갖습니다. 이는 문자열과 문자열 버퍼 간의 사용법에서 일반적으로 언급되는 차이점입니다.

아래에 추가하겠습니다.
String str4 = new String("a");
"a" 리터럴은 jvm의 메소드 영역에 저장됩니다.
str4 개체는 힙에 저장됩니다.
위 문장은 2개의 메모리 주소가 할당되었다는 의미입니다.
스택에는 8가지 기본 유형이 저장되며 returnAddress 및 참조는 스택에 저장되지 않습니다.
해시코드의 사용법은 매칭과 위치결정에 사용됩니다. Baidu에 직접 가서 해시코드와 == 및 같음의 차이점을 알아보세요.
게다가 plus1~6의 메모리 주소도 확실히 다릅니다. 어떻게 동일하다고 생각하셨는지 모르겠습니다. . .

제대로 이해되지 않는 부분이 있으면 조언 부탁드립니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿