Java - 문자열의 포메팅과 null

민찬홍·2023년 8월 30일

Java

목록 보기
11/31
post-thumbnail

문자열의 포메팅과 null에 관해 알아보자

🧩 포메팅

		String str1 = "%s의 둘레는 반지름 X %d X %f입니다.";

        String circle = "원";
        int two = 2;
        double PI = 3.14;

        //  💡 formatted : 주어진 형식에 따라 문자열 생성
        //  ⭐️ 13+버전에 추가됨. 편의상 강의에서 많이 사용할 것
        String str2 = str1.formatted(circle, two, PI);

        //  💡 이전 버전에서의 방식. 실무에서 사용하려면 기억
        String str3 = String.format(str1, circle, two, PI);
        

프로그래밍을 하다보면 문자열 출력의 중간중간에 다른 변수의 값을 넣어줘야 할 때가 있다. 그 때 사용할 수 있는 것이 문자열 포메팅이다. 중요한 것은 이 문자열 포메팅 역시 새 문자열을 반환할 뿐 원본을 바꾸지는 않는다.

최신 버전에서의 fommatted 는 따로 문자열 변수를 메소드 안에 넣어주지 않아도 되는 간결함이 추가되었다.

❗️
%b : 불리언
%d : 10진수 정수
%f : 실수
%c : 문자
%s : 문자열
%n : (포맷 문자열 내 줄바꿈)

		//  ⭐️ 시스템의 printf 메소드 : String.format과 같은 형식으로 출력
       //  줄바꿈을 하지 않으므로 직접 넣어줘야 함
       System.out.printf("%s의 둘레는 반지름 X %d X %f입니다.%n", circle, two, PI);

🧩 정수 포메팅

		System.out.printf("%d, %5d, %05d%n- - - - -%n%n", 123, 123, 123);
		//  💡 정수 다양하게 포매팅하기
        String[] intFormats = {
                "%d",        // 1. 기본
                "%13d",      // 2. n 자리수 확보(비움), 오른쪽 정렬
                "%013d",     // 3. 빈 자리수 0으로 채움
                "%+13d",     // 4. 양수는 앞에 + 붙임
                "%,13d",     // 5. 긴 숫자를 콤마로 구분해줌
                "%-13d",     // 6. 자리수 확보, 왼쪽 정렬
                "%+,013d"    // 7.
        };

        String[] intResults = new String[intFormats.length];

		// 이후의 배울 for 반복문
		// - 위의 형식들로 하나하나 출력해보는 코드
        for (var i = 0; i < intFormats.length; i++) {
            String format = (i + 1) + ". ";
            for (var j = 0; j < 4; j++) {
                format += intFormats[i] + " ";
            }
            format = format.trim() + "%n%n";  // "%d %d %d %d%n%n" ...
			//  System.out.println(format); // 🔍 주석해제하여 함께 확인

			//  🔍 이 숫자들을 스페이스로 구분해서 출력해 볼 것
            System.out.printf(format, 12, 2345, 67890, -1234567);

            //  ⭐️ formatted 메소드에서도 사용 가능
            intResults[i] = format.formatted(12, 2345, 67890, -1234567);
        }

🧩 실수 포메팅

		//  💡 실수 다양하게 포매팅하기
        String[] fltFormats = {
                "%f",       // 1. 기본 (소수점 6자리, 0으로 메움)
                "%.2f",     // 2. 소수점 n자리까지
                "%13.2f",   // 3. 정수자리 확보, 소수자리 제한
                "%,f",      // 4
                "%+013.2f",  // 5
                "%-13.2f",  // 6
        };

        String[] fltResults = new String[fltFormats.length];

        for (var i = 0; i < fltFormats.length; i++) {
            String format = (i + 1) + ". ";
            for (var j = 0; j < 4; j++) {
                format += fltFormats[i] + " ";
            }
            format = format.trim() + "%n%n";

            System.out.printf(format, 1.2, 123.456, 1234.123456789, -123.4567);

            fltResults[i] = format.formatted(1.2, 123.456, 1234.123456789, -123.4567);
        }

🧩 문자열 포메팅

		//  💡 문자열 다양하게 포매팅하기
        String[] strFormats = {
                "%s",    // 1. 기본
                "%9s",   // 2. 자리 확보
                "%.2s",  // 3. ~글자만
                "%9.2s", // 4.
                "%-9s",  // 5. 왼쪽 정렬
        };

        String[] strResults = new String[strFormats.length];

        for (var i = 0; i < strFormats.length; i++) {
            String format = (i + 1) + ". ";
            for (var j = 0; j < 2; j++) {
                format += strFormats[i] + " ";
            }
            format = format.trim() + "%n%n";

            System.out.printf(format, "Hello", "하이염");

            strResults[i] = format.formatted("Hello", "하이염");
        }

🧩 null 문자열

		String emptyStr = "";
        String nullStr = null;

        //  ⭐️ 빈 문자열과 null은 다름
        boolean bool1 = emptyStr == nullStr;

        //  ⚠️ null은 문자열 인스턴스 메소드 사용 불가
        //  아래의 코드들은 모두 런타임 에러를 발생시킴
        //  int int1 = nullStr.length();
        //boolean bool2 = nullStr.equals(emptyStr);
        //String str1 = nullStr.concat("ABC");

null은 그냥 공백과 다르다.

  • 빈 문자열(길이가 0) : 힙 공간에 자리를 차지
  • null 문자열: 힙에 할당되지 않음, 가리키는 곳 없음 (가리키는 종이 자체가 없음)

null 을 가리키게 되면 NullPointerException 이 뜨게 된다. 그렇다면 이러한 null 로 인한 오류는 언제 가장 많이 뜰까. 변수 자체에 값을 넣어줄 때에는 이런 부분들이 생각보다 많이 발생하지는 않는다. 값 할당 자체는 개발자의 통제 아래에 있기 때문이다. 이러한 Exception 이 가장 많이 뜰 때는 외부에 있는 데이터를 가져와서 사용할 때이다. 그 데이터 자체가 값이 있는지, null 인지 개발자로서는 알 길이 없다.

		//  💡 문자열을 외부로부터 받아올 경우 등...
        String defaultStr =
                (nullStr != null && !nullStr.isEmpty())
                        ? nullStr : "(기본값)";
		//  💡 초기화되지 않은 변수와 비교
        String notInitStr;
        String nullStr2 = null;

        //  ⚠️ 컴파일 오류 발생
        System.out.println(notInitStr);

        //  코드에 따라 정상실행 또는 런타임 오류
        System.out.println(nullStr2);
		//  ⭐️ 이 외에도 참조 자료형의 인스턴스는 null 가능
        Object obj = null;
        System sys = null;

        //  ⭐️ 원시값들도 참조 자료형의 인스턴스로는 null 가능
        Integer nullInt1 = null;
        Double nullDbl1 = null;
        Boolean nullBool1 = null;
        Character nullChr1 = null;

        //  ⚠️  원시값은 불가
        //int nullInt2 = null;
        //double nullDbl2 = null;
        //boolean nullBool2 = null;
        //char nullChr2 = null;

원시값 자체에 null값을 대입할 수는 없다는 것을 다시 한번 확인하자.

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

0개의 댓글