Der Unterschied zwischen a.getClass () und A.class in Java

1. Übersicht

In Java ist die Klasse java.lang.Class der Einstiegspunkt aller Reflexionsoperationen . Sobald wir ein Objekt von java.lang.Class haben , können wir die entsprechenden Methoden aufrufen, um die Objekte der Reflexionsklassen abzurufen.

In diesem Tutorial werden die Unterschiede zwischen zwei verschiedenen Methoden zum Abrufen eines Objekts von java.lang.Class erläutert :

  • Aufruf der Object.getClass () -Methode
  • Verwenden der .class- Syntax

2. Kurze Einführung in die beiden Ansätze

Die Object.getClass () -Methode ist eine Instanzmethode der Object- Klasse. Wenn wir ein Objekt haben, können wir object.getClass () aufrufen , um das Class- Objekt seines Typs abzurufen .

Ebenso können wir die ClassName.class- Syntax verwenden, um das Class- Objekt des Typs abzurufen . Ein Beispiel kann es klar erklären:

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

In der obigen Testmethode versuchen wir, das Class- Objekt der String- Klasse auf die beiden genannten Arten zu erhalten. Schließlich sagt uns die Assertionsmethode, dass die beiden Klassenobjekte dieselbe Instanz sind.

Es gibt jedoch Unterschiede zwischen den beiden Ansätzen. Schauen wir sie uns genauer an.

3. Der Laufzeittyp im Vergleich zum statischen Typ

Lassen Sie uns das vorherige Beispiel schnell überprüfen. Wenn wir die Methode str.getClass () aufrufen , erhalten wir den Laufzeit-Typ des str- Objekts. Andererseits wertet String.class die String- Klasse statisch aus . In diesem Beispiel sind der Laufzeittyp von str und die String.class identisch.

Sie können jedoch unterschiedlich sein, wenn die Klassenvererbung der Partei beitritt. Sehen wir uns zwei einfache Klassen an:

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

Lassen Sie uns nun ein Objekt der Animal- Klasse instanziieren und einen weiteren Test durchführen:

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

Wenn wir den obigen Test ausführen, wird ein Testfehler angezeigt:

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

In dem Testverfahren, auch wenn wir das instanziiert Tier Objekt von Tiere Tiere = new Affe (); anstelle von Affentier = neuer Affe (); Der Laufzeittyp des, Tier Objekts ist immer noch Affe. Dies liegt daran , das Tier Objekt eine Instanz ist Affe zur Laufzeit.

Wenn wir jedoch den statischen Typ der Animal- Klasse erhalten, ist der Typ immer Animal .

4. Umgang mit primitiven Typen

Wenn wir Java-Code schreiben, verwenden wir ziemlich oft primitive Typen. Lassen Sie uns versuchen , eine bekommen Klasse Objekt eines primitiven Art der Verwendung object.getClass () Ansatz:

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

Wenn wir versuchen, den obigen Code zu kompilieren, wird ein Kompilierungsfehler angezeigt:

Error: java: int cannot be dereferenced

Der Compiler kann nicht die dereferenzieren Nummer variabel , da es sich um eine primitive Variable ist. Daher kann uns die object.getClass () -Methode nicht helfen, das Class- Objekt eines primitiven Typs abzurufen .

Mal sehen, ob wir den primitiven Typ mit der .class- Syntax erhalten können:

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

So können wir das Class- Objekt vom primitiven Typ int über int.class erhalten . In Java Version 9 und höher gehört ein Class- Objekt vom primitiven Typ zum Modul java.base .

Wie der Test zeigt, ist die .class- Syntax eine einfache Möglichkeit, das Class- Objekt eines primitiven Typs abzurufen.

5. Die Klasse ohne Instanz bekommen

Wir haben gelernt, dass die object.getClass () -Methode uns das Class- Objekt seines Laufzeittyps geben kann.

Betrachten wir nun den Fall, in dem wir ein Class- Objekt eines Typs erhalten möchten , aber keine Instanz des Zieltyps erhalten können, da es sich um eine abstrakte Klasse, eine Schnittstelle oder eine Klasse handelt, die keine Instanziierung zulässt:

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... } 

In diesen Fällen können wir die nicht bekommen Class - Objekte dieser Typen mit der object.getClass () Methode, aber wir können immer noch die Verwendung .class- Syntax der erhalten Class - Objekte von ihnen:

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

Wie der obige Test zeigt, kann die .class- Syntax die Class- Objekte für diese Typen abrufen .

Deshalb , wenn wir das haben wollen Class - Objekt, aber wir können keine Instanz des Typs erhalten, die .class Syntax ist der Weg zu gehen.

6. Fazit

In diesem Artikel haben wir zwei verschiedene Methoden zum Abrufen des Class- Objekts eines Typs kennengelernt : die object.getClass () -Methode und die .class- Syntax.

Später haben wir den Unterschied zwischen den beiden Ansätzen diskutiert. Die folgende Tabelle kann uns einen klaren Überblick geben:

object.getClass () SomeClass.class
Klassenobjekte Der Laufzeittyp des Objekts Der statische Typ von SomeClass
Primitive Typen - - Funktioniert unkompliziert
Schnittstellen, abstrakte Klassen oder Klassen, die nicht instanziiert werden können - - Funktioniert unkompliziert

Wie immer ist der vollständige Quellcode des Artikels auf GitHub verfügbar.