NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    Java 4. String 형식.

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 긴 휴가가 끝나고 내일 출근해야 하는군요-_-; 언제나 노는건 좋습니다. 아직까지는 놀아도 놀아도 질리지 않는거 보면 말이죠^^;

     

    오늘은 자바에서 가장 많이 사용되며 대표적인 String 자료형에 대해서 알아보겠습니다. 자바에는 원시 자료형(C#에서는 빌트인 자료형)이라 부르는데 유일하게 String만 new로 생성할 수 있습니다. C#의 경우에는 모두 new 키워드로 생성해도 되고 리터럴(상수에 지정되는 값)을 사용해도 됩니다. 하지만 C#이든 Java든 new 키워드보다는 리터럴을 이용하여 변수를 초기화하는게 정석처럼 되어 있습니다. 뭐 방식이야 어떻든 상관은 없지만, 가능하면 가독성이 좋고 컴파일 시 최적화에 도움이 되는 리터럴을 사용하는게 좋습니다.

     

    문자열 개체는 한번 만들어지면 변경할 수 없는 변경 불가능 개체입니다. 문자열을 수정하는 것처럼 보이는 모든 String 메서드 및 Java 연산자도 실제로는 새 문자열 개체로 결과를 반환합니다. 다음 예제에서 s1과 s2의 내용이 결합되어 단일 문자열이 만들어질 때 두 원본 문자열은 변경되지 않습니다. += 연산자는 결합된 내용을 포함하는 새 문자열을 만듭니다. 새 개체는 s1 변수에 할당되고 s1에 할당 되었던 원래 개체는 해당 개체에 대한 참조를 유지하는 다른 변수가 없으므로 가비지 수집을 위해 해제됩니다.

    package JavaType;
     
    public class StringTest {
        public static void main(String[] args) {
     
            String s1 = "안녕하세요! ";
            String s2 = "어린시인의벗입니다.";
            
            // s1과 s2를 += 연산자를 사용하여 연결합니다.
            // 실제로 s1과 s2의 문자열을 연결한 후 새로운 문자열 객체를 만들고 할당합니다.
            // 원래 객체인 s1에 대한 참조가 더 이상 없으므로 s1은 가비지 수집 대상에 포함되어 메모리에서 해제됩니다.
            // 연결된 새로운 문자열 객체를 s1에 할당하게 됩니다.
            s1 += s2;
            
            System.out.println(s1);
        }
    }

     

     

    위의 코드를 실행하면 아래와 같은 결과를 볼 수 있습니다.

    9sSYVZF.png

     

     

    문자열 "수정"이 실제로는 새 문자열 생성이므로 문자열에 대한 참조를 만들 때 주의해야 합니다. 문자열에 대한 참조를 만든 다음 원래 문자열을 "수정"할 경우 해당 참조는 문자열을 수정할 때 만든 새 개체 대신 원래 개체를 계속해서 가리킵니다. 다음 예제를 확인해 보면 알 수 있습니다.

    package JavaType;
     
    public class StringTest {
        public static void main(String[] args) {
            String s1 = "Hello ";
            String s2 = s1;
            s1 += "World";
            System.out.println(s2);
        }
    }

     

     

    위 예제의 결과입니다.

    ZjnsaFf.png

     

     

    이렇게 문자열의 경우에는 문자열이 연결될 때마다 새로운 객체를 생성하고 연결된 문자열을 다시 할당하게 됩니다. 따라서, 참조가 살아 있고 계속해서 문자열이 연결되는 로직에서는 Java의 StringBuilder를 사용해야 합니다. 한 문장에서 +연산자를 여러번 사용해도 한번만 복사가 됩니다. 그러나 반목문인 경우에는 심각한 성능 저하가 올 수 있으므로 StringBuilder의 사용도 고려해봐야 합니다.

     

    C#이든 Java든 String에는 문자열을 처리하기 쉽도록 도와주는 메서드가 포함되어 있습니다. 그중에 C#과 Java가 가장 큰 차이를 가지는 메서드는equals(C#에서는 Equals)입니다.

    package JavaType;
     
    public class StringTest {
        public static void main(String[] args) {
            String a = "abc";
            String b = new String("abc");
            System.out.println(a.equals(b));
            System.out.println(a == b);
        }
    }

     

     

    위 코드의 9라인과 10라인의 차이점입니다. 결과는 아래와 같습니다.

    xxpGFJ0.png

     

     

    문자열 a와 b는 모두 "abc"로 같은 값을 가지고 있습니다. equals 메서드를 사용하여 비교할때는 true를 == 연산자를 사용하여 비교할때는 false를 반환합니다. a와 b의 값은 같지만 서로 다른 개체이므로 ==연산자로 비교할 때는 a와 b가 동일한 개체인지를 판단하기 때문에 false를 반환한 것입니다. equals는 개체가 가지고 있는 값으로 비교하기 때문에 true를 반환하게 된것입니다.

    Gx2fRO9.jpg

     

     

    C#의 경우 다른 결과를 보여줍니다. Equals와 ==연산자가 둘다 true를 반환합니다. C#에서는 개체를 비교하려면 System.Object.ReferenceEquals 메서드를 사용해야 합니다. 한가지 팁이라고 할만한 것은 C#의 경우에는 Equals와 ==가 같은 일을합니다. 이 둘은 속도에 차이가 없지만 가능하면 Equals를 사용하는게 좋습니다. Build할 때 IL이 어셈블리를 만드는데 이 때 리플랙션을 해보면 ==가 Equals로 변환되기 때문입니다. 그 후 JIT이 기계어로 실행시키게 되는데 이때는 이미 같은 코드이므로 속도에 차이는 없습니다. 이 외에 여러가지 메서드가 더 있지만 차차 코딩을 진행하면서 알아보도록 하겠습니다.

     

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.