- 자바 객채를 저장하거나 전송하기 위해서 자바 객체의 코드를 다시 복원가능한 형태의 Stream 으로 변경(?) 직렬화 시켜주는 것
  - 용어 설명
    * 직렬화 : Heap 에 위치한 객체를 출력 가능한 상태로 만드는 작업
    * 역직렬화 : 직렬화된 객체를 다시 Heap 에 넣기 위한 작업
    * 직렬화의 대상은 객체의 Attribute 의 값 (메소드는 그저 주소값만 필요) - Attribute 만 직렬화된단 말씀
    * 객체를 IO 하기 위해서는 필터 스트림인 ObjectInputStream & ObjectOutputStream 이 필요하다
    * 직렬화할 대상객치는 java.io.Serializable 를 implements 한 클래스(객체) 이어야 한다.


    EX) 직렬화 대상 클래스
    import java.io.*

    public class Member implements Serializable {
        private String name;
        private String address;
        private String hobby;
        private transient int age;  // 객체 Instance 앞에 transient 키워드를 붙여주면 직렬화 대상에서 제외 된다.
    }
   
    EX) 객체 직렬화 하기
    public void writeMenberObject(Member m) throws IOException {
        ObjectOutputStream oos = null;
 try {
     oos = new ObjectOutPutStream(new FileOutputStream("mem.obj") );  // 연결 + 필터 추가
     oos.writeObject(m);  // 객체를 출력하는 메소드 : writeObject(Object obj)
     // write 할때 Exception 이 발생하는데 이 때 close 를 안하면 스트림이 안닫혀 있는 상태로
 } fimally {
     if( oos != null ) {
             oos.close();  // close 해줌
          }
       }
    }

 

    EX) 역직렬화 된 객체를 복원하기
    public Member readMemberObject() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = null;
 Member m = null;
 try {
     ois = new ObjectInputStream(new FileInputStream("mem.obj") );
     m = (Member)ois.readObject();
 }finally {
         ois.close();
         return m;
         }
      }

 

  - 직렬화 대상 클래스 EX) 중에 인스턴스 변수명 앞에 "transient" -> 객체 직렬화 피하기!
    * 보안적인 측면에서 직렬화 할때 빼는 경우
    * 직렬화 대상이 아닌 객체의 Type
      - 예제를 보기전에 설명을 하자면 직렬화할 클래스에 implements Serializable 를 붙였다.

         Ex) Class Woochul implements Serialzable
        'Ex)' 의 'Woochul' class 에 다른 객체(Serialzable 안한 class)의 멤버 인스턴스를 가지고 있다면, 직렬화가 되지 않는다.
              이때도, transient 를 사용해서 제외시킨다.(코드를 수정하지 않아도 되는 이점이 있다고 한다.)

        EX) 객체 직렬화 피하기
 Class Woochul implements Serialzable{
     Ssung ssung = new Ssung(); -> transient Ssung ssung = new Ssung();  // 객체 직렬화 피하기
 }

 Class Ssung {
     ....
 }

 

  - 부록
    역직렬화해서 만든 객체(readObject() 메소드로 불러온 객체)의 클래스가 변경 되었을떄
    JVM 은 역직렬화 객체를 대입할수 없다고 예외를 발생 시킨다.
    직렬화, 역직렬화 할때 JVM 이 serialVersionUID 를 부여하는데 역직렬화해서 만든 객체의 클래스가 변경될때 이 값

    (serivalVersionUID) 변경이 되어 서로 일치하지 않아서 발생하는 현상이다.
    이를 해결하기 위해서 새로변경된 클래스와 역직렬화 하는 객체의 serialVersionUID 를 일치시켜주어야 한다.


    참고사이트 ->    #####  http://dojeun.egloos.com/317825   #######

'공부 > JAVA' 카테고리의 다른 글

