JavaRush /Java Blog /Random-KO /커피 브레이크 #180. Java의 변수: 정의 및 사용 방법 Java의 직렬화 및 역직렬화에 대해 알...

커피 브레이크 #180. Java의 변수: 정의 및 사용 방법 Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 사항

Random-KO 그룹에 게시되었습니다

Java의 변수: 변수는 무엇이며 어떻게 사용됩니까?

출처: Hackernoon Java에는 프로그램에서 선언된 위치에 따라 네 가지 유형의 변수가 있습니다. 오늘은 각 유형의 예와 차이점을 알아보겠습니다. 커피 브레이크 #180.  Java의 변수: 정의 및 사용 방법  Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 - 11. 인스턴스 변수 또는 인스턴스 필드는 static 키워드 없이 클래스 내부에 선언되지만 메서드, 생성자 또는 코드 블록 외부에 선언된 변수입니다. 이러한 변수는 클래스 내 어디에서나 선언될 수 있습니다. public , private , protected 또는 default (키워드 아님) 와 같은 액세스 한정자를 사용하거나 사용하지 않고 선언할 수 있습니다 .
public class MyClass {

  //instance field 1
  private String instanceField1;

  public MyClass(){} //Constructor

  //instance field 2
  public int anotherInstanceField2;

  public void setInstanceField(String parameterVariable) {...} //instance method

  //instance field 3
  boolean instanceField3;

  public static void main(String[] args) {
    System.out.println("field 1 value: " + instanceField1); // = null
    System.out.println("field 2 value: " + anotherInstanceField2); // = 0
    System.out.println("field 3 value: " + instanceField3); // = 0
  }
}
인스턴스 필드에 선언 시 값이 할당되지 않은 경우 기본 유형(예: int , boolean , long , float ) 이면 기본값 0이 할당되고 기본 유형이 아닌 경우 null이 할당됩니다. 예를 들어 ( String , Integer , AnyClass ). 선언된 클래스에서 생성된 객체의 인스턴스에 속하기 때문에 필드 또는 인스턴스 변수라고 합니다.
public Main {

  public static void main(String[] args) {
    MyClass obj1 = new MyClass();
    MyClass obj2 = new MyClass();

    //Now we can access every 'public' field declared in the MyClass class
    // from the newly created object 'obj'

    obj1.anotherInstanceField2 = 11;
    obj2.anotherInstanceField2 = 33;

    System.out.println(obj1.anotherInstanceField2); // prints '11'
    System.out.println(obj2.anotherInstanceField2); // prints '33'
  }
}
따라서 위의 코드 조각에서 볼 수 있듯이 각 인스턴스 필드는 해당 개체에 대해 고유합니다. 여기에서 obj1obj2 는 각각의 인스턴스 필드에 고유한 값이 할당되어 있습니다. 2. 클래스 필드 또는 정적 필드는 static 키워드 로 선언된 필드입니다 . 클래스 내부에서 선언되지만 메서드, 생성자 또는 코드 블록 외부에서 선언됩니다. 또한 public , private , protected 또는 default (키워드 아님)와 같은 액세스 한정자를 사용하거나 사용하지 않고 클래스 내의 어느 위치에서나 선언할 수 있습니다 .
public class MyClass {

  //static field
  public static String staticField;

  public MyClass(){} //Constructor

}

class Main {

  public static void main(String[] args) {

    MyClass obj = new MyClass();

    obj.staticField //will throw Not defined Error

    //Now we cannot access the static field declared in MyClass class from the
     // newly created object 'obj' because static fields are not attached to any
    // object. They belong solely to the class they are declared and can only be
    // accessed from their class.

    MyClass.staticField = "I am a static field";
    System.out.println(MyClass.staticField); // prints 'I am a static field'
  }
}
위의 코드 조각에 표시된 것처럼 정적 필드는 해당 클래스를 통해서만 액세스할 수 있으며 객체에서는 액세스할 수 없습니다. 3. 매개변수 또는 인수 변수는 메소드 시그니처의 여는 중괄호와 닫는 중괄호 사이에 있는 메소드 구문 내에서 선언된 변수입니다. 값이나 객체를 메소드에 전달하는 데 사용됩니다.
public class MyClass {

  //instance field
  public String instanceField;

