Class.isInstance vs Class.isAssignableFrom

1. Einleitung

In diesem kurzen Tutorial werden wir uns den Unterschied zwischen Class.isInstance und Class.isAssignableFrom ansehen . Wir werden lernen, wie man jede Methode benutzt und welche Unterschiede zwischen ihnen bestehen.

2. Setup

Lassen Sie uns eine Schnittstelle und einige Klassen einrichten, die verwendet werden sollen, während wir die Funktionen Class.isInstance und Class.isAssignableFrom untersuchen .

Definieren wir zunächst eine Schnittstelle:

public interface Shape { }

Als nächstes definieren wir eine Klasse, die Shape implementiert :

public class Triangle implements Shape { }

Jetzt erstellen wir eine Klasse, die Triangle erweitert :

public class IsoscelesTriangle extends Triangle { }

3. Class.isInstance

Die isInstance- Methode für die Class- Klasse entspricht dem Operator instanceof . Die isInstance- Methode wurde in Java 1.1 eingeführt, da sie dynamisch verwendet werden kann. Diese Methode gibt true zurück, wenn das Argument nicht null ist und erfolgreich in den Referenztyp umgewandelt werden kann, ohne eine ClassCastException auszulösen .

Schauen wir uns an, wie wir die isInstance- Methode mit der von uns definierten Schnittstelle und den Klassen verwenden können:

@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)); }

Wie wir sehen können, kann die rechte Seite der linken Seite entsprechen oder spezifischer sein . Wenn Sie für die isInstance- Methode null angeben , wird false zurückgegeben .

4. Class.isAssignableFrom

Die Class.isAssignableFrom- Methode gibt true zurück, wenn die Klasse auf der linken Seite der Anweisung mit der angegebenen Superklasse oder Superschnittstelle des angegebenen Class- Parameters identisch ist oder eine solche ist.

Verwenden wir unsere Klassen mit der Methode 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())); }

Wie im isInstance- Beispiel können wir deutlich sehen, dass die rechte Seite entweder gleich oder spezifischer sein muss als die linke Seite. Wir können auch sehen, dass wir unsere Shape- Oberfläche niemals zuweisen können.

5. Die Unterschiede

Nachdem wir einige detaillierte Beispiele aufgeführt haben, gehen wir einige der Unterschiede durch:

  1. Um isInstance verwenden zu können , müssen wir wissen, welche der Klassen sich zur Kompilierungszeit befindet.
  2. Nur isAssignableFrom kann mit Grundelementen verwendet werden. Wir sollten beachten, dass die Methode bei Verwendung von Grundelementen nur dann true zurückgibt, wenn das Class- Objekt und der Class- Parameter genau dieselbe Klasse sind .
  3. Die Methode isAssignableFrom löst eine NullPointerException aus, wenn das auf beiden Seiten des Ausdrucks verwendete Objekt null ist . Wenn Sie der isInstance- Methode eine Null geben , wird false zurückgegeben .
  4. Wir sollten uns isInstance als Antwort auf die Frage vorstellen, ob das bereitgestellte Objekt der Typ ist, mit dem wir es vergleichen (entweder direkt oder über eine Schnittstelle oder Vererbung). Wir können uns isAssignableFrom als Antwort auf die Frage vorstellen, ob wir die Parameterklasse als Objektklasse definieren können. Mit anderen Worten, wird Triangle triangle = new IsoscelesTriange () kompiliert?

6. Fazit

In diesem kurzen Tutorial haben wir uns sowohl die Methoden Class.isInstance als auch Class.isAssignableFrom angesehen und ihre Verwendung und ihre Unterschiede untersucht.

Wie immer finden Sie den Beispielcode für dieses Tutorial auf GitHub.