Study/Java

[새싹x코딩온] 웹 개발자 부트캠프 과정 20주차 회고 | Java 에서 String(문자열) 타입의 값을 비교하는 법

다니니니 2024. 9. 25. 23:54
728x90

1. 들어가며

  • Java에서 String(문자열) 타입의 값을 비교하는 법 알아보기

2. Java의 String 타입

자바의 데이터 타입은 크게 두 가지로 나눌 수 있다.

  1. 기본 타입(Primitive)
  2. 레퍼런스 타입(참조형, Reference)

그 중 String 타입은 레퍼런스 타입이다.

 

데이터들은 메모리 어디에 저장될까

Java에서 Primitive type은 메모리의 stack 영역에 저장된다.

Reference type은 객체에 대한 주소값이 stack에 저장되고 이 stack의 주소값을 이용해서 heap 에 있는 객체에 접근한다.

public class Person {
    public static void main(String[] args) {
        String name = "김굉필";
        int age = 30;
        int grade = 2;
        double score = 80.2;
        Favorite favorite = new Favorite("인사이드 아웃", 33);
    }
}


public class Favorite {
    String movie;
    int number;

    public Favorite(String movie, int number){
        this.movie = movie;
        this.number = number;
    }
}

위와 같이 변수들을 지정한다고 했을 때, 변수들은 stack에 저장된다. 

하지만 String 타입인 name과 class 인 favorite은 stack에 주소값이 저장된다.

 

그래서 실제로 출력을 해보면 아래와 같이 class 인 favorite은 주소값이 나온다.

 

위에서 String 도 Reference type이라 했는데 왜 주소값이 안나오고 값이 나오냐면

String 타입은 주소를 출력하지 않고 글자를 출력하게끔 설계되었다고 한다.

 

이를 그림으로 나타내면 아래와 같이 표현할 수 있을 것이다.

 

String 의 값을 비교하는 법

String 타입은 문자열 리터럴로 선언했는지, new 연산자로 선언(문자열 동적할당)했는지에 따라

주소값(참조값)이 달라질 수 있다.

 

1. 문자열 리터럴로 선언

String name1 = "하츄핑";
String name2 = "하츄핑";

동일한 문자열 리터럴이 사용된 경우,

자바 컴파일러는 문자열 풀(String pool)이라는 공유된 메모리 영역에 해당 문자열을 저장한다.

즉, 같은 주소값(참조값)을 가진다.

 

2. new 연산자로 선언

String name3 = new String("하츄핑");
String name4 = new String("하츄핑");

new 연산자로 선언해서 문자열 객체를 생성하면, 값의 내용이 동일하더라도 다른 주소값(참조값)을 가진다.

 

 

비교 연산자(==) 사용해보기

.비교 연산자(==) 는 두 객체의 "참조"를 비교한다. 즉, 동일한 메모리 주소(위치)를 가리키는지 검사한다.

System.out.println("name1 == name2 : " +  (name1 == name2));
System.out.println("name1 == name3 : " +  (name1 == name3));
System.out.println("name4 == name3 : " +  (name4 == name3));

 

name1과 name2 는 문자열 리터럴로 선언했기 때문에 동일한 참조값을 가져서 동일한 참조값을 갖는다.

따라서, true 가 나왔다.

그러나 name3와 name4는 new 연산자로 선언했기 때문에 서로 다른 참조값을 가진다.

따라서, false 가 나온다.

 

equals() 메소드 사용해보기

equals() 메소드는 두 객체의 "내용"이 동일한지를 비교한다. 

즉, 참조값을 비교하는 것이 아닌 두 문자열 객체가 가지고 있는 값 자체를 비교한다.

System.out.println("name1.equals(name2) : " + (name1.equals(name2)));
System.out.println("name1.equals(name3) : " + (name1.equals(name3)));
System.out.println("name4.equals(name3) : " + (name4.equals(name3)));

name1, name2, name3, name4는 모두 "하츄핑" 이라는 동일한 "내용"을 가지고 있다.

따라서 equals() 로 비교하면 true 가 나온다.

 

결론

이와 같이 자바에서는 String이 나름 특별한 규칙을 갖고 있기 때문에,

내용을 비교할 것이라면 equals() 를 사용해서 비교하는 것이 바람직하다.

 

3. 마치며

이제 자바를 들어가며 자바의 데이터 타입들을 배우고 여러가지 메서드를 배웠다.

그 중에서도 String 타입이 특이해서 이에 대해 살펴보았다.

자바스크립트를 공부했을 때, 주변에서 이미 자바나 C# 또는 C++ 을 사용하던 친구들이

자바스크립트가 타입을 지정하지 않아서 오히려 헷갈리고 어렵다는 이야기를 많이 들었다.

나는 자바스크립트를 먼저 공부해서 그런지 타입을 지정하는 것이 더 헷갈리지만

어차피 자바스크립트에서도 타입 에러나 기타 다른 오류를 잡기 위해 타입스크립트라는 것이 나왔으므로

자바나 타입스크립트를 계속 공부하면서 감을 익혀야 겠다는 생각이 들었다.

 

4. Reference

1. 코딩온 강의 교안 및 실습

 

2. https://320hwany.tistory.com/88

 

자바가 Call By Reference가 아닌 이유

프로그래밍 언어를 공부하다보면 Call By Value, Call By Reference 라는 용어가 자주 들립니다. Call By Value는 값을 전달하는 방식이고 Call By Reference는 주소를 전달하는 방식입니다. 그렇다면 자바는 어떤

320hwany.tistory.com

 

3. https://velog.io/@ahnick/Java-Call-by-Value-Call-by-Reference

 

[Java] Call by Value, Call by Reference

프로그래밍 언어들의 메소드 매개변수 호출 방식에는 여러 가지가 있으며 호출 방식은언어마다 다르게 되어 있습니다. 그 중 자바의 Call by Value 방식에 대해 알아봅시다 !

velog.io

 

4. https://320hwany.tistory.com/109

 

Java에서 배열이 객체인 이유와 메모리 할당에 대해서

가장 기본적인 자료 구조 중 하나로 배열이 있습니다. 배열은 미리 일정 크기만큼 메모리를 할당한 후 데이터를 순차적으로 저장하는 자료구조입니다. Java 에서의 배열 Java에서는 다음과 같이

320hwany.tistory.com

5. https://yeo-computerclass.tistory.com/245

 

[Java] 프로그램 메모리 저장 방식

📌프로그램이 메모리 사용하는 방식 데이터 저장 영역 = 스태틱 영역 + 스택 영역 + 힙 영역 💡main 메소드 실행될 때 데이터 저장 영역 JRE는 프로그램안에 main() 메소드가 있나 확인한다. main() 메

yeo-computerclass.tistory.com

6. https://milku.tistory.com/112

 

[Java] 문자열(String) 비교 방법 ==, equals() 차이

서비스에서 문자열을 비교하던 중 같은 값을 비교했는데 false가 나오는 상황이 발생했습니다. 원인을 찾아보니 == 연산자로 문자열을 비교했기 때문이었습니다. == 연산자는 객체의 주소를 비교

milku.tistory.com

7. https://sso-feeling.tistory.com/12

 

[자바JAVA] 변수 기본 예제3 - 참조변수, String의 toString, 주소값

안녕하세요 자바칩 프라푸치노입니다. 오늘도 공부를 달려봅시다! 오늘은 참조변수에 대해 이해를 해보도록 하겠습니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package sec01_exam; public class Var_Pri_Re

sso-feeling.tistory.com

 

728x90