Perbedaan Antara a.getClass () dan A.class di Java

1. Ikhtisar

Di Java, kelas java.lang.Class adalah titik masuk dari semua operasi refleksi . Setelah kita memiliki objek java.lang.Class , kita kemudian dapat memanggil metode terkait untuk mendapatkan objek kelas refleksi.

Dalam tutorial ini, kita akan membahas perbedaan antara dua cara berbeda untuk mendapatkan objek java.lang.Class :

  • Memanggil Object.getClass () metode
  • Menggunakan sintaks .class

2. Pengantar Singkat tentang Dua Pendekatan

Metode Object.getClass () adalah metode turunan dari kelas Object . Jika kita memiliki sebuah objek, kita bisa memanggil object.getClass () untuk mendapatkan objek Kelas dari tipenya.

Demikian pula, kita bisa menggunakan sintaks ClassName.class untuk mendapatkan objek Kelas dari tipe tersebut. Sebuah contoh dapat menjelaskannya dengan jelas:

@Test public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult() { String str = "I am an object of the String class"; Class fromStrObject = str.getClass(); Class clazz = String.class; assertSame(fromStrObject, clazz); } 

Dalam metode pengujian di atas, kami mencoba untuk mendapatkan objek Kelas dari kelas String menggunakan dua cara yang telah kami sebutkan. Terakhir, metode pernyataan memberi tahu kita bahwa dua objek Kelas adalah instance yang sama.

Namun, ada perbedaan antara kedua pendekatan tersebut. Mari kita lihat lebih dekat.

3. Jenis Runtime vs. Jenis Statis

Mari kita tinjau contoh sebelumnya dengan cepat. Ketika kita memanggil metode str.getClass () , kita mendapatkan tipe runtime dari objek str . Di sisi lain, String.class mengevaluasi kelas String secara statis . Dalam contoh ini, tipe runtime dari str dan String.class adalah sama.

Namun, mereka bisa berbeda jika warisan kelas bergabung dengan partai. Mari kita lihat dua kelas sederhana:

public class Animal { protected int numberOfEyes; } public class Monkey extends Animal { // monkey stuff }

Sekarang mari kita membuat instance objek dari kelas Animal dan melakukan tes lain:

@Test public void givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult() { Animal animal = new Monkey(); Class runtimeType = animal.getClass(); Class staticType = Animal.class; assertSame(staticType, runtimeType); } 

Jika kami menjalankan pengujian di atas, kami akan mendapatkan pengujian yang gagal:

java.lang.AssertionError: .... Expected :class com.baeldung.getclassobject.Animal Actual :class com.baeldung.getclassobject.Monkey

Dalam metode pengujian, meskipun kita membuat instance objek hewan dengan Animal animal = new Monkey (); bukannya Monyet hewan = Monyet baru (); , jenis waktu proses dari objek hewan masih Monkey. Ini karena objek hewan adalah turunan dari Monkey pada waktu proses.

Namun, saat kita mendapatkan tipe statis dari kelas Hewan , jenisnya selalu Hewan .

4. Penanganan Tipe Primitif

Saat kami menulis kode Java, kami cukup sering menggunakan tipe primitif. Mari kita coba mendapatkan objek Kelas dari tipe primitif menggunakan pendekatan object.getClass () :

int number = 7; Class numberClass = number.getClass();

Jika kita mencoba mengkompilasi kode di atas, kita akan mendapatkan error kompilasi:

Error: java: int cannot be dereferenced

Kompilator tidak dapat mendereferensi variabel bilangan karena ini adalah variabel primitif. Oleh karena itu, metode object.getClass () tidak dapat membantu kita mendapatkan objek Kelas dari tipe primitif.

Mari kita lihat apakah kita bisa mendapatkan tipe primitif menggunakan sintaks .class :

@Test public void givenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks() { Class intType = int.class; assertNotNull(intType); assertEquals("int", intType.getName()); assertTrue(intType.isPrimitive()); } 

Jadi, kita bisa mendapatkan objek Class dari tipe primitif int melalui int.class . Di Java versi 9 dan yang lebih baru, objek Kelas dengan tipe primitif termasuk dalam modul java.base .

Sebagai menunjukkan tes, yang .class sintaks adalah cara mudah untuk mendapatkan Kelas objek dari tipe primitif.

5. Mendapatkan Kelas Tanpa Instance

Kita telah mempelajari bahwa metode object.getClass () bisa memberi kita objek Class dari tipe runtime-nya.

Sekarang, mari pertimbangkan kasus di mana kita ingin mendapatkan objek Kelas dari suatu tipe, tetapi kita tidak bisa mendapatkan turunan dari tipe target karena itu kelas abstrak , antarmuka, atau beberapa kelas tidak mengizinkan instantiasi:

public abstract class SomeAbstractClass { // ... } interface SomeInterface { // some methods ... } public class SomeUtils { private SomeUtils() { throw new RuntimeException("This Util class is not allowed to be instantiated!"); } // some public static methods... } 

Dalam kasus ini, kita tidak bisa mendapatkan objek Kelas dari tipe tersebut menggunakan metode object.getClass () , tetapi kita masih bisa menggunakan sintaks .class untuk mendapatkan objek Kelasnya :

@Test public void givenTypeCannotInstantiate_whenGetTypeStatically_thenGetTypesSuccefully() { Class interfaceType = SomeInterface.class; Class abstractClassType = SomeAbstractClass.class; Class utilClassType = SomeUtils.class; assertNotNull(interfaceType); assertTrue(interfaceType.isInterface()); assertEquals("SomeInterface", interfaceType.getSimpleName()); assertNotNull(abstractClassType); assertEquals("SomeAbstractClass", abstractClassType.getSimpleName()); assertNotNull(utilClassType); assertEquals("SomeUtils", utilClassType.getSimpleName()); } 

Seperti yang ditunjukkan pengujian di atas, sintaks .class dapat memperoleh objek Kelas untuk tipe tersebut.

Oleh karena itu, ketika kita ingin memiliki objek Kelas , tetapi kita tidak bisa mendapatkan turunan dari tipe, sintaks .class adalah cara yang tepat.

6. Kesimpulan

Dalam artikel ini, kita mempelajari dua cara berbeda untuk mendapatkan objek Class dari suatu tipe: metode object.getClass () dan sintaks .class .

Nanti, kami membahas perbedaan antara kedua pendekatan tersebut. Tabel berikut dapat memberi kita gambaran yang jelas:

object.getClass () SomeClass.class
Objek kelas Jenis objek waktu proses Jenis statis SomeClass
Tipe primitif - Bekerja dengan mudah
Antarmuka, kelas abstrak, atau kelas yang tidak bisa dibuat instance-nya - Bekerja dengan mudah

Seperti biasa, kode sumber lengkap artikel tersedia di GitHub.