JAVA_[Vector]  (0) 2012.07.31
JAVA_[Thread]  (0) 2012.06.23
JAVA_[Adapter_패턴 (일명 : Wrapper 패턴)]  (0) 2012.06.23
JAVA_[Eclipse_SerialVersionUID]  (0) 2012.06.23
JAVA_[코딩_지침]  (0) 2012.06.21

  - '이미 제공되어 있는 것'과 '필요한 것' 사이의 '차이'를 없애주는 디잔인 패턴 이 Adapter 패턴 (일명 : Wrapper 패턴)
 
  - Adapter 패턴의 종류
    * 클래스에 의한 Adapter 패턴 (상속을 사용한 Adapter 패턴)
      - 단점 : 상속 을 활용하기 때문에 유연하지 못하다.
      - 장점 : 어댑터를 전체를 다시 구현할 필요가 없다.(빠르다는 얘기)
      - 주의 : 자바는 다중상속을 지원하지 않는다. (Ex - public class Adapter extends Target, Adaptee{} )
        EX)
        public class Adaptee {
     public void specificRequest() {
         System.out.println("Adaptee.speificRequest()" );
     }
 }

        public interface Target{
     public void request():
 }
       
        public class Adapter extends Adaptee implements Target {
     public void request() {
         this.specificRequest();  // 다중상속
     }
 }

 public class Clinet {
     public static void main(String args[] ) {
         Target target = new Adapter();
  target.request();
     }
 }

 결과 : Adaptee.speificRequest(); 출력 된다.
 대충 소스를 보면 이해는 되겟는데... 설명하라면 못하겠다 -0-

 

 

 

    * 인스턴스에 의한 Adapter 패턴 (위임을 사용한 Adapter 패턴)
    - 단점 : Adapter 클래스의 대부분의 코드를 구현해야 하기 떄문에 효율적이지 못하다.
    - 장점 : 구성(Composition) 를 사용하기 때문에 더 뛰어나다(유연하다)
      EX)
      public class Adaptee {
          public void specificRequest() {
       System.out.println("Adaptee.speificRequest()" );
   }
      }

      public interface Target {
          public void request();
      }

      public class Adapter implements Target {
          Adaptee adaptee = new Adaptee();  // 객채 생성

   public void request() {
       adaptee.specificRequest():  // 객체 연결
   }
      }

      public class Clinet {
          public static void main(String args[] ) {
       Target target = new Adapter();

       target.request();
   }
      }
       결과 : Adaptee.speificRequest(); 출력 된다.

 

 

 

 

 

 

 

 

 

'공부 > JAVA' 카테고리의 다른 글

JAVA_[Thread]  (0) 2012.06.23
JAVA_[객체_직렬화]  (0) 2012.06.23
JAVA_[Eclipse_SerialVersionUID]  (0) 2012.06.23
JAVA_[코딩_지침]  (0) 2012.06.21
JAVA_[StringTokenizer 과 Split 의 차이]  (0) 2012.06.21

#### SerialVersionUID ####

 

- 데이타의 전송은 객체건 뭐건 바이트의 흐름으로 전송&저장 이 된다.

  다시 읽었을 때 객체의 자료구조를 그대로 보존하지 않으면 안된다(그것이 Serialzation)

  만일, serialVersionUID 를 지정하지 않으면 실행시점에서 JVM 이 디폴트 값을 산정하게 되며,

  그 알고리즘은 JAVA(TM) Objec Serialzation Specification 의 정의 된것을 따른다고 한다.

  한마디로 굳이 신경 쓸 필요는 없다는 뜻!

 

  모든 serialzation 이 필요한 클래스에는 명시적으로 serialVersionUID 를 선언해주는 것이 좋다.

  그 이유는 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에

  컴파일러 구현체에 따라 deserialzation(serialization 했던 객체를 복구하는 과정) 과정에서 예상하지 못한

  InvalidClassException을 유발할 수 있다는게 이유란다. 난 몬 소린지 모르겟다.

 

  위에 설명 다 집어 치우고 - 서로 다른 자바 컴파일러 구현체 사이에서도 동일한 serialVersionUID 값을 얻기 위해서는 명시적으로

  serivalVersionUID 값을 선언해야 하며 가능한 serivalVersionUID 을 pivate 으로 선언하라는 것이다.

  (상속되어 쓰여지는 것은 유용하지 않고, 해당 클래스에서만 쓰일 것이기 때문에...)

 

  - 설정 방법

  1. 첨부파일을 압축을 풀고, 이클립스 플러그인 디렉토리에 넣어두면 자동생성 플러그인 설치 끝

