SSISO Community

시소당

객체 직렬화(Serializable)

*  객체직렬화의  개념

  

자바  I/O  처리는  정수,  문자열,  바이트  단위의  처리만  지원했었다.

따라서  복잡한  객체의  내용을  저장/복원하거나,  네트워크로  전송하기  위해서는  객체의  멤버변수의

각  내용을  일정한  형식으로  만들어(이것을  패킷이라고  한다)  전송해야  했다.

  

객체직렬화는  객체의  내용(구체적으로는  멤버변수의  내용)을  자바  I/O가  자동적으로  바이트  단위로  변환하여,  저장/복원하거나  네트워크로  전송할  수  있도록  기능을  제공해준다.

즉,  개발자  입장에서는  객체가  아무리  복잡하더라도,  객체직렬화를  이용하면  객체의  내용을  자바  I/O가  자동으로  바이트  단위로  변환하여  저장이나  전송을  해주게  된다.

또한  이것은  자바에서  자동으로  처리해주는  것이기  때문에,  운영체제가  달라도  전혀  문제되지  않는다.

  

객체를  직렬화할때  객체의  멤버변수가  다른  객체(Serializable  인터페이스를  구현한)의  레퍼런스  변수인  경우에는  레퍼런스  변수가  가리키는  해당  객체까지도  같이  객체직렬화를  해버린다.

또  그  객체가  다른  객체를  다시  가리키고  있다면,  같은  식으로  객체직렬화가  계속해서  일어나게  된다.

이것은  마치  객체직렬화를  처음  시작한  객체를  중심으로  트리  구조의  객체직렬화가  연속적으로  일어나는  것이다.

  

  

*  도입이유

  

1.  RMI의  도입

RMI는  원격객체통신을  지원해야  하기  때문에,  객체의  내용이  투명하게  이동할  수  있어야  한다

  

2.  Beans

Beans는  설계시에  상태정보를  지정할  수  있는데,  이것을  마땅히  저장할  메커니즘이  없다.

이때  객체직렬화를  사용하면,  편하게  객체의  상태정보를  저장하는  것이  가능하다

  

3.  간단한  네트워크  프로그램이나  파일  프로그램은  객체직렬화를  사용하면,  코딩이  반으로  준다.

  

  

  

*  객체  직렬화의  과정

  

객체는  ObjectOutputStream의  writeObject()  메쏘드에  자신을  넘김으로써  직렬화  된다.
writeObject()메쏘드는  private  필드와  super  클래스로부터  상속받은  필드를  포함,
객체의  모든  것을  기록하게된다.
  
직렬화  해제는  직렬화와  반대의  과정을  거치게  되는데
ObjectInputStream의  readObject()  메서드를  호출함으로써
스트림으로부터  읽어  들이고  이를  직렬화  되기전의  객체로  다시  만들게  된다.

직렬화에  대한  간단한  예제이다.

ObjectOutputStream을  생성해서  writeObject()  메서드를  이용해서  객체를  직렬화하고,
ObjectInputStream을  생성해서  readObject()  메서드를  통해서  객체를  복원한다.
또한  SerializableClass가  Serializable을  implements한  것을  주의해서  보아야  한다.

  

----------------------------------------------------------------------------------

ObjectSerializableTest.java

  


import  java.io.*;

  

public  class  ObjectSerializeTest  {

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


//  파일을  열어서  그곳에  객체를  직렬화시켜서  저장한다.
//  파일  출력스트림을  연다.
FileOutputStream  fileout  =  new  FileOutputStream("test.txt");

  

//  객체스트림을  열고,  객체스트림을  통해  객체를  파일에  저장
ObjectOutputStream  out  =  new  ObjectOutputStream(fileout);
out.writeObject(new  SerializableClass("Serialize  Test  Program",  1014));

  

//  객체스트림을  닫는다.
out.close();

  

//  직렬화  된  객체를  저장된  파일로  부터  객체를  해제시켜  원래의  객체로  복원
//  파일  입력스트림으로부터  객체  입력스트림을  연다.
FileInputStream  fileinput  =  new  FileInputStream("test.txt");
ObjectInputStream  in  =  new  ObjectInputStream(fileinput);

  

//  객체  입력스트림으로부터  객체를  읽어온다.
SerializableClass  sc  =  (SerializableClass)in.readObject();

  

//  객체스트림을  닫는다.
in.close();

  

//  스트림으로부터  읽어들인  객체의  내용을  출력
//  원래  생성되었던  객체와  같은  값을  갖는다는  것을  알수가  있다.
System.out.println("String  :  "  +  sc.Sstr);
System.out.println("Integer  :  "  +  sc.Sint);
}
}


