Javaでオブジェクトを作成するためのガイド

Javaでオブジェクトを作成するためのガイド

1. 概要

簡単に言えば、JVMでオブジェクトを操作する前に、初期化する必要があります。

次のセクションでは、プリミティブ型とオブジェクトを初期化するさまざまな方法を見ていきます。

2. 宣言対 初期化

同じページにいることを確認することから始めましょう。

Declaration is the process of defining the variableとそのタイプおよび名前。

ここでは、id変数を宣言しています。

int id;

一方、初期化とは、値を割り当てることです。例えば:

id = 1;

実例を示すために、nameプロパティとidプロパティを持つUserクラスを作成します。

public class User implements {
    private String name;
    private int id;

    // standard constructor, getters, setters,
}

次に、初期化するフィールドのタイプに応じて、初期化の動作が異なることがわかります。

3. オブジェクトと プリミティブ

Javaは、プリミティブ型と参照型の2種類のデータ表現を提供します。 このセクションでは、初期化に関する2つの違いについて説明します。

Javaには、Javaプリミティブ型と呼ばれる8つの組み込みデータ型があります。このタイプの変数は、値を直接保持します。

参照型は、オブジェクト(クラスのインスタンス)への参照を保持します。 Unlike primitive types that hold their values in the memory where the variable is allocated, references don’t hold the value of the object they refer to.

代わりに、a reference points to an object by storing the memory address where the object is located.

Javaでは、物理メモリアドレスが何であるかを検出できないことに注意してください。 むしろ、参照を使用してオブジェクトを参照することしかできません。

Userクラスから参照型を宣言して初期化する例を見てみましょう。

@Test
public void whenIntializedWithNew_thenInstanceIsNotNull() {
    User user = new User();

    assertThat(user).isNotNull();
}

ここでわかるように、新しいUserオブジェクトの作成を担当するキーワードnew,を使用して、参照を新しいものに割り当てることができます。

オブジェクトの作成についてさらに学習を続けましょう。

5. オブジェクトを作成する

プリミティブとは異なり、オブジェクトの作成はもう少し複雑です。 これは、フィールドに値を追加するだけではないためです。代わりに、newキーワードを使用して初期化をトリガーします。 これは、代わりに、コンストラクターを呼び出し、メモリ内のオブジェクトを初期化します。

コンストラクターとnewキーワードについてさらに詳しく説明しましょう。

newキーワードはresponsible for allocating memory for the new object through a constructor.です

A constructor is typically used to initialize instance variables representing the main properties of the created object

コンストラクタを明示的に指定しない場合、コンパイラは引数を持たず、オブジェクトにメモリを割り当てるだけのデフォルトのコンストラクタを作成します。

A class can have many constructors as long as their parameters lists are different (overload)。 同じクラス内の別のコンストラクターを呼び出さないすべてのコンストラクターは、明示的に記述されたか、super()を介してコンパイラーによって挿入されたかに関係なく、親コンストラクターを呼び出します。

Userクラスにコンストラクターを追加しましょう。

public User(String name, int id) {
    this.name = name;
    this.id = id;
}

これで、コンストラクターを使用して、プロパティの初期値を持つUserオブジェクトを作成できます。

User user = new User("Alice", 1);

6. 可変スコープ

次のセクションでは、Javaの変数が存在できるさまざまなタイプのスコープと、これが初期化プロセスにどのように影響するかを見ていきます。

6.1. インスタンスとクラス変数

Instance and class variables don’t require us to initialize them.これらの変数を宣言するとすぐに、次のようなデフォルト値が与えられます。

image

それでは、いくつかのインスタンスとクラス関連の変数を定義して、それらにデフォルト値があるかどうかをテストしてみましょう。

@Test
public void whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() {
    User user = new User();

    assertThat(user.getName()).isNull();
    assertThat(user.getId() == 0);
}

6.2. ローカル変数

Local variables must be initialized before useにはデフォルト値がなく、コンパイラは初期化されていない値を使用できないためです。

たとえば、次のコードはコンパイラエラーを生成します。

public void print(){
    int i;
    System.out.println(i);
}

7. Finalキーワード

