JavaRush /Java Blog /Random-JA /コーヒーブレイク#180。Java の変数: 変数の内容と使用方法。Java のシリアル化と逆シリアル化について知...

コーヒーブレイク#180。Java の変数: 変数の内容と使用方法。Java のシリアル化と逆シリアル化について知っておくべき 5 つのこと

Random-JA グループに公開済み

Java の変数: 変数とは何か、またどのように使用されるか

出典: Hackernoon Java には、プログラム内の宣言場所に応じて 4 つの異なるタイプの変数があります。今日は、各タイプの例と違いを学びます。 コーヒーブレイク#180。 Java の変数: 変数の内容と使用方法。 Java のシリアル化と逆シリアル化について知っておくべき 5 つのこと - 11. インスタンス変数またはインスタンス フィールドは、静的キーワードを使用せずにクラス内で宣言された変数ですが、メソッド、コンストラクター、またはコード ブロックの外で宣言されます。このような変数はクラス内のどこでも宣言できます。これらは、 publicprivateprotected 、または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
  }
}
宣言時にインスタンス フィールドに値が割り当てられていない場合、( intbooleanlongfloat ) などのプリミティブ型の場合はデフォルト値の 0 が割り当てられ、プリミティブ型でない場合はnull が割り当てられます。 ( StringIntegerAnyClass )など。これらは、宣言されたクラスから作成されたオブジェクトのインスタンスに属するため、フィールドまたはインスタンス変数と呼ばれます。
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キーワードを使用して宣言されたフィールドです。これらはクラス内で宣言されますが、メソッド、コンストラクター、またはコード ブロックの外側で宣言されます。また、アクセス修飾子 ( publicprivateprotected、または(キーワードではない) など) の有無にかかわらず、クラス内の任意の位置で宣言することもできます。
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.javaクラスとPerson.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();
    }
}

人物.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変数にtransient キーワードを使用しました。これがシリアル化と逆シリアル化プロセスの後に得られたものです。

#5 外部化可能なインターフェイス

Java では、シリアル化および逆シリアル化のプロセスをカスタマイズする場合、遷移プロセスを使用して、シリアル化および逆シリアル化のプロセスに必要のない変数を無視できます。簡素化してパフォーマンスを向上させるもう 1 つの方法は、 Serializableインターフェイスの代わりにExternalizableインターフェイスを使用することです。例を見てみましょう:
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());
    }
}
ご覧のとおり、Externalizableを使用すると、カスタム ロジックを簡単に記述し、変数を無視して、 Serializable を使用するよりも優れたパフォーマンスを得ることができます。次に、出力を見てみましょう。 コーヒーブレイク#180。 Java の変数: 変数の内容と使用方法。 Java のシリアル化と逆シリアル化について知っておくべき 5 つのこと - 5

結論

この記事を通じて、Java でシリアル化と逆シリアル化がどのように機能するかを明確に理解し、上記の例が将来の実践に役立つことを願っています。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION