거의 모든 개발자들은 windows를 OS로 사용하는데,

난 Windows와 맥OSX(이하 맥) 둘 다를 사용하고 있다.


그러다보면 가끔씩 격는 일이 바로 한글인코딩 문제이다.

가끔씩 겪는 일임에도 불구하고, 맥환경을 새로 정리하고 났더니 다시 헤매이는건 어쩔 수 없다.


흔하게 겪는 일중에 하나는....

아래처럼 맥에서 이클립스를 사용할때 겪는 한글깨짐이다.

이클립스에서는 별도 설정을 하지 않았다면, 운영체제의 기본 인코딩이 그대로 사용된다.

윈도우 기본 인코딩은 ms949인데,

윈도우 이클립스에서 작성된 프로젝트를 SVN을 통해 맥에서 땡겨오면....

프로젝트를 통째로 땡겨왔음에도 불구하고,

인코딩이 정상적으로 표시되지 않고, 한글은 깨져보인다.


만약 저게 중요한 내용이고, 무슨 인코딩일지도 모르면 게임 끝나는 거다. ㅋㅋㅋㅋ

하지만, 대부분 우리는 무슨 인코딩을 사용했는지 알고는 있다.



이럴땐... 콤보박스에는 없는 "ms949"를

그져 쳐 넣으면 해결된다.


가끔씩 이런걸로 당황하고 나면 정신이 없다 ㅡ,.ㅡ;

Google AdSense


자바 공부시작하는 어린이들은 참고하세요~


https://sites.google.com/site/godofjavabook/10_extra/summary-pdf



무단으로 친구들에게 공유하는 것은 OK

무단으로 제본해서 보는 것은 OK

무단으로 자기가 만든 것처럼 변경해서 공유하는 것은 저작권법 위반

이라고 생각하시면 됩니다.

Google AdSense

 

비주얼스튜디오로 개발을 하다보면 간혹 컴포넌트 문제가 발생한다.

그런데 Form 표시와 관련된 Exception이라면,

디자인파일을 여는 단계에서 문제가 표시되는데...

 

간혹 아래의 같이 .ErrorStyle 어쩌고 하는 요상한 html형식의 text가 뿌려질 때가 있다.

 

이 경우는 폼표시 기능에서 예외가 발생했지만,

그 예외를 표시할 수 없어서 나타나는 상황이다.

컴파일은 문제없을지 몰라도, 컴포넌트 미설치등의 사유로 인해 폼을 표시할 수 없는 상태인 것이다.

 

비주얼스튜디오같은 IDE툴의 강점은 문제가 있으면 무엇이 문제인지 표시를 해주는 것인데,

이 경우 무엇이 문제인지 알 길이 묘연하다.

 

해결방법은 다음과 같다.

html형식으로된 오류화면을 표시할 수 있게 레지스트리를 조작해주면 되는 것이다.

 

아래 그림과 같이...

HKEY_LOCAL_MACHINE\SOFTWARE\Classes 에 아래와 같이 .tmp키를 추가하고,

아래의 3가지 값을 넣어주면 된다.

 

이렇게 하고 다시 비주얼스튜디오를 실행하면,

해당 폼의 어디가 문제인지 그 오류가 표시될 것이다.

Google AdSense

 

 

코드를 작성할때 가장많이 쓰는 논리구문은 if문이 아닐까 한다.

너무 흔하게 쓰고 많이 쓰기때문에 익숙하기 그지없다.

 

시스템이 예상치 못한 방향으로 움직이는걸 발견하고,

원인을 찾아봤는데, 웃지못할 곳에서 원인을 찾았다.

아주 사소한 수정에서 발생한 버그였는데,

예를 들어 설명하자면 다음과 같다.

 

첨에 이런 코드가 있었다치자.

public class JustTest {

    public static void main(String[] args)
    {
        boolean bCheck1 = true;
        int iResult = 2;
  
        if(bCheck1)
            iResult = 3;
        else
            iResult = 1;

        System.out.println("감정결과 : " +  iResult);  
    }
}

bCheck1값을 확인해서 TRUE이면 3이 나오고, 아니라면 1이 나오는 단순한 구문이다.

 

물론 아래와 같이 if문을 {}로 감싸줘도 되지만,

보통 한줄짜리 구문을 일부러 라인낭비해가며 {}를 쓰는 개발자는 드물것이다.

public class JustTest {

    public static void main(String[] args)
    {
        boolean bCheck1 = true;
        int iResult = 2;
  
        if(bCheck1)

        {
            iResult = 3;

        }
        else

        {
            iResult = 1;

        }

        System.out.println("감정결과 : " +  iResult);  
    }
}

 

 

그런데 확인해야할 bCheck2라는 값이 하나 더 생겼다.

public class JustTest {

    public static void main(String[] args)
    {
        boolean bCheck1 = true;
        boolean bCheck2 = false;
        int iResult = 2;
  
        if(bCheck1)
            iResult = 3;
        else
            iResult = 1;

        System.out.println("감정결과 : " +  iResult);  
    }
}

이젠 bCheck1과 bCheck2가 모두 TRUE여야 3을 반환하게 수정해야한다.

bCheck1과 bCheck1가 모두 TRUE이면 3,

bCheck1만 TRUE이면 2,

둘다 FALSE였으면 1이 되면 된다.

 

그래서 코드를 아래와 같이 고쳤다.

public class JustTest {

    public static void main(String[] args)
    {
        boolean bCheck1 = true;

        boolean bCheck2 = false;
        int iResult = 2;
  
        if(bCheck1)
            if(bCheck2)

                iResult = 3;
        else
            iResult = 1;

        System.out.println("감정결과 : " +  iResult);  
    }
}

