티스토리 뷰
다음과 같이 str1, str2 를 선언 해봅시다.
str1 과 str2 는 동일하게 "Hello world" 를 나타내지만 둘은 같은 객체일까요?
각각의 실행 결과는 아래와 같이 나옵니다.
중요한 것은 str1 과 str2 는 서로 다른 객체이기 때문에 false 가 표기되었다는 것입니다.
코드의 7~9번 라인은 아래와 같이 바꿔서 이해해도 됩니다.
if ( str1 == str2) System.out.println("true");
else System.out.println("flase");
str1 과 str2 는 같은 값을 표기할 뿐이지 서로 다른 객체입니다.
str1.hashCode() 와 str2.hashCode() 는 각각의 String 객체에 담겨있는 값을 hash 로 표현한 값입니다.
객체의 주소번지 값이 아닙니다.
아래 코드를 추가해서 실제 객체의 주소값을 비교해봅시다.
hashCode() 아래에 identityHashCode() 로 인해 서로 다른 hash 값이 생성된 것을 확인했습니다.
조금 더 설명할게 있으니 아래 코드를 추가해봅시다.
기존과 같은 방식으로 str3, str4 를 만들고, str1 과 str3 를 비교합니다.
25~27라인의 결과는 어떻게 나올까요?
String str1 = "Hello world";
String str3 = "Hello world";
str1, str3 이 동일객체인지 비교했는데 이번엔 true 값이 출력됩니다.
왜죠..?
String 을 new String() 으로 객체로 선언하지 않고 문자열만 바로 배정해서 사용하면
java 메모리에서 이미 만들어진 문자열을 공유해서 사용합니다.
메모리에서 공용으로 사용되는 문자열을 리터럴(Literal) 이라고 합니다.
문자 리터럴은 상수의 한 종류로써 변하지 않는 일종의 고유값잆니다.
아래 부연 설명을 읽어보시길 바랍니다.
System.out.println("========");
String a = "hello";
System.out.println(System.identityHashCode(a));
// "hello" 리터럴 생성 및 활용
a += " world"; // "hello world" 리터럴 생성 및 활용
System.out.println(System.identityHashCode(a));
// 기존의 "hello" 는 사라지지 않고 메모리 어딘가에 있음
// 다만 연결된 객체가 없을 뿐
String b = "hello";
System.out.println(System.identityHashCode(b));
// 사라지지 않고 떠다니던 "hello" 리터럴을 객체 b와 연결
// b를 위한 새로운 문자열 "hello" 가 생성되는게 아님
String c = "hello";
// 마찬가지로 c를 위한 문자열 "hello" 가 새로 생성되는게 아님
// b와 c 는 동일한 "hello" 리터럴을 바라보고 있음
//즉 b와 c는 동일한 문자열을 참조하고 있음.
System.out.println(b == c);
// 그러므로 결과는 true
하지만 str2 와 str4 는 객체로서 완전히 새로 생성했기 때문에 리터럴 방식을 이용한게 아닙니다.
String str2 = new String("Hello world");
String str4 = new String("Hello world");
이 둘은 신규 객체로 각각 생성되었고 String 객체가 표현해야 할 value 값이 같을 뿐입니다.
그래서 str1, str3 의 identityHashCode() 는 동일 값이 나오고
str2, str4 의 identiyHashCode() 는 서로 다른 값이 나오는 겁니다.
그래서 String 의 값 비교는 == 연산자를 사용하면 안됩니다.
String.equals("문자열")을 사용하세요
전체 소스코드와 결과물을 다시 첨부하니 참고하세요
문자열 리터럴과 String 객체 주소값의 추가적인 비교는
다음편에 이어서 합니다.
'수업 노트 > java (이론)' 카테고리의 다른 글
java static 쉬운 설명 (0) | 2021.08.31 |
---|---|
String 객체의 원리(2) (0) | 2021.08.24 |
for each 사용법 (0) | 2021.08.24 |
- Total
- Today
- Yesterday
- OverTheWire
- nc
- 웹보안공부
- X32
- grep
- 리눅스
- bz2
- 웹보안
- Natas
- natas7
- Strings
- tr
- gz
- OpenSSL
- Linux
- java
- solution
- 32bit
- 리터럴
- 풀이
- HTTPS
- ssh
- Bandit
- over the wire
- SSL
- tar
- BASE64
- 압축파일
- Encode
- find
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |