Java - 문자열 자료형과 기초 사용법

민찬홍·2023년 8월 21일

Java

목록 보기
8/31
post-thumbnail

String: 문자열 자료형

  • 0~ 다수의 문자들로 구성
  • 쌍따옴표로 둘러쌈
  • 앞에서 다룬 자료형들과 다르게 참조 자료형
    • 그러나 특별히 원시값과 유사하게 사용될 수 있음
		//  리터럴 방식
        String str1 = "Hello World!";
        String str2 = "안녕하세요 😆 반갑습니다~ 🖐️🖐️🖐️";
        
        // 빈 문자열 가능
        String str3 = "";

        //  인스턴스 생성 방식
        String str4 = new String("나중에 자세히 배웁니다.");
        
        // 리터럴 방식도 내부적으로는 인스턴스 생성 방식대로 처리됨 

위에 코드를 보면 알 수 있겠지만, 지금까지 배워온 자료형(int,float,double,char)는 범위가 정해져 있었다. 데이터 하나에 지정된 메모리 용량이 있던 것이다. 문자열은 이와는 다르게 기존 원시 자료형과는 다른 참조 자료형이다.

  • 클래스의 인스턴스
    • 일단 단순 값 뿐 아니라 특정 기능들을 가진 무언가로 이해할 것
    • 객체 지향 세션에서 자세하게 다룰 예정
		String hl1 = "Hello";
        String hl2 = "Hello";
        String wld = "World";

        //  리터럴끼리는 == 을 사용하여 비교 가능
        boolean bool1 = hl1 == hl2;  // true
        boolean bool2 = hl1 == wld;  // false

        String hl3 = new String("Hello");
        String hl4 = new String("Hello");
        String hl5 = hl4;

        //  💡 인스턴스와 비교하려면 .equals 메소드를 사용해야 함
        //   특별한 경우가 아니면 문자열은 .equals로 비교할 것
        boolean bool3 = hl3 == hl4;  // false

        boolean bool4 = hl1.equals(hl2); // true
        boolean bool5 = hl1.equals(hl3); // true
        boolean bool6 = hl3.equals(hl4); // true
        boolean bool7 = wld.equals(hl2); // false

        //  같은 곳을 참조하는 인스턴스들
        boolean bool8 = hl4 == hl5; // true

위의 코드의 디버깅 결과를 보면 신기한 점이 있다. hl1 변수와 hl2 변수는 각각 리터럴 형식으로 생성되었고, hl3 변수와 hl4 변수는 인스턴스 방식으로 생성되었다. hl1h12==을 사용하여 비교하였더니 true가 나왔는데, 인스턴스로 생성된 hl3hl4를 비교하니 false가 나왔다. 이와 같이 특별한 경우가 아니면 문자열은 .equals로 비교하는 것이 더 좋다.

또한 한가지 신기한 부분을 더 발견할 수 있는데, 인스턴스로 생성된 hl4를 그대로 대입한 hl5 변수는 == 을 사용해서 hl4 와 비교해도 true가 나오는 것을 볼 수 있다. 이러한 차이들은 자바가 내부적으로 문자열을 어떻게 다루는지를 알아야 알 수 있다. 간단하게 얘기하면

  • == : 같은 종이인가?
  • equals : 같은 글이 적혀있는가?

자세하게 설명하자면 너무 길어서 간단하게 말하자면 리터럴로 생성된 것은 String constant pool이라는 곳에 중복이 없게 저장된다. 예를 들어 hl1 변수가 "Hello" 로 선언된 후, hl2 변수도 "Hello" 로 선언되면 저 String constant pool 에서 기존에 있는 "Hello" 를 바라보게 하는 것이다.

반면 클래스의 인스턴스로 선언된 경우 그 외의 영역에 하나하나 따로 저장이 된다. 따라서 == 즉 같은 종이냐고 묻는 것에는 false 가 반환되지만, 그 종이에 적힌 내용이 같냐를 묻는 equals 에는 true 를 반환하는 것이다.

이것 역시 중요한데 자바에서 이런 참조자료형을 = 을 통해 대입하게 되면 값을 복사해서 주는 것이 아니라, 값의 주소를 넘겨주게 된다. 따라서 hl4hl5== 으로 비교해도 true 가 나오는 것이다.

따라서 결론적으로 그냥 문자열을 비교할때는 어지간해서는 .equals 를 쓰자.