나의 실수를 찾았는가?

물론 이 코드는 아무런 문제가 없다.

그렇다면 bCheck2값이 FALSE이므로 결과가 2로 나올 것 같은가?

 

아니다. 이 코드의 결과값은 1으로 나온다.

 

여기서 아래의 빨간 마크부분을 유심히 살펴봐야한다.

public class JustTest {

    public static void main(String[] args)
    {
        boolean bCheck1 = true;

        boolean bCheck2 = false;
        int iResult = 2;
  
        if(bCheck1)
            if(bCheck2)

                iResult = 3;
        else
            iResult = 1;

        System.out.println("감정결과 : " +  iResult);  
    }
}

이 코드의 맹점은 if문의 바디를 지징하는 별도의 {}가 없다라는 점이다.

if~else~구조에서...

else문이 어느 if에 대한 else인지 명확하지가 않다.

 

물론 시스템은 이 else문이 어느 if문의 else문인지,

명확히 알고 있으니 에러를 발생시키지 않는것이다 ^^

(시스템은 논리구문을 속에서부터, 뒤에서부터 바라본다)

 

나의 의도는 if~else~ 구문이 이렇게 되길 바랬지만,

        if(bCheck1)
            if(bCheck2)
                iResult = 3;
        else
            iResult = 1;

 

실제로 시스템은 이렇게 알고 있었던 것이다.

        if(bCheck1)
            if(bCheck2)
                iResult = 3;
        else
            iResult = 1;

 

별 시덥지 않은 실수가 맹붕을 끌어올 수 있다는 사실을 다시한번 통감하는 하루였다.

Google AdSense

클래스를 디자인하다 보면,

많은 경우 생성자의 인자를 통해 멤버변수를 초기화를 하는데,

멤버변수를 추가해야할 일이 생기게 되면,

덩달아서 생성자 또한 변경이나 추가를 해줘야 한다.

 

우선 Java를 예로 들어보자.

 

 

2개의 멤버변수를 갖는 클래스를 예로 들어보자.

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

 

    public TestClass(int iVal1, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

    }

}

 

이 클래스에 멤버변수가 추가된다고 무작정 이렇게 클래스를 변경하는 사람은 없을꺼다.

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

    private int m_iVal3 = 0;

 

    public TestClass(int iVal1, int iVal2, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

        m_iVal3 = iVal3;

    }

}

무작정 이렇게 변경을 해버리면

기존에 인자 2개 생성자 TestClass(1,2)를 사용했던 모든 프로그램들에선 오류가 발생한다.

 

그렇다고 이렇게 똑같은 생장자에 코드만 추가생성을 하면 어떻게 될까?

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

    private int m_iVal3 = 0;

 

    public TestClass(int iVal1, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

    }

 

    public TestClass(int iVal1, int iVal2, int iVal3)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

        m_iVal3 = iVal3;

    }

}

이렇게 수정했을시 또다른 문제가 발생할 수 있다.

첫째 문제 불필요한 소스코드 작성이고,

둘째 문제는 TestClass(1, 2)와 TestClass(1,2,3)간 무결성 오류가 생길 수 있다는 것이다.

 

시간이 지나고 지나서, 생성자에서 멤버변수 초기화부분을 수정하게 된다면...

매번 TestClass(1, 2)와 TestClass(1,2,3)를 똑같이 수정해주거나,

한쪽에서 수정을 빼먹는다면 무결성 오류가 발생할 수 있는것이다.

 

따라서 이렇게 수정하는 것이 가장 깔끔하다고 할 수 있다.

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

    private int m_iVal3 = 0;

 

    public TestClass(int iVal1, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

    }

 

    public TestClass(int iVal1, int iVal2, int iVal3)

    {

        this(iVal1, iVal2);    //이 코드앞에 다른 코드를 추가하면 컴파일 오류가 생긴다.

        m_iVal3 = iVal3;

    }

}

항상 주의해야 할 것은 생성자에서 또다른 생성자를 호출할때,

Body의 가장 첫부분에 생성자를 호출해야한다는 것이다.

생성자가 클래스를 초기화 하는 놈인데, 클래스 초기화도 전에 다른 것을 수행하면 안되기 때문이다.

아주 간단한 Print문이라도 예외없이 Java컴파일는 오류를 반환한다.

 

 

 

자 이번엔 C#을 예로 들어보자.

 

 

위와 똑같은 구분을 C#으로 작성해보면 에러가 발생한다.

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

    private int m_iVal3 = 0;

 

    public TestClass(int iVal1, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

    }

 

    public TestClass(int iVal1, int iVal2, int iVal3)

    {

        this(iVal1, iVal2);    //여기서 오류가 발생한다.

        m_iVal3 = iVal3;

    }

}

C#에서는 생성자 Body안에서 생성자를 호출하는 것이 문법적으로 막혀있다.

Java에서는 Body안에 호출할 수는 있지만, 가장 처음에 호출하게 되었있는데,

C#에서는 아예 문법적으로 이를 제약하여 Body구문 이전에 이를 호출해야한다.

 

C#생성장에서 다른 생성자를 호출하려면 이렇게 해야한다.(C++을 써왔다면 익숙한 구문)

public class TestClass

{

    private int m_iVal1 = 0;

    private int m_iVal2 = 0;

    private int m_iVal3 = 0;

 

    public TestClass(int iVal1, int iVal2)

    {

        m_iVal1 = iVal1;

        m_iVal2 = iVal2;

    }

 

    public TestClass(int iVal1, int iVal2, int iVal3) : this(iVal1, iVal2)

    {

        m_iVal3 = iVal3;

    }

}


Google AdSense

+ Recent posts