Class.isInstance vs Class.isAssignableFrom

1. Pengenalan

Dalam tutorial ringkas ini, kita akan melihat perbezaan antara Class.isInstance dan Class.isAssignableFrom . Kami akan belajar bagaimana menggunakan setiap kaedah dan apa perbezaan di antara mereka.

2. Persediaan

Mari kita set up antara muka dan beberapa kelas untuk digunakan semasa kita meneroka Class.isInstance dan Class.isAssignableFrom fungsi.

Pertama, mari kita tentukan antara muka:

public interface Shape { }

Seterusnya, mari kita tentukan kelas yang menerapkan Shape :

public class Triangle implements Shape { }

Sekarang, kami akan membuat kelas yang memanjangkan Segitiga :

public class IsoscelesTriangle extends Triangle { }

3. Class.isInstance

The isInstance kaedah di Kelas kelas adalah bersamaan dengan instanceof operator. The isInstance kaedah telah diperkenalkan di Jawa 1.1 kerana ia boleh digunakan secara dinamik. Kaedah ini akan kembali benar jika argumen tidak kosong dan berjaya dihantar ke jenis rujukan tanpa menaikkan ClassCastException .

Mari lihat bagaimana kita dapat menggunakan kaedah isInstance dengan antara muka 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 dapat kita lihat, sebelah kanan boleh sama atau lebih spesifik daripada sebelah kiri . Memberikan null kepada kaedah isInstance kembali salah .

4. Class.isAssignableDaripada

The Class.isAssignableFrom kaedah akan kembali benar jika Kelas di sebelah kiri tangan kenyataan itu adalah sama dengan atau merupakan superclass atau superinterface daripada disediakan Kelas parameter.

Mari gunakan kelas kami dengan kaedah 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 contoh isInstance , kita dapat melihat dengan jelas bahawa sebelah kanan mestilah sama atau lebih spesifik daripada sebelah kiri. Kami juga dapat melihat bahawa kami tidak pernah dapat menetapkan antara muka Shape kami .

5. Perbezaannya

Sekarang setelah kami memberikan beberapa contoh terperinci, mari kita bahas beberapa perbezaan:

  1. Untuk menggunakan isInstance , kita perlu mengetahui apa salah satu kelas pada waktu penyusunan.
  2. Hanya isAssignableFrom boleh digunakan dengan primitif. Kita harus sedar bahawa jika kita menggunakan primitif, kaedah ini hanya akan kembali benar jika Kelas objek dan Kelas parameter adalah sama Kelas .
  3. The isAssignableFrom kaedah akan membuang NullPointerException jika objek yang digunakan pada kedua-dua belah ungkapan adalah null . Sekiranya anda memberikan nol kepada kaedah isInstance , ia akan menjadi palsu .
  4. Kita harus memikirkan isInstance sebagai menjawab pertanyaan apakah objek yang disediakan adalah jenis yang kita bandingkan dengannya (baik secara langsung atau melalui antara muka atau warisan). Kita boleh menganggap isAssignableFrom sebagai menjawab persoalan sama ada kita dapat menentukan kelas parameter sebagai kelas objek. Dengan kata lain, adakah Segitiga segitiga = IsoscelesTriange baru () disusun?

6. Kesimpulannya

Dalam tutorial pendek ini, kita melihat kedua-dua Class.isInstance dan Class.isAssignableFrom kaedah dan diterokai penggunaannya dan bagaimana mereka berbeza.

Seperti biasa, contoh kod untuk tutorial ini boleh didapati di GitHub.