serialversionutil-civan.zip

 

  2. 설정 방법

 

 

  다음과 같이 Add SerialVersionUID 가 자동생성 후

  앞에 private 만 적어주면 완료.

 

 

 

   

'공부 > JAVA' 카테고리의 다른 글

JAVA_[객체_직렬화]  (0) 2012.06.23
JAVA_[Adapter_패턴 (일명 : Wrapper 패턴)]  (0) 2012.06.23
JAVA_[코딩_지침]  (0) 2012.06.21
JAVA_[StringTokenizer 과 Split 의 차이]  (0) 2012.06.21
JAVA_[텍스트파일읽기_예제]  (0) 2012.06.21

'공부 > JAVA' 카테고리의 다른 글

JAVA_[객체_직렬화]  (0) 2012.06.23
JAVA_[Adapter_패턴 (일명 : Wrapper 패턴)]  (0) 2012.06.23
JAVA_[Eclipse_SerialVersionUID]  (0) 2012.06.23
JAVA_[StringTokenizer 과 Split 의 차이]  (0) 2012.06.21
JAVA_[텍스트파일읽기_예제]  (0) 2012.06.21

- StirngToKenizer 과 Split 의 차이점

 

### StringTokenizer ####

 

보통 문자열을 쪼개서 사용을 할때 많이 사용하는 것이 String Tokenizer 이다.

하지만, 조심해야 한다. 특정 구분자로 문자를 자를때 Null 값을 출력하지 못한다.

예를 들면,

String _str = "최우철|김진성||김성수";

StringTokenizer _tokens = new StringTokenizer(_str, "|");

for ( int i = 1; tokens.hasMoreElements(); i++ ) {

System.out.println("문자" + i + " = " + tokens.netToken() );

}

결과는

문자1 = 최우철

문자2 = 김진성

문자3 = 김성수

 

이렇게 나오게 된다. 즉 구분자("|") 로 따지면 Null 값이지만 값은 4개다.

하지만, 인식을 못한다.

만약에, DB 에 INSERT 한다면, 필드가 하나 빠지게 된다.

조심하자. 그래서 SDK 1.4 부터 나온 Split() 가 있다.

 

### Split ####

 

Stirng _str = "최우철|김진성||김성수";

String[] _values = _str.split("|");

for( int i = 0; x < _values.length; i++ ) {

System.out.println("문자" + (i+1) + " = " + _values[i] );

}

결과는

문자1 = 최우철

문자2 = 김진성

문자3 =

문자4 = 김성수


만약에, 맨 뒤에 값이 없을 경우에는 어떻게 처리할까?

String _str = "최우철|김진성|김성수||";

String[] _values = _str.split("|");

결과는

문자1 = 최우철

문자2 = 김진성

문자3 = 김성수

이렇게 나온다. 참고! split / StringTokenizer 두개 모두 이런경우에는 3개만 나온다.

하지만 마지막 데이타도 Null 값으로 출력을 하고 싶다면...

당연 split() 메서드다.

이클립스 split() 자동완성 API 를 보면 오보로딩 된 메서드로 2개가 있다.

1. split( String regex ) / 2. split( String regex, int limit )

2번 split( String regex, int limit ) 를 사용하면 limint int 만큼 배열의 Null 값 입력

문자열이 limit int 보다 크면 limit int 만큼만 출력하고 나머지는 버린다.

'공부 > JAVA' 카테고리의 다른 글