연산자


		String str_a1 = "안녕";

        boolean bool_a1 = str_a1.equals("안녕");  // true

        //  💡 리터럴로 선언했어도 객체 인스턴스로 만들어짐
        //  때문에 객체의 기능인 메소드 사용 가능
        boolean bool_a2 = "안녕".equals("안녕"); // true
        boolean bool_a3 = "안녕".equals(str_a1); // true
		String str_b1 = "Hello, ";
        String str_b2 = "World!";
        
        // + 연산자: 이어붙여진 결과를 반환
        String str_b3 = str_b1 + str_b2;
        // str_b3 : "Hello, World!"
		//  += 연산자:
       //  1. ⭐️ 해당 변수에 문자열을 이어붙임 (부수효과)
       String str_c1 = "나는 아무 생각이 없다. ";
       str_c1 += "왜냐하면 ";
       
       
       //  2. 그 결과를 반환
       String str_c2 = str_c1 += "아무 생각이 없기 때문이다.";

       boolean bool_c = (str_c1).equals(str_c2);
       
       // str_c1 : "나는 아무 생각이 없다. 왜냐하면 아무 생각이 없기 때문이다." 
       // str_c2 : "나는 아무 생각이 없다. 왜냐하면 아무 생각이 없기 때문이다."

하나 얘기하고 가자면, 문자열에서는 += 만 가능하다. -= 는 불가하다. 당연하게 *= 이나 /= 도 불가하다.

		//  ⚠️ 상수에는 적용할 수 없음
        final String str_d = "헬로";
        str_d += "월드";  // 불가
		int intNum = 123;
        float fltNum = 3.14f;
        boolean bool = true;
        char character = '가';

        String str_d1 = "자, 이어붙여볼까요? ";

        //  💡 문자열에 다른 자료형을 더하면 문자열로 이어붙여짐
        String str_d2 = str_d1 + intNum + fltNum + bool + character;
        
        // str_d2 = "자, 이어붙여볼까요? 1233.14true가"

타 자료형간 변환


		//  💡 타 자료형으로부터 문자열로 변환
        String str1 = String.valueOf(true);
        String str2 = String.valueOf(false);
        String str3 = String.valueOf(123);
        String str4 = String.valueOf(3.14f);  // str4 = "3.14"
        String str5 = String.valueOf('가');
        
        String str6 = true + "";  // "true"
        String str7 = 123.45 + ""; // "123.45"
        // 이런식으로 그냥 빈문자열과 더해줘도 된다. 

이제 문자열을 타 자료형으로 변환하는 것을 보겠다. 아래 코드를 보자.

		String str123 = "123";

        //  문자열을 정수 자료형으로 변환하기
        byte bytNum = Byte.parseByte(str123);
        short srtNum = Short.parseShort(str123);
        int intNum = Integer.parseInt(str123);
        long lngNum = Long.parseLong(str123);
		
        // 해당 자료형의 Wrapper클래스.parse자료형  이런식으로 써주면 된다.
        
        //  대소문자 무관 'true'일 때 true 반환
        boolean bool1 = Boolean.parseBoolean("TRUE"); // true
        boolean bool2 = Boolean.parseBoolean("true"); // true
        boolean bool3 = Boolean.parseBoolean("T"); // false

Character같은 경우에는 parse로 바꿔주는게 아니다.

		String strA = "A";

        //  다음 강에 배울 메소드
        char chr = strA.charAt(0);
        
        // 괄호안에 인덱스를 넣어주면 된다.
		//  ⚠️ 런타임 에러 발생. 하나씩 주석해제해서 테스트
        //  '실행'으로 테스트하거나, 디버그 후 콘솔 탭에서 확인해볼 것
        
        //byte bytNum2 = Byte.parseByte("12345");
        //int intNum2 = Integer.parseInt("123.45");
        //double dblNum2 = Integer.parseInt("하나");

바로 위에 코드는 컴파일 단계에서는 오류가 안나지만, 실행을 하면 오류가 난다. 자료형에 맞는대로 넣어주지를 않았기 때문이다.

이스케이프 표(escape sequence)


		String str1 = "문자열에 "큰따옴표가" 안 들어가요";
        String str2 = "엔터도 안 들어가요. 못 믿겠으면 넣어봐.";

이스케이프 표현

  • \" : 큰따옴표
  • \' : 작은 따옴표
  • \n : 줄바꿈
  • \t : 탭
  • \\ : 백슬래시 하나
		//  실행하여 확인
        String str = "문자열에 \"큰따옴표\"도,\n엔터도 넣을 수 있다고?";
        System.out.println(str);
		String table = "언어\t\t종류\t\t\t\t자료형\nJava\tcompiled\t\t정적\nPython\tinterpreted\t\t동적";
        System.out.println(table);
		char singleQuote = '\'';
        System.out.println(singleQuote);

        String path = "C:\\Document\\MyCodings";
        System.out.println(path);

다음에는 문자열의 메소드들을 살펴볼 것이다.

profile
백엔드 개발자를 꿈꿉니다

0개의 댓글