char + String을 더하면 무슨 일이 생길까

드코미·2026년 6월 20일
post-thumbnail

시작은 단순한 의문에서

자바로 코드를 짜다 보면 이런 코드를 마주칠 때가 있습니다.

char a = 'A';
char b = 'B';
System.out.println(a + b);

직관적으로는 "AB"가 출력될 것 같습니다. 문자 두 개를 더했으니 문자열이 이어붙는 게 자연스러워 보이니까요. 그런데 실제로 실행해보면:

131

숫자가 나옵니다. 왜 이런 일이 생길까요?


char는 사실 숫자다

자바에서 char는 "문자처럼 보이지만 사실은 숫자"입니다. 정확히는 유니코드 코드값을 저장하는 16비트 정수 타입입니다. 'A'라는 문자는 내부적으로 65라는 숫자로 저장되어 있고, 'B'는 66입니다.

char a = 'A';
int code = a;          // 암묵적으로 int로 변환 가능
System.out.println(code);  // 65

이걸 직접 확인해보면:

System.out.println((int) 'A');  // 65
System.out.println((int) 'B');  // 66
System.out.println((int) 'a');  // 97
System.out.println((int) '0');  // 48

char는 글자 모양을 가진 게 아니라, "이 숫자는 이 글자에 대응된다"는 약속(유니코드 테이블)을 가지고 있는 정수일 뿐입니다.


char + char는 왜 숫자 계산이 될까

자바의 + 연산자는 피연산자의 타입을 보고 동작이 결정됩니다. charint 같은 숫자 타입끼리 +를 만나면, 자바는 이걸 그냥 산술 연산(더하기)으로 처리합니다.

char a = 'A';  // 65
char b = 'B';  // 66

System.out.println(a + b);  // 65 + 66 = 131

여기서 한 가지 더 알아둘 점은, char + char 연산의 결과는 char가 아니라 int로 자동 승격(promotion)된다는 것입니다. 그래서 131이라는 결과의 타입은 int입니다.

char a = 'A';
char b = 'B';
// char result = a + b;  // 컴파일 에러! int를 char에 바로 못 넣음
int result = a + b;       // 정상 동작, 131

만약 131을 다시 문자로 보고 싶다면 명시적으로 char로 캐스팅해야 합니다.

char result = (char) (a + b);
System.out.println(result);  // 131에 해당하는 유니코드 문자가 출력됨 (보통 보이지 않는 특수문자)

그럼 String이 끼면 왜 결과가 달라질까

반대로 + 연산자의 한쪽에 String이 있으면 동작이 완전히 바뀝니다.

char a = 'A';
String b = "BC";

System.out.println(a + b);  // "ABC"

자바는 + 연산에서 피연산자 중 하나라도 String이면, 다른 쪽을 자동으로 String으로 변환한 뒤 문자열 결합을 수행합니다. 이건 자바 언어 명세에 정의된 동작으로, String.valueOf()를 자동으로 호출해주는 것과 비슷합니다.

char a = 'A';
String b = "BC";

// 자바 내부적으로는 대략 이렇게 처리됨
String result = String.valueOf(a) + b;
// "A" + "BC" = "ABC"

+ 연산자의 의미가 "숫자 더하기"에서 "문자열 이어붙이기"로 완전히 바뀌는 거죠. 어느 쪽으로 동작할지는 String이 연산에 끼어있는지 여부가 결정합니다.


순서를 바꿔도 결과는 같다

char + String이든 String + char든 결과는 동일하게 문자열 결합입니다.

char a = 'A';
String b = "BC";

System.out.println(a + b);  // "ABC"
System.out.println(b + a);  // "BCA"

다만 여러 개를 한 줄에 더할 때는 왼쪽부터 순서대로 계산되기 때문에 순서에 따라 결과가 크게 달라질 수 있습니다.

char a = 'A';
char b = 'B';
String c = "";

System.out.println(a + b + c);   // "131" !!
System.out.println(c + a + b);   // "AB"
  • a + b + c: 먼저 a + b가 계산되는데, 둘 다 char라서 131(int)이 됩니다. 그 다음 131 + c에서 c가 String이라 131이 문자열 "131"로 변환되어 합쳐집니다. 결과는 "131".
  • c + a + b: 맨 앞에 String이 있어서 c + a부터 이미 문자열 결합으로 시작합니다. "" + 'A'"A", 그다음 "A" + 'B'"AB".

같은 변수 셋을 더해도 어디서부터 String이 끼는지에 따라 결과가 완전히 달라지는 셈입니다.


정리

연산결과이유
char + charint (코드값의 합)둘 다 숫자 타입이라 산술 연산으로 처리됨
char + intint (코드값 + 숫자)마찬가지로 산술 연산
char + StringString (문자열 결합)String이 있으면 다른 피연산자가 String으로 자동 변환됨
String + charString (문자열 결합)순서가 바뀌어도 동일하게 동작
a + b + c (혼합)왼쪽부터 순서대로 계산, String 등장 시점부터 문자열 결합 시작연산자 결합 규칙(왼쪽 우선)을 따름

핵심은 한 가지입니다. + 연산에 String이 하나라도 있으면 전체가 문자열 결합으로 동작하고, 없으면 숫자 타입끼리의 산술 연산으로 처리된다. 이 규칙만 기억해두면 'A' + 'B'131이 나오는 이유도, 반대로 'A' + "BC""ABC"가 되는 이유도 한 번에 설명됩니다.

자바에서 문자와 문자열을 다룰 때 흔히 마주치는 함정이니, 코드를 짤 때 + 연산자 양쪽의 타입이 무엇인지 한 번 더 확인하는 습관을 들이면 좋을 것 같습니다.

profile
할 수 있다!!!

0개의 댓글