//  하나의  문자열과  정수를  저장하고  있는  SerializableClass를
//  Serializable을  implements  함으로써
//  스트림을  통해  직렬화되고  해제되어질  수  있다.

class  SerializableClass  implements  Serializable  {

public  String  Sstr;
public  int  Sint;

  

//  생성자
public  SerializableClass(String  s,  int  i)  {
this.Sstr  =  s;
this.Sint  =  i;
}
}

  


-----------------------------------------------------------------
실행결과

  

String  :  Serialize  Test  Program
Integer  :  1014

  

  

  

  

========================================================================================

자바는  객체지향언어이다.

즉,  가상머신  내에  존재하는  것은  모두  객체들로  이루어져  있습니다.

물론,  객체를  만들기  위한  클래스들도  있겠죠.

클래스의  형태를  보고  필요하다면  언제든지  객체를  만들어  낼  수  있습니다.

객체와  클래스의  관계를  논하지  않고서는  아무것도  할  수  없겠죠.

컴파일  한  후,  생성된  .class파일은  클래스의  모든  정보를  담고  있으며,

이  .class의  바이트는  가상머신에  Class클래스의  형태로  로딩  되어  집니다.

그리고,  로딩된  클래스의  정보를  보고  객체를  만들게  됩니다.

클래스는  데이터  타입이며  이  데이터타입이  있어야  그  모양을  보고  객체의  메모리를  생성할  수  있습니다.

  

특정  클래스의  객체를  만들었을  때  객체는  무엇으로  이루어져  있을까요?

객체는  멤버변수의  메모리의  크기와  같다.  

객체는  멤버변수의  메모리만으로  이루어져  있습니다.

만약,  객체를  이용해서  메서드를  호출한다면  객체가  보유하고  있는  값과  호출할  메서드의  형태만  있으면  언제든지  호출  가능합니다.

메서드의  형태는  클래스의  정보가  있는  부분에  있을  것이고,

메서드  내에  멤버변수가  사용되어진다면,  그  값은  객체  내에  있으니  이  두  가지를  조합한다면  언제든지  메서드를  호출할  수  있습니다.  

  

가상머신에  존재하는  객체메모리  그  자체를  저장하거나,  통째로  네트웍으로  전송하려고  합니다.

저장을  하든  네트웍으로  전송을  하든간에  객체는  일련의  바이트의  형태로  되어  있어야  합니다.

어떤  규칙에  의해서  객체  메모리를  한  줄로  늘어선  바이트의  형태로  만들고,

다시  객체의  형태로  복원하는  작업을  우리는  객체  직렬화라고  합니다

  

  

‘이름’,  ‘부서’,  ‘직책’  이라는  속성을  가진  직원  클래스가  있고,  이  클래스를  이용하여  두  개의  객체  (직원1  객체와  직원2  객체)가  생성되어  메모리에  저장되어  있다면,

직원1  객체는  이름이  홍길동이고  부서는  총무부,  직책은  과장이라는  상태  정보를  저장하고  있습니다.

  

이러한  객체들이  저장  되어  있는  메모리는  휘발성이기  때문에,

컴퓨터의  전원을  종료하게  되면  객체의  상태  정보는  모두  사라집니다.

그래서  우리는  이  정보를  데이터베이스에  저장하거나  아니면  따로  기록해  두는  것입니다.

다시  객체로  만들려면  데이터베이스  내용을  검색해서  해당  내용을  찾아와서  객체의  형태로  다시  조합해야  합니다.

  

이러한  방법을  사용하는  대신,  객체  그  자체를  바로  저장하고  다시  불러왔을  때  원래의  객체  형태  그  자체라면  아주  효율적이겠죠.

  

정민철,영업부,부장  이라는  정보를  묶어서  소켓으로  전송한다면  다음과  같이  전송할  겁니다.

  

정민철|영업부|부장

  

이러한  방법으로  보내면  받는쪽에서는  “|”을  구분자로  해서  하나씩  분해해야  합니다.

만약  객체자체를  보낸다면  상황은  다릅니다.  다음과  같은  객체를  보낸다면

  

--------------------------------------------------------------

Employee.java

  

  

public  class  Employee  {

      private  String  name;                          //  이름

      private  String  dept;                              //  부서

      private  String  duties;                        //  직책

  

      public  Employee  (String  name,  String  dept,  String  duties)  {

              this.name  =  name;

              this.dept  =  dept;

              this.duties  =  duties;

      }//  생성자

  

public  static  void  main(String[]  args){

              Employee  Emp  =  new  Employee("조한서",  "인사","차장");

          //Emp  자체를  네트웍으로  전송

      }

}

  

Emp  객체를  네트웍을  통해서  받았다면  바로  객체를  사용할  수  있다는  장점이  있습니다.

파싱할  필요도  없고,  특별한  작업  없이도  객체를  사용할  수  있는  방법론을  제공하는  것이  바로  객체  직렬화입니다.

이  개념이  RMI,  Java  Beans등의  핵심  기술이  됩니다.

  

객체  직렬화는  상당히  복잡한  과정을  필요로  하지만,  내부적으로  완벽하게  감추어져  있기  때문에  객체  직렬화를  직접  구현을  하는  것이  아니라  규칙에  맞게  사용하는  방법을  배우는  것이라고  보면  됩니다.

  

객체  직렬화에  대해서  정리하면

  

객체  직렬화는  객체의  상태를  보존하는  방법론을  제공한다.

파일  스트림,  네트워크  스트림  등과  함께  사용할  수  있는  확장성을  제공한다.

  

실제로  객체  직렬화  기술은  원격메소드호출(RMI  :  Remote  Method  Invocation)과  같은  기술에서  중요하게  사용이  됩니다.

RMI는  한쪽의  자바  가상  머신  내에  있는  객체가  멀리  떨어져  있는  원격지의  자바  가상  머신  내  객체를  네트워크를  통해  접근하고,

메서드를  호출  할  수  있게  해주는  기술입니다.

두  자바  가상  머신  사이에  연결된  바이트  스트림을  통해  메서드의  인자나  반환  값으로  객체를  주고  받기  위해서  객체  직렬화  기술이  사용됩니다.

또한,  EJB라는  기술에서도  EJB  컨테이너의  성능  향상을  위해  사용됩니다.

  

객체  스트림에  저장될  객체는  Serializable이나  Externalizable  인터페이스를  구현  함으로써,  객체  자신이  저장될  의사가  있음을  반드시  밝혀야  합니다.

  

Serializable인터페이스는  아무  메서드도  가지고  있지않은  표시(태그)  인터페이스입니다.  Serializable인터페이스를  구현한  객체는  객체  스트림  클래스들이  자동으로  필드들의  값을  저장하고  복구  해주지만,

Externalizable인터페이스를  구현한  객체는  객체를  표현할  필드들의  종류와  값을  writeExternal()메서드와  readExternal()메서드를  사용해서  직접  저장하고  복원하는  과정을  구현해야  합니다.  

  

  

*  interface  Serializable

  

객체직렬화가  필요한  객체는  반드시  Serializable  인터페이스르  구현해야  한다.

그러나,  Serializable  인터페이스는  객체가  직렬화가  제공되어야  함을  자바가상머신(JVM)에  알려주는  역할만을  하는  인터페이스다.

따라서,  Serializable  인터페이스를  지정하였다고  해도,  구현할  메서드는  없다.

  

보낼  객체가  직렬화  되어  있으면  전송은  특정  장치에  연결되어  있는  스트림이  모두  해결합니다.

우선  파일이나  네트웍에  스트림을  생성  한  후  객체를  보낼  수  있는  스트림으로  변환을  합니다.

그리고  직렬화되어  있는  객체를  보내면  됩니다.

그  순서를  정리하면  다음과  같습니다.

  

1.  네트웍이나  파일등에  스트림을  생성한다.

2.  생성된  스트림을  Object스트림으로  변환한다.

3.  입력과  출력스트림은  ObjectInputStream과  ObjectOutputStream이다.

4.  직렬화된  객체를  객체스트림을  통해서  전송한다.

        -  ObjectOutputStream  à  writeObject(직렬화된객체)

5.  객체  스트림을  통해서  직렬화된  객체를  받는다.

        -  ObjectInputStream  à  readObject()

  

이와  같은  순서로  객체  직렬화를  구현합니다.

스트림은  I/O에서  제공해  주기  때문에  보낼  객체만  생각하면  됩니다.

보낼  객체에  impelements  Serializable만  붙이면  됩니다.

  

-------------------------------------------------------------

SerializableObject.java

  

  

import  java.io.*;

  

public  class  SerialObject  implements  Serializable{

      private  String  name;                //  이름

      private  String  dept;                    //  부서

      private  String  duties;              //  직책

