HOWTO · Java
Laufzeitklasse eines Objekts in Java prüfen
Mit getClass(), getSimpleName() und getTypeName() die Laufzeitklasse eines Java-Objekts ermitteln – nicht den deklarierten Variablentyp.
Auf dieser Seite
Mit getClass() lässt sich die Laufzeitklasse eines nicht-null Objekts ermitteln – niemals der deklarierte Typ der Variablen. getSimpleName() liefert den Klassennamen ohne Paketangabe, getName() den Namen samt Paket und getTypeName() einen Typnamen wie java.lang.String. Verwende instanceof, wenn du nur eine Ja/Nein-Prüfung statt eines Namens brauchst.
Mit getClass().getSimpleName() den Typ einer Variablen in Java prüfen
Rufe getClass() für ein Objekt auf, um dessen Class<?>-Objekt zu erhalten. Mit getSimpleName() erhältst du anschließend den Klassennamen ohne Paketangabe. Das Ergebnis entspricht der Laufzeitklasse des Objekts, auch wenn die Variable als Object deklariert ist.
Führe dieses Beispiel aus:
public class RuntimeSimpleNames {
public static void main(String[] args) {
Object value = "Hello, Java!";
String[] names = {"Ada", "Lin"};
int count = 3;
Object boxedCount = count;
System.out.println(value.getClass().getSimpleName());
System.out.println(names.getClass().getSimpleName());
System.out.println(boxedCount.getClass().getSimpleName());
}
}
Ausgabe:
String
String[]
Integer
Arrays sind Objekte, daher funktioniert getClass() auch mit ihnen; ein Wert vom Typ String[] hat den einfachen Klassennamen String[]. Für einen primitiven Wert wie int gibt es keine getClass()-Methode – der Abschnitt zu primitiven Werten weiter unten erklärt, warum das so ist und was das Verpacken (Boxing) stattdessen meldet.
Mit getClass().getName() den Typ einer Variablen in Java prüfen
getName() gibt den voll qualifizierten Namen der Laufzeitklasse samt Paket zurück – verwende diese Methode, wenn das Paket nötig ist, um gleichnamige Klassen zu unterscheiden. Bei Arrays liefert sie jedoch den JVM-internen Namen statt lesbarer Quelltextsyntax: Jedes führende [ steht für eine Array-Dimension, und L<Klasse>; codiert den Komponententyp.
Führe dieses Beispiel aus:
public class RuntimeName {
public static void main(String[] args) {
Object value = "Hello, Java!";
String[] names = {"Ada", "Lin"};
System.out.println(value.getClass().getName());
System.out.println(names.getClass().getName());
}
}
Ausgabe:
java.lang.String
[Ljava.lang.String;
Die zweite Zeile beschreibt ein eindimensionales Array aus java.lang.String. Weil diese Codierung schwer zu lesen ist, sind für Arrays getSimpleName() oder getTypeName() die bessere Wahl.
Mit getClass().getTypeName() den Typ einer Variablen in Java prüfen
getTypeName() gibt den Typnamen als String zurück. Bei einem String-Objekt enthält er, anders als bei getSimpleName(), auch den Paketnamen.
Führe dieses Beispiel aus:
public class RuntimeTypeName {
public static void main(String[] args) {
Object value = "Hello, Java!";
String typeName = value.getClass().getTypeName();
System.out.println(typeName);
}
}
Ausgabe:
java.lang.String
Wähle getSimpleName() für den kurzen Namen, getName() für den Klassennamen samt Paket und getTypeName() für einen lesbaren Typnamen, der auch Arrays lesbar formatiert. Keine der drei Methoden ermittelt den deklarierten Typ einer Variablen.
Mit instanceof prüfen, ob ein Objekt eine Instanz eines Typs ist
Der Operator instanceof beantwortet eine Ja/Nein-Frage statt einen Namen zu liefern: Ist dieses Objekt eine Instanz des angegebenen Typs oder eines seiner Untertypen? Er folgt damit der gesamten Typhierarchie, während ein Vergleich von getClass() mit == nur eine einzige, exakte Laufzeitklasse prüft.
Führe dieses Beispiel aus:
import java.util.ArrayList;
import java.util.List;
public class InstanceofCheck {
public static void main(String[] args) {
Object value = new ArrayList<String>();
System.out.println(value instanceof ArrayList);
System.out.println(value instanceof List);
System.out.println(value instanceof String);
System.out.println(value.getClass() == ArrayList.class);
System.out.println(value.getClass() == List.class);
}
}
Ausgabe:
true
true
false
true
false
Das Objekt ist eine Instanz von ArrayList und zugleich der Schnittstelle List, die ArrayList implementiert; beide instanceof-Prüfungen liefern daher true. Der letzte Vergleich liefert false, weil die exakte Laufzeitklasse ArrayList ist, nicht List. Faustregel: instanceof akzeptiert Untertypen, die Gleichheit von getClass() nur die exakte Klasse.
Mit Pattern Matching für instanceof in einem Schritt prüfen und umwandeln
Seit Java 16 kann instanceof zusätzlich eine Mustervariable des geprüften Typs deklarieren. Ist die Prüfung erfolgreich, liegt der Wert bereits umgewandelt vor, und die Variable bleibt nur dort im Gültigkeitsbereich, wo die Prüfung als erfolgreich feststeht – der früher nötige separate Cast entfällt.
Führe dieses Beispiel aus:
public class InstanceofPattern {
public static void main(String[] args) {
Object value = "Hello, Java!";
if (value instanceof String text) {
System.out.println(text.toUpperCase());
}
Object number = 42;
if (number instanceof String text) {
System.out.println(text);
} else {
System.out.println("Not a string");
}
}
}
Ausgabe:
HELLO, JAVA!
Not a string
Die erste Prüfung bindet text als direkt verwendbaren String. Die zweite schlägt fehl – die verpackte 42 ist ein Integer –, also läuft der else-Zweig.
Den Typ einer Variablen prüfen, die null sein kann
Eine null-Referenz zeigt auf kein Objekt und hat deshalb keine Laufzeitklasse. getClass() auf ihr aufzurufen, wirft eine NullPointerException. Der Operator instanceof ist die null-sichere Prüfung: Er liefert für null einfach false, statt eine Ausnahme zu werfen.
Führe dieses Beispiel aus:
public class NullTypeCheck {
public static void main(String[] args) {
Object value = null;
System.out.println(value instanceof String);
try {
System.out.println(value.getClass().getSimpleName());
} catch (NullPointerException e) {
System.out.println("getClass() failed: value is null");
}
}
}
Ausgabe:
false
getClass() failed: value is null
Prüfe einen Wert, der null sein kann, zuerst ausdrücklich mit value == null oder mit instanceof, bevor du eine getClass()-Methode auf ihm aufrufst.
Den Typ eines primitiven Werts in Java prüfen
Primitive Werte wie int und double sind einfache Werte, keine Objekte: Sie haben keine Methoden und tragen keine Laufzeitklasse. Ihr Typ steht bereits beim Kompilieren fest, und zur Laufzeit arbeitet die JVM nur mit dem reinen Wert – genau deshalb kompiliert count.getClass() nicht.
Um einen primitiven Wert zur Laufzeit zu prüfen, lässt du ihn in seine Wrapper-Klasse verpacken; gemeldet wird dann der Wrapper, niemals der primitive Typ selbst. Ein Klassenliteral für den primitiven Typ existiert trotzdem – int.class, dasselbe Objekt wie Integer.TYPE –, es benennt aber den Typ abstrakt, nicht einen konkreten Wert.
Führe dieses Beispiel aus:
public class PrimitiveTypeCheck {
public static void main(String[] args) {
int count = 3;
double price = 9.99;
Object boxedCount = count;
Object boxedPrice = price;
System.out.println(boxedCount.getClass().getSimpleName());
System.out.println(boxedPrice.getClass().getSimpleName());
System.out.println(int.class.getSimpleName());
System.out.println(double.class == Double.TYPE);
}
}
Ausgabe:
Integer
Double
int
true
Kurz gesagt: Der Typ eines primitiven Werts ist nur eine Tatsache zur Kompilierzeit. Solange das Boxing kein Objekt erzeugt hat, gibt es zur Laufzeit nichts, das getClass() oder instanceof prüfen könnten.
Fazit
Verwende getClass().getSimpleName(), getClass().getName() oder getClass().getTypeName(), wenn du den Namen der exakten Laufzeitklasse eines Objekts brauchst. Verwende instanceof – ab Java 16 mit Mustervariable, wenn du die Umwandlung gleich mit brauchst –, wenn jeder Untertyp die Prüfung bestehen soll, und verlasse dich bei Werten, die null sein können, auf instanceof. Primitive Werte haben keinen meldbaren Laufzeittyp; verpacke sie zuerst und erwarte die Wrapper-Klasse, etwa Integer für ein int.