Java の変数: 変数とは何か、またどのように使用されるか
出典:
Hackernoon Java には、プログラム内の宣言場所に応じて 4 つの異なるタイプの変数があります。今日は、各タイプの例と違いを学びます。 1. インスタンス変数または
インスタンス フィールドは、静的キーワードを使用せずにクラス内で宣言された変数ですが、メソッド、コンストラクター、またはコード ブロックの外で宣言されます。このような変数はクラス内のどこでも宣言できます。
これらは、 public、
private、
protected 、または
default (キーワードではない) などのアクセス修飾子を付けても付けなくても宣言できます。
public class MyClass {
private String instanceField1;
public MyClass(){}
public int anotherInstanceField2;
public void setInstanceField(String parameterVariable) {...}
boolean instanceField3;
public static void main(String[] args) {
System.out.println("field 1 value: " + instanceField1);
System.out.println("field 2 value: " + anotherInstanceField2);
System.out.println("field 3 value: " + instanceField3);
}
}
宣言時にインスタンス フィールドに値が割り当てられていない場合、( 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();
obj1.anotherInstanceField2 = 11;
obj2.anotherInstanceField2 = 33;
System.out.println(obj1.anotherInstanceField2);
System.out.println(obj2.anotherInstanceField2);
}
}
したがって、上記のスニペットに見られるように、各インスタンス フィールドはそのオブジェクトに固有です。その中で、
obj1と
obj2には、それぞれのインスタンス フィールドに割り当てられた一意の値があります。
2. クラス フィールドまたは
静的フィールドは、 staticキーワードを使用して宣言されたフィールドです。これらはクラス内で宣言されますが、メソッド、コンストラクター、またはコード ブロックの外側で宣言されます。
また、アクセス修飾子 ( public、
private、
protected、または(キーワードではない)
など) の有無にかかわらず、クラス内の任意の位置で宣言することもできます。
public class MyClass {
public static String staticField;
public MyClass(){}
}
class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.staticField
MyClass.staticField = "I am a static field";
System.out.println(MyClass.staticField);
}
}
静的フィールドにはクラスを通じてのみアクセスでき、上記のコード スニペットに示すようにオブジェクトからはアクセスできません。3.
パラメータまたは
引数変数は、メソッド シグネチャの左中括弧と右中括弧の間のメソッド構造内で宣言された変数です。これらは、値またはオブジェクトをメソッドに渡すために使用されます。
public class MyClass {
public String instanceField;
public MyClass(){}
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);
}
}
4.
ローカル変数は、メソッドまたはコードのブロック内で宣言された変数です。たとえば、
ifステートメント、
for ループ、
while ループ、 switchステートメントのブロックなどのブロック内で宣言されます。
public Main {
public static void main(String[] args) {
MyClass obj1 = new MyClass();
int id = 1;
if (id > 1) {
String tempName = "Austin";
}
}
}
このコードでは、いくつかの変数で参照が使用されていますが、ローカル変数
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");
}
}
シリアル化プロセスが完了すると、次の内容のファイルが作成されます。
#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());
}
}
逆シリアル化プロセス後のデータは次のとおりです。
#3 シリアルバージョンUID
SerialVersionUID は、シリアル化および逆シリアル化プロセスの各バージョンの一意の識別番号を意味します。この番号は、シリアル化されたオブジェクトと逆シリアル化されたオブジェクトの両方が互換性のあるクラスを使用することを保証するために使用されます。Person.javaの場合
、 serialVersionUID を 2 に増やしたいと思います。person.txt ファイルを逆シリアル化した後の出力を見てみましょう。
#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 を使用するよりも優れたパフォーマンスを得ることができます。次に、出力を見てみましょう。
結論
この記事を通じて、Java でシリアル化と逆シリアル化がどのように機能するかを明確に理解し、上記の例が将来の実践に役立つことを願っています。
GO TO FULL VERSION