      public  SerialObject  (String  name,  String  dept,  String  duties)  {

              this.name  =  name;

              this.dept  =  dept;

              this.duties  =  duties;

      }

      public  String  toString(){

              return  name  +  ":"  +  dept  +  ":"  +  duties;

      }

}

  

임의의  파일에  객체  스트림을  연결하여  객체를  읽고  기록해  봅니다.

아래의  예는  객체를  기록한  후  다시  읽어내는  예제입니다.

  

----------------------------------------------------------------------

SerialObject.java

  

  

import  java.io.*;

  

public  class  SerialObjectTest  {

            

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

  

          FileOutputStream  fileout  =  new  FileOutputStream("test.txt");

            ObjectOutputStream  out  =  new  ObjectOutputStream(fileout);

              SerialObject  se1  =  new  SerialObject("김언어",  "개발부",  "팀장");

              SerialObject  se2  =  new  SerialObject("김서리",  "자금부",  "부장");

              SerialObject  se3  =  new  SerialObject("이회계",  "경리부",  "차장");

              out.writeObject(se1);

              out.writeObject(se2);

              out.writeObject(se3);

              out.close();

  

              FileInputStream  filein  =  new  FileInputStream("test.txt");

              ObjectInputStream  in  =  new  ObjectInputStream(filein);

              SerialObject  iso1  =  (SerialObject)in.readObject();

              SerialObject  iso2  =  (SerialObject)in.readObject();

              SerialObject  iso3  =  (SerialObject)in.readObject();

              System.out.println(iso1.toString());

              System.out.println(iso2.toString());

              System.out.println(iso3.toString9));

              in.close();

      }

}

  

  

test.txt파일에  파일출력스트림을  생성합니다.

그리고  이  파일출력스트림을  Object출력스트림으로  변환합니다.

스트림을  열었다면  implements  Serializable로  구현된  객체를  만들어야합니다.

위의  예제에서는  3개의  객체를  만들었습니다

그리고  이  객체를  test.txt파일에  객체가  3개이니  3번  기록  해야  합니다.

마지막으로  출력스트림을  닫습니다.

소스의  이  부분까지  수행되면  test.txt가  만들어지고  객체  3개가  순서대로  기록되게  됩니다.

  

입력된  객체를  읽어  내기  위해서  test.txt파일에  파일입력스트림을  생성합니다.

그리고  생성된  파일입력스트림을  Object입력스트림으로  변환합니다.

변환된  Object입력스트림으로  객체를  읽어냅니다.

앞에서  3개  입력했으니  3번만  읽어  내도록  합니다.

그리고  Object입력스트림으로  읽었을  때

반환형이  Object형이기  때문에  강제  Downcasting시켜야  합니다.

마지막으로  Object입력스트림을  닫으시면  모든  작업은  끝납니다.

  

  

Object스트림은  스트림의  한  종류입니다.

직렬화  된  객체를  보낼  수  있는  스트림이라고  말할  수  있습니다.  

객체를  객체출력스트림에  쓸  때는  ObjectOutputStream  클래스의  writeObject()  메서드를  사용합니다.

writeObject()의  원형의  다음과  같습니다.

  

public  final  void  writeObject(Object  obj)  throws  IOException

  

  writeObject()메서드는  인자로  넘어  온  객체가  Serializable인터페이스나  Externalizable  인터페이스를  구현했는지  검사합니다.

  

주어진  객체가  Serializable  인터페이스를  구현했다면,

writeObject()메서드는  자동으로  객체의  상태를  스트림에  기록해  줍니다.

만약  객체가  Serializable이나  Externalizable인터페이스  중  어느것도  구현하지  않았다면,  NotSerializableException을  발생시킵니다.

  

스트림에  직렬화  되어있는  객체는  ObjectInputStream  클래스의  readObject()  메서드를  사용해서  복원  할  수  있습니다.

readObject()의  원형은  다음과  같습니다.

  

public  final  Object  readObject()  throws  IOException,  ClassNotFoundException

  

  readObject()메서드는  연결된  스트림으로부터  객체의  상태  정보를  읽어  내고,

writeObject()메소드와  마찬가지로  readObject()메서드  역시  객체가  Serializable  인터페이스를  구현했다면  스트림에  쓰여져  있던  객체의  상태  정보를  기반으로  자동으로  새로운  객체를  복원해  줍니다.

  

  

*  transient  키워드

  

