[Java] Java String (대입 연산자와 new 연산자의 차이, ==과 .equals의 차이)
1. 데이터 타입
1.1 데이터 타입 종류
1.2 기본 데이터 타입과 참조 데이터 타입의 차이점
1.3 스택 영역과 힙 영역
2. 참조 데이터 타입의 변수 선언
2.1 = 사용 (같은 주소값을 가리킴)
2.2 new 연산자 사용 (다른 주소값을 가리킴)
2.3 정리
3. ==과 .equals
3.1 new 연산자로 선언한 string을 ==로 비교
3.2 new 연산자로 선언한 string을 .equals로 비교
3.3 =로 선언한 string을 ==로 비교
3.4 =로 선언한 string을 .equals로 비교
...
1. 데이터 타입
1.1 데이터 타입 종류
데이터 타입에는 기본 데이터 타입과 참조 데이터 타입이 있다.
기본 데이터 타입 : int, char, boolean...
참조 데이터 타입 : String, class...
1.2 기본 데이터 타입과 참조 데이터 타입의 차이점
기본 데이터 타입은 변수에 할당된 값을 직접 저장하지만
참조 데이터 타입은 변수가 값이 저장된 주소를 가리킨다.

1.3 스택 영역과 힙 영역
자바에서 사용하는 메모리 영역에는 3종류가 있다.
메소드 영역 : 코드에서 사용되는 클래스(.class)들을 클래스 로더로 읽은 후, 분류해서 저장
스택 영역 : 스레드가 실행될 때 할당됨. (스레드 : 프로세스 안에서 실행되는 흐름의 단위)
힙 영역 : 객체와 배열이 생성되는 영역
메모리 영역은 나중에 자세히 공부한다고 한다.
아무튼 사용자가 변수를 선언하고 값을 할당할 때는 스택 영역과 힙 영역을 사용하게 된다.
int a = 5;
String a = "aa";
라는 변수를 만들었다.

기본 데이터 타입은 int는 5라는 값이 스택영역에 저장되어있다.
하지만 참조 데이터 타입인 String은 100이라는 주소값이 저장되었고, 그 주소는 힙 영역의 100을 가리키고 있다.
...
2. 참조 데이터 타입의 변수 선언
2.1 = 사용 (같은 주소값을 가리킴)
String A = "aa";
String a = "aa";
참조 (문자열) 데이터 타입에 변수 A와 a를 선언해서, 같은 "aa"값을 할당했다.

=를 사용해서 값을 할당해주면, 두 변수는 같은 값을 가리키게 된다.
하지만 한 변수의 값을 바꿔주게 되면 다른 값을 가리키게 된다.
String A = "aa";
String a = "aa";
A="bb";
System.out.println("A : "+ A +", a : " + a);

2.2 new 연산자 사용 (다른 주소값을 가리킴)
String A = new String("aa");
String a = new String("aa");
마찬가지로 참조 (문자열) 데이터 타입에 변수 A와 a를 선언해서, 같은 "aa"값을 할당했다.

new 연산자를 사용해서 값을 할당해주면, 다른 주소를 가리키게 된다.
2.3 정리

=로 값을 저장한 변수는, 변수에 저장된 객체의 번지가 동일해서
힙 영역의 같은 hello를 가리킨다.
하지만 new로 값을 저장한 변수는 값이 동일해도
힙 영역의 다른 hello를 가리킨다.
...
3. ==과 .equals
public class StringArray {
public static void main(String[] args) {
String h1 = new String("hello");
String h2 = new String("hello");
String h3 = "hello";
String h4 = "hello";
}
}
=와 new연산자로 선언한 변수들의 값을 ==와 .equals로 비교해봤다.
h1과 h2는 new로 선언했고, h3과 h4는 =로 선언했다.
결과를 먼저 말하자면,
==는 주소가 같은지 아닌지를 판단하고
.equals는 값이 같은지 아닌지를 판단한다.

3.1 new 연산자로 선언한 string을 ==로 비교
public class StringArray {
public static void main(String[] args) {
String h1 = new String("hello");
String h2 = new String("hello");
String h3 = "hello";
String h4 = "hello";
// new 연산자로 선언한 string
// ==로 비교
if (h1==h2) {
System.out.println("h1과 h2가 같다");
}
else {
System.out.println("h1과 h2가 다르다");
}
}
}

값이 같은데, 다르다는 결과가 나왔다.
new로 선언했기 때문에 다른 주소를 가리키고 있다는걸 알 수 있다.

3.2 new 연산자로 선언한 string을 .equals로 비교
public class StringArray {
public static void main(String[] args) {
String h1 = new String("hello");
String h2 = new String("hello");
String h3 = "hello";
String h4 = "hello";
// new 연산자로 선언한 string
// .equals로 비교
if (h1.equals(h2)) {
System.out.println("h1과 h2가 같다");
}
else {
System.out.println("h1과 h2가 다르다");
}
}
}

이번에는 같다는 결과가 나왔다.
.equlse()는 입력받은 값을 비교하는 메소드이기 때문이다.

3.3 =로 선언한 string을 ==로 비교
public class StringArray {
public static void main(String[] args) {
String h1 = new String("hello");
String h2 = new String("hello");
String h3 = "hello";
String h4 = "hello";
// = 연산자로 선언한 string
// ==로 비교
if (h3==h4) {
System.out.println("h3과 h4가 같다");
}
else {
System.out.println("h3과 h4가 다르다");
}
}
}

이번에도 같다는 결과가 나왔다.
==는 같은 주소면 참이기 때문에 같다는 결과가 나온 것이다.

3.4 =로 선언한 string을 .equals로 비교
public class StringArray {
public static void main(String[] args) {
String h1 = new String("hello");
String h2 = new String("hello");
String h3 = "hello";
String h4 = "hello";
// = 연산자로 선언한 string
// .equals로 비교
if (h3.equals(h4)) {
System.out.println("h3과 h4가 같다");
}
else {
System.out.println("h3과 h4가 다르다");
}
}
}

결과는 같다.
equals메소드는 값이 같으면 참이기 때문이다.
