Class.isInstance vs Class.isAssignableFrom

1. Perkenalan

Dalam tutorial singkat ini, kita akan melihat perbedaan antara Class.isInstance dan Class.isAssignableFrom . Kita akan belajar bagaimana menggunakan setiap metode dan apa perbedaannya.

2. Penyiapan

Set Mari sebuah antarmuka dan beberapa kelas untuk menggunakan sementara kami menjelajahi Class.isInstance dan Class.isAssignableFrom fungsi.

Pertama, mari kita tentukan antarmuka:

public interface Shape { }

Selanjutnya, mari kita tentukan kelas yang mengimplementasikan Shape :

public class Triangle implements Shape { }

Sekarang, kita akan membuat kelas yang memperluas Segitiga :

public class IsoscelesTriangle extends Triangle { }

3. Class.isInstance

The isinstance metode pada kelas kelas setara dengan instanceof operator. The isinstance metode diperkenalkan di Jawa 1.1 karena dapat digunakan secara dinamis. Metode ini akan mengembalikan nilai true jika argumennya bukan null dan bisa berhasil dilemparkan ke tipe referensi tanpa memunculkan ClassCastException .

Mari kita lihat bagaimana kita dapat menggunakan metode isInstance dengan antarmuka dan kelas yang kita tentukan:

@Test public void whenUsingIsInstanceProperly_desiredResultsHappen() { Shape shape = new Triangle(); Triangle triangle = new Triangle(); IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle(); Triangle isoscelesTriangle2 = new IsoscelesTriangle(); Shape nonspecificShape = null; assertTrue(Shape.class.isInstance(shape)); assertTrue(Shape.class.isInstance(triangle)); assertTrue(Shape.class.isInstance(isoscelesTriangle)); assertTrue(Shape.class.isInstance(isoscelesTriangle2)); assertFalse(Shape.class.isInstance(nonspecificShape)); assertTrue(Triangle.class.isInstance(shape)); assertTrue(Triangle.class.isInstance(triangle)); assertTrue(Triangle.class.isInstance(isoscelesTriangle)); assertTrue(Triangle.class.isInstance(isoscelesTriangle2)); assertFalse(IsoscelesTriangle.class.isInstance(shape)); assertFalse(IsoscelesTriangle.class.isInstance(triangle)); assertTrue(IsoscelesTriangle.class.isInstance(isoscelesTriangle)); assertTrue(IsoscelesTriangle.class.isInstance(isoscelesTriangle2)); }

Seperti yang bisa kita lihat, sisi kanan bisa setara atau lebih spesifik daripada sisi kiri . Memberikan null ke metode isInstance akan menghasilkan nilai false .

4. Class.isAssignableFrom

The Class.isAssignableFrom metode akan kembali benar jika Kelas di sisi kiri dari pernyataan itu adalah sama dengan atau superclass atau superinterface dari yang disediakan Kelas parameter.

Mari gunakan kelas kita dengan metode isAssignableFrom :

@Test public void whenUsingIsAssignableFromProperly_desiredResultsHappen() { Shape shape = new Triangle(); Triangle triangle = new Triangle(); IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle(); Triangle isoscelesTriangle2 = new IsoscelesTriangle(); assertFalse(shape.getClass().isAssignableFrom(Shape.class)); assertTrue(shape.getClass().isAssignableFrom(shape.getClass())); assertTrue(shape.getClass().isAssignableFrom(triangle.getClass())); assertTrue(shape.getClass().isAssignableFrom(isoscelesTriangle.getClass())); assertTrue(shape.getClass().isAssignableFrom(isoscelesTriangle2.getClass())); assertFalse(triangle.getClass().isAssignableFrom(Shape.class)); assertTrue(triangle.getClass().isAssignableFrom(shape.getClass())); assertTrue(triangle.getClass().isAssignableFrom(triangle.getClass())); assertTrue(triangle.getClass().isAssignableFrom(isoscelesTriangle.getClass())); assertTrue(triangle.getClass().isAssignableFrom(isoscelesTriangle2.getClass())); assertFalse(isoscelesTriangle.getClass().isAssignableFrom(Shape.class)); assertFalse(isoscelesTriangle.getClass().isAssignableFrom(shape.getClass())); assertFalse(isoscelesTriangle.getClass().isAssignableFrom(triangle.getClass())); assertTrue(isoscelesTriangle.getClass().isAssignableFrom(isoscelesTriangle.getClass())); assertTrue(isoscelesTriangle.getClass().isAssignableFrom(isoscelesTriangle2.getClass())); assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(Shape.class)); assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(shape.getClass())); assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(triangle.getClass())); assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle.getClass())); assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle2.getClass())); }

Seperti pada contoh isInstance , kita dapat dengan jelas melihat bahwa sisi kanan harus sama atau lebih spesifik daripada sisi kiri. Kami juga dapat melihat bahwa kami tidak pernah dapat menetapkan antarmuka Bentuk kami .

5. Perbedaan

Sekarang setelah kami memberikan beberapa contoh mendetail, mari kita bahas beberapa perbedaannya:

  1. Untuk menggunakan isInstance , kita perlu mengetahui salah satu kelas pada waktu kompilasi.
  2. Hanya isAssignableFrom yang dapat digunakan dengan primitif. Kami harus dicatat bahwa jika kita menggunakan primitif, metode hanya akan kembali benar jika Kelas objek dan kelas parameter yang persis sama Kelas .
  3. The isAssignableFrom metode akan melempar NullPointerException jika objek yang digunakan di kedua sisi ekspresi adalah nol . Jika Anda memberikan null ke metode isInstance , itu akan mengembalikan false .
  4. Kita harus memikirkan isInstance sebagai menjawab pertanyaan apakah objek yang diberikan adalah tipe yang kita bandingkan (baik secara langsung atau melalui antarmuka atau warisan). Kita dapat menganggap isAssignableFrom sebagai menjawab pertanyaan apakah kita dapat mendefinisikan kelas parameter sebagai kelas objek. Dengan kata lain, akankah segitiga segitiga = new IsoscelesTriange () dikompilasi?

6. Kesimpulan

Dalam tutorial singkat ini, kita melihat kedua metode Class.isInstance dan Class.isAssignableFrom serta menjelajahi penggunaannya dan perbedaannya.

Seperti biasa, kode contoh untuk tutorial ini dapat ditemukan di GitHub.