객체직렬화  전후에  보존하고  싶지  않은  멤버변수가  있을  경우에는,  해당  멤버변수에  transient  키워드를  사용함으로써  객체직렬화시  내용을  저장하지  않을  수  있다.

예를  들어  패스워드나  중요한  정보는  객체직렬화로  저장을  하게되면,  복원시에  누구라도  내용을  도로  알아낼  수가  있다.

따라서,  이러한  정보를  갖게되는  멤버변수는  transient  키워드를  사용해서  선언해주는  것이  좋다.

  

스트림을  이용해서  직렬화  할  때  객체의  모든  상태정보를  직렬화하게  됩니다.

하지만,  클래스를  디자인하다  보면  순간적으로  사용하고  버리는  필요없는  정보도  있습니다.  이러한  정보를  제외  시키기  위해서  transient키워드를  사용합니다.

  

클래스를  만들다  보면  중요하지는  않지만  전역  변수로  사용하기  위해서  어쩔  수  없이  멤버변수로  만드는  경우가  있습니다.

저장할  필요가  없다고  생각된다면  접근지정자  다음에  transient를  붙이면  직렬화에서  

제외되어  버립니다.

  

객체를  직렬화  하는데  제외하겠다는  의미  이외에는  별다른  개념은  없습니다.

직렬화  될  필드가  static,  transient로  선언되어  있으면  직렬화할  때  제외됩니다.

static변수는  공유메모리  개념을  가지고  있기  때문에  직렬화  할  때  제외  됩니다.

  

  

---------------------------------------------------------------------------------------------------------

TransientTest.java

  

  

import  java.io.*;

  

public  class  TransientTest  implements  Serializable
{


          //  멤버변수
          private  String  name;
          transient  String  passwd;

  

  //  생성자
  public  TransientTest(String  s,  String  p)
  {
            name  =  s;
            passwd  =  p;
            System.out.println("생성자가  호출되었습니다:  "  +  name);
  }

  

  //  toString()  메서드를  오버라이드하여
  //  println()  메서드에서  사용할때,  내용을  출력하도록  변경
  public  String  toString()
  {
            return  "이름은  "  +  name+  "  :  패스워드  :  "  +  passwd;
  }

  

  public  static  void  main(String  args[])
  {
            TransientTest  tt1,  tt2;
            tt1  =  new  TransientTest("김가방","1234");
            tt2  =  new  TransientTest("이치민","0011");

    try
    {
              //  객체직렬화로  파일에  저장하기  위해
              //  FileOutputStream에서  ObjectOutputStream  생성
              ObjectOutputStream  out  =  new  ObjectOutputStream(new  FileOutputStream("TransientTest.ser"));

            

              //  writeObject()  메서드를  사용하여  객체  저장
              out.writeObject(tt1);
              out.writeObject(tt2);
              out.close();

  

              //  객체직렬화로  파일에  저장된  객체를  복원하기  위해
              //  FileInputStream에서  ObjectInputStream  생성
              ObjectInputStream  in  =  new  ObjectInputStream(new  FileInputStream("TransientTest.ser"));

      

              TransientTest  tt3,  tt4;

  

              //  해당  스트림에서  readObject()  메서드를  호출
              tt3  =  (TransientTest)in.readObject();
              tt4  =  (TransientTest)in.readObject();

              System.out.println("다시  복원합니다");

    

                //  내용을  출력한다
              System.out.println(tt3);
              System.out.println(tt4);
    }catch(Exception  e)  {e.printStackTrace();}
  }
}

  

  

======================================================

출력내용

  

생성자가  호출되었습니다:  김가방
생성자가  호출되었습니다:  이치민
다시  복원합니다
이름은  김가방  :  패스워드  :  null
이름은  이치민  :  패스워드  :  null

-----------------------------

name  멤버변수는  그대로  복원이  되었으나,

transient로  되어있는  passwd  멤버변수는  null값이  들어있다.

  

  

  

*  Externalizable

  

객체직렬화의  또  다른  방법으로는  Externalizable인터페이스를  사용하는  것입니다.

그  기본  개념은  Serializable과  같습니다.

Externalizable자체가  Serializable인터페이스를  상속한  인터페이스이기  때문입니다.  인터페이스는  인터페이스  끼리는  상속의  개념이  적용됩니다.

  

그래서  그  Externalizable의  원형은  다음과  같습니다.

  

public  interface  Externalizable  extends  Serializable  {

      public  void  writeExternal(ObjectOutput  out)  throws  IOException;

  

      public  void  readExternal(ObjectInput  in)  throws  IOException,

                                                                                                                                                          ClassNotFoundException;

}

  

Externalizable  인터페이스는  2개의  메서드를  구현해야만  사용  가능합니다.

그리고  Serializable보다  미세한  직렬화를  다루기  위해서  사용됩니다.

Serializable에서는  자동으로  데이터가  기록되지만

Externalizable에서는  기록하는  부분을  직접  제어합니다.

  

이  때  기록하는  부분은  writeExternal()  메서드에  구현을  하며

읽어내는  부분은  readExternal()  메서드에  만들어  줍니다.

writeExternal()  메서드에서  사용자가  임의로  기록하는  방법을  구현했다면

읽어내는  해답을  갖고  있는  것은  writeExternal()을  구현한  개발자  자신입니다.

거의  암호화의  개념에  가깝다.

  

  

-------------------------------------------------------------------------

ExternalObject.java

  

  

import  java.io.*;

  

public  class  ExternalObject  implements  Externalizable  {

  

      private  int  dept;                              //  부서

      private  String  name;              //  이름

      private  float  duties;                  //  직책

  

      public  ExternalObject(){}

  

      public  ExternalObject(int  dept,  String  name,  float  duties)  {

              this.dept  =  dept;

              this.name  =  name;

              this.duties  =  duties;

      }

      public  void  readExternal(ObjectInput  in)  throws  IOException,

                                                                                                                                                          ClassNotFoundException

{

              System.out.println("readExternal()  메서드입니다.");

              dept  =  in.readInt();

              name  =  (String)in.readObject();

              duties  =  in.readFloat();

      }

      public  void  writeExternal(ObjectOutput  out)  throws  IOException  {

              System.out.println("writeExternal()  메서드입니다.");

              out.writeInt(dept);

              out.writeObject(name);

              out.writeFloat(duties);

      }

      public  String  toString(){

              return  dept  +  ":"  +  name  +  ":"  +  duties;

      }

}

  

  

매개변수로  넘어오는  ObjectOutput의  객체  out을  이용하여  기록하고  싶은  부분을  차례대로  write해주고  있습니다.

물론  필요로  하는  대부분의  write메서드는  이미  존재합니다.

여기서는  간단히  int,  String,  float만을  기록하였지만

ObjectOutput  인터페이스가  제공해주는  writeBoolean,  writeByte,  writeBytes,  writeChar,  writeChars,  writeDouble,  writeFloat,  writeInt,  writeLong,  writeShort,  writeUTF  메서드들을  전부  사용할  수  있습니다.

그리고,  다시  이것을  읽어  오는  부분은  기록한  차례대로  읽어오면  됩니다.

  

정확하게  순서를  맞추어  호출해  주어야  합니다.

만약  이것의  순서를  바꾼다면    에러를  만나게  될  것입니다.

그리고  마지막으로  직렬화된  데이터를  읽어들여서  객체를  만들기  위해  인자없는  생성자가  필요합니다.

이것을  만들어주지  않으면  에러메시지에서  인자없는  생성자를  요구할  것입니다

  

  

---------------------------------------------------------------------------

ExternalObjectTest.java

  

  

import  java.io.*;

  

public  class  ExternalObjectTest  {

            

      public  static  void  main(String[]  args)  throws  IOException,  ClassNotFoundException{

  

              FileOutputStream  fileout=  new  FileOutputStream("exTest.txt");

              ObjectOutputStream  out=  new  ObjectOutputStream(fileout);

              ExternalObject  eo1  =  new  ExternalObject(1,  "김사양",  170.25f);

              ExternalObject  eo2  =  new  ExternalObject(2,  "이거지",  190.01f);

              ExternalObject  eo3  =  new  ExternalObject(3,  "삼다수",  180.34f);

              out.writeObject(eo1  );

              out.writeObject(eo2  );

              out.writeObject(eo3  );

              out.close();

  

              FileInputStream  filein  =  new  FileInputStream("exTest.txt");

              ObjectInputStream  in  =  new  ObjectInputStream(filein);

              ExternalObject  eso1  =  (ExternalObject)in.readObject();

              ExternalObject  eso2  =  (ExternalObject)in.readObject();

              ExternalObject  eso3  =  (ExternalObject)in.readObject();

              System.out.println(eso1.toString());

              System.out.println(eso2.toString());

              System.out.println(eso3.toString());

              ois.close();

      }

}

[출처]  객체  직렬화(Serializable)|작성자  로비즈
http://blog.naver.com/robiz?Redirect=Log&logNo=110009710978

727 view

4.0 stars