JAVA_[객체_직렬화]  (0) 2012.06.23
JAVA_[Adapter_패턴 (일명 : Wrapper 패턴)]  (0) 2012.06.23
JAVA_[Eclipse_SerialVersionUID]  (0) 2012.06.23
JAVA_[코딩_지침]  (0) 2012.06.21
JAVA_[텍스트파일읽기_예제]  (0) 2012.06.21

- 회사에서 '우편모아 시스템' 도로명 주소 검색시 INSERT 를 위해 GOOGLE 검색해서 만든 코드.

  1줄씩 읽어와서 처리. 특정 경로의 1개의 파일만 읽을시에는 File file = new File("경로/텍스트파일명")

  특정 폴더의 모든 텍스트 파일을 읽어 오려면 아래의 예제 처럼 사용하면 된다.

  사용하는 코드를 그대로 옮겨 놓은 것이므로 조금은 예제의 목적에 맞지 않지만 이해하자.

 

 

#### JAVA_텍스트파일읽기_예제 ####

 

 

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;

import com.srpost.salmon.lang.StringUtil;

public class ConversionMain {
   
    /* 새주소 텍스트 파일 postmoa insert 변환 */
    /* 텍스트 파일 구분자 */
    private final static String DELIM = "|";
    /* 변환할 도로명주소 텍스트파일 저장경로 */
    private final static String READ_TXT_PATH = "D:/DEV/PROJECTS/postmoa_juso_conversion/file/read/";
    /* 변환후 도로명주소 텍스트파일 저장경로 */
    private final static String CREATE_TXT_PATH = "D:/DEV/PROJECTS/postmoa_juso_conversion/file/create/";

    public static void main(String[] args) throws Exception {

        try {
            File file = new File(READ_TXT_PATH);
            File[] files = file.listFiles();

            /* READ_TXT_PATH 경로의 파일 수 체크 */
            int _fileLen = files.length;
            System.out.println(" [FileLength] :" + _fileLen);

            // FileReader fr = null;
            BufferedReader br = null;

            String read = null;

            for (int i = 0; i < files.length; i++) {
                String fileName = files[i].getName();
                String filePath = files[i].getPath();
                System.out.println(" [FileName] : " + fileName);
                System.out.println(" [FilePath] : " + filePath);

                // fr = new FileReader(filePath);
                File _encodingFile = new File(filePath);

                /* 인코딩 해서 BufferedReader */
                br = new BufferedReader(new BufferedReader(
                        new InputStreamReader(
                                new FileInputStream(_encodingFile), "UTF-8")));

                /* 변환 후 텍스트 파일 생성 */
                FileWriter out = new FileWriter(CREATE_TXT_PATH + "변환_" + fileName);

                while ((read = br.readLine()) != null) {

                   /* 회사 Salmon 프레임워크 코드 문자열 구분자("|") 잘라서 String[] 에 넣기 */
                    String[] _linez = StringUtil.fastSplit(read, DELIM);

                    String _lineStr = "";

                    _lineStr = _linez[19] + "|" + _linez[1] + "|" + _linez[2]
                            + "|" + _linez[3] + "|" + _linez[4] + "|"
                            + _linez[5] + "|" + _linez[6] + "|" + _linez[7]
                            + "|" + _linez[9] + "|" + _linez[11] + "|"
                            + _linez[12] + "|" + _linez[13] + "|" + _linez[14];
                    out.write(_lineStr + "\n");
                }
                out.close();
            }
            // if(fr!=null)fr.close();
            if (br != null)
                br.close();

            System.out.println(" [FileCreate_End !!!] ");
        } catch (Exception e) {
            System.out.println("Error :" + e.getMessage());
        }

    }// end - main
}// end - class

 

'공부 > JAVA' 카테고리의 다른 글

JAVA_[객체_직렬화]  (0) 2012.06.23
JAVA_[Adapter_패턴 (일명 : Wrapper 패턴)]  (0) 2012.06.23
JAVA_[Eclipse_SerialVersionUID]  (0) 2012.06.23
JAVA_[코딩_지침]  (0) 2012.06.21
JAVA_[StringTokenizer 과 Split 의 차이]  (0) 2012.06.21

+ Recent posts