フィールドに適用されるfinalキーワードは、初期化後にフィールドの値を変更できなくなることを意味します。 このようにして、Javaで定数を定義できます。

Userクラスに定数を追加しましょう:

private static final int YEAR = 2000;

定数は、宣言時またはコンストラクターで初期化する必要があります。

8. Javaのイニシャライザー

Javaでは、initializer is a block of code that has no associated name or data typeは、メソッド、コンストラクター、またはコードの別のブロックの外部に配置されます。

Javaには、静的とインスタンス初期化の2種類の初期化子があります。 それぞれの使い方を見てみましょう。

8.1. インスタンス初期化子

これらを使用して、インスタンス変数を初期化できます。

実例を示すために、Userクラスのインスタンス初期化子を使用してユーザーidに値を指定しましょう。

{
    id = 0;
}

8.2. 静的初期化ブロック

静的初期化子または静的ブロック–staticフィールドを初期化するために使用されるコードのブロックです。 つまり、キーワードstatic:でマークされた単純な初期化子です。

private static String forum;
static {
    forum = "Java";
}

9. 初期化の順序

もちろん、さまざまなタイプのフィールドを初期化するコードを作成するときは、初期化の順序に注意する必要があります。

Javaでは、初期化ステートメントの順序は次のとおりです。

  • 順番に静的変数と静的初期化子

  • インスタンス変数とインスタンス初期化子の順序

  • コンストラクタ

10. オブジェクトのライフサイクル

オブジェクトを宣言して初期化する方法を学習したので、オブジェクトが使用されていないときにオブジェクトがどうなるかを見てみましょう。

オブジェクトの破壊を心配しなければならない他の言語とは異なり、Javaはガベージコレクターを通じて古いオブジェクトを処理します。

All objects in Java are stored in our program’s heap memory。 実際、ヒープは、Javaアプリケーションに割り当てられた未使用メモリの大きなプールを表しています。

一方、garbage collector is a Java program that takes care of automatic memory managementは、到達できなくなったオブジェクトを削除します。

Javaオブジェクトが到達不能になるには、次のいずれかの状況に遭遇する必要があります。

  • オブジェクトには、それを指す参照がなくなりました

  • オブジェクトを指すすべての参照が範囲外です

結論として、オブジェクトは最初にクラスから作成され、通常はキーワードnew.を使用します。その後、オブジェクトは存続し、メソッドとフィールドへのアクセスを提供します。

最後に、不要になると、ガベージコレクターはそれを破棄します。

11. オブジェクトを作成するための他のメソッド

このセクションでは、methods other than new keyword to create objects and how to apply them, specifically reflection, cloning, and serializationについて簡単に説明します。

Reflection is a mechanism we can use to inspect classes, fields, and methods at run-time.リフレクションを使用してUserオブジェクトを作成する例を次に示します。

@Test
public void whenInitializedWithReflection_thenInstanceIsNotNull()
  throws Exception {
    User user = User.class.getConstructor(String.class, int.class)
      .newInstance("Alice", 2);

    assertThat(user).isNotNull();
}

この場合、リフレクションを使用して、Userクラスのコンストラクターを見つけて呼び出しています。

次のメソッド、cloning, is a way to create an exact copy of an object.このために、UserクラスはCloneableインターフェースを実装する必要があります。

public class User implements Cloneable { //... }

これで、clone()メソッドを使用して、userオブジェクトと同じプロパティ値を持つ新しいclonedUserオブジェクトを作成できます。

@Test
public void whenCopiedWithClone_thenExactMatchIsCreated()
  throws CloneNotSupportedException {
    User user = new User("Alice", 3);
    User clonedUser = (User) user.clone();

    assertThat(clonedUser).isEqualTo(user);
}

sun.misc.Unsafeクラスを使用して、コンストラクターを呼び出さずにオブジェクトにメモリを割り当てることもできます。

User u = (User) unsafeInstance.allocateInstance(User.class);

12. 結論

このチュートリアルでは、Javaのフィールドの初期化について説明しました。 Javaでさまざまなデータ型とその使用方法を発見しました。 また、Javaでオブジェクトを作成するいくつかの方法についても詳しく調べました。

このチュートリアルの完全な実装はover on Githubにあります。