  public MyClass(){} //Constructor

  //instance method with a parameter variable
   public void setInstanceField(String parameterVariable) {
      instanceField = parameterVariable;
   }
}

class Main {

  public static void main(String[] args) {

    MyClass obj = new MyClass();

    obj.setInstanceField("From a parameter variable");

    System.out.println(obj.instanceField); // prints 'From a parameter variable'
  }
}
4. 지역 변수는 메소드나 코드 블록 내에서 선언된 변수입니다(예: if 문 블록 , for 루프 , while 루프 , switch 문 블록 등).
public Main {

  public static void main(String[] args) {
    MyClass obj1 = new MyClass(); // 'obj1' is local reference variable

    int id = 1; // 'name' is a local variable here.

    if (id > 1) {
        String tempName = "Austin"; // 'tempName' is a local reference variable
     }
  }
}
이 코드에서는 일부 변수에 참조가 사용되는 것을 볼 수 있지만 로컬 변수 id는 참조 변수로 언급되지 않았습니다. 기본이 아닌 모든 변수는 참조 변수입니다. 예를 들어 obj1 은 MyClass 유형의 변수 이고 tempName 은 String 유형의 변수 이며 여기서 두 유형 모두 기본 유형이 아닙니다. 이 경우 id 는 기본 데이터 유형인 int 유형의 변수입니다 . 따라서 비참조변수이다.

Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 사항

출처: Devgenius 이 튜토리얼을 통해 직렬화 및 역직렬화가 작동하는 방식에 대한 지식을 향상시킬 수 있습니다. Java의 직렬화는 기존 객체를 바이트 스트림으로 변환하는 데 도움이 됩니다. 반대로 역직렬화는 바이트 스트림을 객체로 만듭니다. Java에서 직렬화 및 역직렬화를 사용하면 객체에 대한 정보를 한 JVM에서 다른 JVM으로 전송할 수 있습니다.

#1 직렬화

자세히 알아보기 전에 SerializeUtils.javaPerson.java 클래스를 살펴보겠습니다 . 여기서는 특정 예제를 사용하여 직렬화 및 역직렬화를 수행하는 데 도움이 됩니다.

SerializeUtils.java

package com.techteam.serialization;

import java.io.*;

public class SerializeUtils {
    public static <T> void serialize(T input, String fileName) throws IOException {
        FileOutputStream file = new FileOutputStream(fileName);
        ObjectOutputStream out = new ObjectOutputStream(file);
        out.writeObject(input);
        out.close();
        file.close();
    }

    public static <T> T deserialize(String fileName) throws IOException, ClassNotFoundException {
        FileInputStream file = new FileInputStream(fileName);
        ObjectInputStream in = new ObjectInputStream(file);
        T result = (T) in.readObject();

        return result;
    }

    public static void externalSeialize(Externalizable e, String fileName) throws IOException {
        FileOutputStream file = new FileOutputStream(fileName);
        ObjectOutputStream out = new ObjectOutputStream(file);
        e.writeExternal(out);
        out.close();
        file.close();
    }

    public static void externalDeseialize(Externalizable e, String fileName) throws IOException, ClassNotFoundException {
        FileInputStream file = new FileInputStream (fileName);
        ObjectInputStream in = new ObjectInputStream (file);
        e.readExternal(in);
        in.close();
        file.close();
    }
}

Person.java

package com.techteam.serialization;

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
앞서 언급했듯이 직렬화는 객체를 바이트 스트림으로 변환하는 데 도움이 됩니다. 이는 객체에 대한 모든 정보(메서드, 속성, 데이터 등)도 바이트 스트림으로 변환된다는 의미입니다. 다음은 객체가 직렬화되는 방법의 예입니다.
package com.techteam.serialization;

import java.io.IOException;

public class SerializationMain {

    public static void main(String[] args) throws IOException {
        Person p = new Person();
        p.setId(1);
        p.setName("Tech team members");
        p.setAge(20);

        SerializeUtils.serialize(p, "/person.txt");
    }
}
직렬화 프로세스 후에는 다음 내용이 포함된 파일이 생성됩니다. 커피 브레이크 #180.  Java의 변수: 정의 및 사용 방법  Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 - 2

#2 역직렬화

이전 예제에서 객체를 직렬화하여 바이트 스트림을 생성했다면 이제 역직렬화를 사용하여 객체로 돌아가는 방법을 살펴보겠습니다.
package com.techteam.serialization;

import java.io.IOException;

public class DeserializationMain {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person p = SerializeUtils.deserialize("/person.txt");

        System.out.println("Person data:");
        System.out.println(p.getId());
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}
역직렬화 프로세스 이후의 데이터는 다음과 같습니다. 커피 브레이크 #180.  Java의 변수: 정의 및 사용 방법  Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 - 3

#3 직렬 버전 UID

SerialVersionUID는 직렬화 및 역직렬화 프로세스의 각 버전에 대한 고유 식별 번호를 의미합니다. 이 숫자는 직렬화된 객체와 역직렬화된 객체 모두 호환 가능한 클래스를 사용하는지 확인하는 데 사용됩니다. Person.java 의 경우 serialVersionUID를 2로 늘리고 싶습니다. person.txt 파일을 역직렬화한 후의 출력을 살펴보겠습니다. 커피 브레이크 #180.  Java의 변수: 정의 및 사용 방법  Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 - 4

#4 키워드 일시적

직렬화 및 역직렬화 과정에서 개체에 대한 모든 정보를 직렬화할 필요가 없는 경우가 있습니다. 변수에 대해 임시 프로세스를 사용하면 직렬화되는 개체에서 해당 변수를 무시할 수 있습니다. 아래 예는 이를 보다 명확하게 이해하는 데 도움이 됩니다.
package com.techteam.serialization;

import java.io.IOException;
import java.io.Serializable;

public class PersonWithTransient implements Serializable {

    private static final long serialVersionUID = 1L;

    private int id;
    private String name;
    private transient int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        PersonWithTransient p = new PersonWithTransient();
        p.setId(2);
        p.setName("Tech team members(transient)");
        p.setAge(50);

        SerializeUtils.serialize(p, "/person_transient.txt");

        PersonWithTransient deserializeP = SerializeUtils.deserialize("/person_transient.txt");
        System.out.println("Person without transient data:");
        System.out.println(deserializeP.getId());
        System.out.println(deserializeP.getName());
        System.out.println(deserializeP.getAge());
    }
}
위 코드에서는 age 변수 에 임시 키워드를 사용했습니다 . 이것이 직렬화 및 역직렬화 프로세스 후에 얻은 결과입니다.

#5 외부화 가능한 인터페이스

Java에서는 직렬화 및 역직렬화 프로세스를 사용자 정의하려는 경우 전환 프로세스를 사용하여 직렬화 및 역직렬화 프로세스에 필요하지 않은 변수를 무시할 수 있습니다. 성능을 단순화하고 향상시키는 또 다른 방법은 직렬화 가능 인터페이스 대신 외부화 가능 인터페이스를 사용하는 것입니다 . 예를 살펴보겠습니다:
package com.techteam.serialization;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class PersonExternalizable implements Externalizable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(this.name);
        out.writeInt(this.age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.name = in.readUTF();
        this.age = in.readInt();
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        PersonExternalizable p = new PersonExternalizable();
        p.setId(3);
        p.setName("Tech team members(Externalizable)");
        p.setAge(30);

        SerializeUtils.externalSeialize(p, "/person_externalizable.txt");

        PersonExternalizable deserializeP = new PersonExternalizable();
        SerializeUtils.externalDeseialize(deserializeP, "/person_externalizable.txt");
        System.out.println("Person data:");
        System.out.println(deserializeP.getId());
        System.out.println(deserializeP.getName());
        System.out.println(deserializeP.getAge());
    }
}
보시다시피, 외부화 가능을 사용하면 사용자 정의 논리를 쉽게 작성하고 변수를 무시할 수 있으며 직렬화 가능을 사용하는 것보다 더 나은 성능을 얻을 수 있습니다 . 이제 출력을 살펴보겠습니다. 커피 브레이크 #180.  Java의 변수: 정의 및 사용 방법  Java의 직렬화 및 역직렬화에 대해 알아야 할 5가지 - 5

결론

이 기사를 통해 Java에서 직렬화 및 역직렬화가 어떻게 작동하는지 명확하게 이해했으며 위의 예제가 향후 실제로 도움이 될 수 있기를 바랍니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION