안녕하세요. 코딩개입니다. 이번 시간에는 java에서 string에 들어있는 문자들을 어떻게 hex 값으로 보는지 알아보도록 하겠습니다.

 


 저번 시간에 replace랑 replaceAll이랑 비교한 부분 기억하실 거에요.

 

 

 출력은 같아 보이는데, 사실 다른 문자열이라고 했습니다. 왜? 출력이 되지 않는 문자가 포함되어 있기 때문이에요. 정말 그것이 포함되어 있는지 디버그를 해 보기 위해서 string에 저장 되어 있는 문자들을 차례대로 hex로 출력해 봅시다.

 

 

 


 Format 문자열에 대한 설명을 봅시다. Conversions 단락을 보면, 몇 가지 카데고리로 나뉜다고 되어 있습니다. General은 어떠한 type도 받아들인다는 것을 의미합니다. 3번의 Numeric은 몇 개의 type만 잡는데요. Integral은 char와 Character를 제외한 정수 타입을 받습니다.

 

 

 hex 값으로 출력하기 위해서, H를 써야 할 거 같습니다. 그래 보이는 것이 arg가 null이 아니면 Integer의 toHexString을 호출한다고 되어 있기 때문입니다. 그런데, leading zero를 붙여야 한다면 이야기가 달라집니다. hex로 출력해야 한다면 'x'나 'X'를 붙이는 것이 답입니다.

 

 

 그 이유는 '0' flag는 Integeral과 Point에 y가 되어 있지만, General에는 -라고 표기되어 있기 때문입니다. 실제로 Formatter의 내부 소스를 뜯어보면 General한 케이스에 대해서 '0'이 들어오면 invalid하다는 예외를 떨구게끔 되어 있어요.

 

 

 Flag.ZERO_PAD는 '0'을 의미합니다.

 

 

 String의 value에 저장 되어 있는 캐릭터 값들을 보기 위해서, toCharArray 메서드로 끌고 옵니다. 이 메서드는 내부를 뜯어보면 단순하게 value 필드를 결과 배열에 arrayCopy로 copy를 뜬 결과를 그대로 리턴함을 알 수 있어요. replaceChar 배열을 순회하면서 보게 되는 char형 c에 대해서 값을 출력해야 합니다.

 

 그러면 format string을 작성해야 하는데요. format string에는 "%04X"라고 적었습니다. 이는 정수형을 받는다는 의미입니다. 앞에 04는 width가 4인데, 남는 공간은 0으로 채운다는 것을 의미합니다. 그런데, char형으로 들어가면 안 되니, 2번째 인자로 들어가는 c는 강제 형변환을 시켜서 넣었습니다. 목적에 정확하게 맞아 들어갑니다. 실행 결과는 아래와 같아요. 

 

 

 똚의 코드 포인트는 U+B61A인데 정확하게 그 값이 나왔음을 알 수 있어요. 그리고 replace는 단순하게 ch1을 ch2로 치환한다는 것 또한 알 수 있습니다. 3번째 char 값으로 찍힌 것이 0000인 것을 보면 명확하게 알 수 있습니다.

 

 


 비슷해 보이는 getBytes는 다르게 동작합니다. 설명을 보면, Encode를 한다고 되어 있습니다. 어렵게 생각할 필요 없습니다. '가' 라는 것을 utf-8로 인코딩 한 것을 hex로 표현하면 AC00이 됩니다. 그런데 utf-16은 다르게 표현됩니다. 표현 방법이 다를 뿐입니다. 즉, '가'라는 데이터를 특정한 방법으로 가공해서 리턴한다 정도로 생각하시면 좋겠어요.

 

 

 실제로 내부 소스 코드를 보면 StringCoding의 encode를 호출합니다.

 

 

 이 메서드의 내부에서는 encode를 호출하는데요. "ISO-8859-1"과 같은 charsetName이 인자로 들어갑니다. 특정한 인코딩 방식으로 가공해서 byte 배열로 리턴하는데요. 이것은 실제로 String의 char 배열에 저장된 value 값을 가공 처리를 하기 때문에 제가 제시한 목적과는 맞지 않습니다.