Panduan Membuat Objek di Java

1. Ikhtisar

Sederhananya, sebelum kita dapat bekerja dengan sebuah objek di JVM, itu harus diinisialisasi.

Di bagian berikut, kita akan melihat berbagai cara kita dapat menginisialisasi tipe dan objek primitif.

2. Deklarasi vs. Inisialisasi

Mari kita mulai dengan memastikan bahwa kita berada di halaman yang sama.

Deklarasi adalah proses mendefinisikan variabel beserta jenis dan namanya.

Di sini, kami mendeklarasikan variabel id :

int id;

Inisialisasi, di sisi lain, adalah tentang pemberian nilai; sebagai contoh:

id = 1;

Untuk mendemonstrasikan, kita akan membuat kelas User dengan nama dan properti id :

public class User { private String name; private int id; // standard constructor, getters, setters, }

Selanjutnya, kita akan melihat bahwa inisialisasi bekerja secara berbeda bergantung pada jenis bidang yang kita inisialisasi.

3. Objek vs. Primitif

Java menyediakan dua tipe representasi data: tipe primitif dan tipe referensi. Di bagian ini, kita akan membahas perbedaan antara keduanya berkaitan dengan inisialisasi.

Java memiliki delapan tipe data built-in, disebut tipe primitif Java; variabel jenis ini menyimpan nilainya secara langsung.

Jenis referensi menyimpan referensi ke objek (contoh kelas). Tidak seperti tipe primitif yang menyimpan nilainya di memori tempat variabel dialokasikan, referensi tidak menyimpan nilai objek yang dirujuknya.

Sebaliknya, referensi menunjuk ke suatu objek dengan menyimpan alamat memori di mana objek itu berada.

Perhatikan bahwa Java tidak mengizinkan kita menemukan apa alamat memori fisik itu. Sebaliknya, kita hanya dapat menggunakan referensi untuk merujuk ke objek tersebut.

Mari kita lihat contoh yang mendeklarasikan dan menginisialisasi tipe referensi dari kelas User kita :

@Test public void whenIntializedWithNew_thenInstanceIsNotNull() { User user = new User(); assertThat(user).isNotNull(); }

Seperti yang bisa kita lihat di sini, referensi dapat diberikan ke yang baru dengan menggunakan kata kunci baru, yang bertanggung jawab untuk membuat objek Pengguna baru .

Mari lanjutkan dengan mempelajari lebih lanjut tentang pembuatan objek.

5. Membuat Objek

Berbeda dengan primitif, pembuatan objek sedikit lebih kompleks. Ini karena kami tidak hanya menambahkan nilai ke bidang; sebaliknya, kami memicu inisialisasi menggunakan kata kunci baru . Ini, sebagai gantinya, memanggil konstruktor dan menginisialisasi objek dalam memori.

Mari kita bahas konstruktor dan kata kunci baru secara lebih rinci.

Kata kunci baru bertanggung jawab untuk mengalokasikan memori untuk objek baru melalui konstruktor.

Konstruktor biasanya digunakan untuk menginisialisasi variabel instan yang mewakili properti utama dari objek yang dibuat .

Jika kita tidak menyediakan konstruktor secara eksplisit, kompilator akan membuat konstruktor default yang tidak memiliki argumen dan hanya mengalokasikan memori untuk objek tersebut.

Sebuah kelas dapat memiliki banyak konstruktor selama daftar parameternya berbeda ( kelebihan beban ) . Setiap konstruktor yang tidak memanggil konstruktor lain dalam kelas yang sama memiliki panggilan ke konstruktor induknya apakah itu ditulis secara eksplisit atau disisipkan oleh kompilator melalui super () .

Mari tambahkan konstruktor ke kelas User kita :

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

Sekarang kita dapat menggunakan konstruktor kita untuk membuat objek User dengan nilai awal propertinya:

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

6. Ruang Lingkup Variabel

Pada bagian berikut, kita akan melihat berbagai jenis cakupan yang dapat digunakan variabel di Java dan bagaimana hal ini memengaruhi proses inisialisasi.

6.1. Variabel Instance dan Kelas

Variabel instance dan kelas tidak mengharuskan kita untuk menginisialisasi mereka. Segera setelah kami mendeklarasikan variabel-variabel ini, mereka diberi nilai default sebagai berikut:

Sekarang, mari kita coba untuk mendefinisikan beberapa instance dan variabel terkait kelas dan menguji apakah mereka memiliki nilai default atau tidak:

@Test public void whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() { User user = new User(); assertThat(user.getName()).isNull(); assertThat(user.getId() == 0); }

6.2. Variabel Lokal

Variabel lokal harus diinisialisasi sebelum digunakan , karena mereka tidak memiliki nilai default dan compiler tidak mengizinkan kita menggunakan nilai yang tidak diinisialisasi.

Misalnya, kode berikut menghasilkan kesalahan kompiler:

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

7. Kata Kunci Terakhir

Kata kunci terakhir yang diterapkan ke bidang berarti nilai bidang tidak lagi dapat diubah setelah inisialisasi. Dengan cara ini, kita bisa mendefinisikan konstanta di Java.

Let's add a constant to our User class:

private static final int YEAR = 2000;

Constants must be initialized either when they're declared or in a constructor.

8. Initializers in Java

In Java, an initializer is a block of code that has no associated name or data type and is placed outside of any method, constructor, or another block of code.

Java offers two types of initializers, static and instance initializers. Let's see how we can use each of them.

8.1. Instance Initializers

We can use these to initialize instance variables.

To demonstrate, let’s provide a value for a user id using an instance initializer in our User class:

{ id = 0; }

8.2. Static Initialization Block

A static initializer or static block – is a block of code which is used to initialize static fields. In other words, it’s a simple initializer marked with the keyword static:

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

9. Order of Initialization

When writing code that initializes different types of fields, of course, we have to keep an eye on the order of initialization.

In Java, the order for initialization statements is as follows:

  • static variables and static initializers in order
  • instance variables and instance initializers in order
  • constructors

10. Object Life Cycle

Now that we've learned how to declare and initialize objects, let's discover what happens to objects when they're not in use.

Unlike other languages where we have to worry about object destruction, Java takes care of obsolete objects through its garbage collector.

All objects in Java are stored in our program's heap memory. In fact, the heap represents a large pool of unused memory, allocated for our Java application.

On the other hand, the garbage collector is a Java program that takes care of automatic memory management by deleting objects that are no longer reachable.

For a Java object to become unreachable, it has to encounter one of the following situations:

  • The object no longer has any references pointing to it
  • All reference pointing to the object are out of scope

In conclusion, an object is first created from a class, usually using the keyword new. Then the object lives its life and provides us with access to its methods and fields.

Finally, when it's no longer needed, the garbage collector destroys it.

11. Other Methods for Creating Objects

In this section, we’ll take a brief look at 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. Here's an example of creating our User object using reflection:

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

In this case, we're using reflection to find and invoke a constructor of the User class.

The next method, cloning, is a way to create an exact copy of an object. For this, our User class must implement the Cloneable interface:

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

Sekarang kita bisa menggunakan metode clone () untuk membuat objek clonedUser baru yang memiliki nilai properti yang sama dengan objek pengguna :

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

Kita juga bisa menggunakan kelas sun.misc.Unsafe untuk mengalokasikan memori untuk sebuah objek tanpa memanggil konstruktor:

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

12. Kesimpulan

Dalam tutorial ini, kami membahas inisialisasi bidang di Java. Kami menemukan tipe data yang berbeda di Java dan cara menggunakannya. Kami juga mempelajari beberapa cara membuat objek di Java secara mendalam.

Implementasi lengkap dari tutorial ini dapat ditemukan di Github.