Wenn Klasse B
und Klasse Klasse C
erweitern A
und ich ein Objekt vom Typ B
oder habe C
, wie kann ich feststellen, von welchem Typ es sich um eine Instanz handelt?
Wenn Klasse B
und Klasse Klasse C
erweitern A
und ich ein Objekt vom Typ B
oder habe C
, wie kann ich feststellen, von welchem Typ es sich um eine Instanz handelt?
Antworten:
if (obj instanceof C) {
//your code
}
if(!(obj instanceof C))
code
Child1 child1 = new Child1 (); Parent1 parentChild = new Child2 (); Child2 child2 = new Child2 (); (child1-Instanz von Parent1); (child1 Instanz von Child1); (parentChild-Instanz von Child2); (parentChild-Instanz von Parent1); (parentChild-Instanz von Child1); code
kann es die Absicht der Instanz von löschen.
Verwenden Sie Object.getClass () . Es gibt den Laufzeittyp des Objekts zurück.
Es wurden mehrere richtige Antworten präsentiert, aber es gibt noch mehr Methoden: Class.isAssignableFrom()
und einfach zu versuchen, das Objekt zu werfen (was ein werfen könnte ClassCastException
).
Lassen Sie uns die möglichen Möglichkeiten zum Testen zusammenfassen, ob ein Objekt obj
eine Instanz vom Typ ist C
:
// Method #1
if (obj instanceof C)
;
// Method #2
if (C.class.isInstance(obj))
;
// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
;
// Method #4
try {
C c = (C) obj;
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
// Method #5
try {
C c = C.class.cast(obj);
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
null
HandhabungEs gibt jedoch einen Unterschied in der null
Handhabung:
false
wenn obj
ist null
( null
nicht Instanz von irgendetwas ist).NullPointerException
offensichtlich einen werfen .null
weil null
auf jeden Typ gegossen werden kann!Zu beachten:
null
ist keine Instanz eines Typs, kann aber in einen beliebigen Typ umgewandelt werden.
Class.getName()
sollte nicht verwendet werden, um einen "is-instance-of" -Test durchzuführen, da das Objekt, wenn es nicht vom Typ, C
sondern von einer Unterklasse ist, möglicherweise einen völlig anderen Namen und ein anderes Paket hat (daher stimmen Klassennamen offensichtlich nicht überein) immer noch vom Typ C
.Class.isAssignableFrom()
ist der Vererbungsgrund nicht symmetrisch : obj.getClass().isAssignableFrom(C.class)
würde zurückgeben, false
wenn der Typ von obj
eine Unterklasse von ist C
.Sie können verwenden:
Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object
HTH. Aber ich denke, die meiste Zeit ist es keine gute Praxis, dies für den Kontrollfluss oder ähnliches zu verwenden ...
Jede Verwendung einer der vorgeschlagenen Methoden wird als Codegeruch betrachtet, der auf einem schlechten OO-Design beruht.
Wenn Ihr Design gut ist, sollten Sie nicht feststellen, dass Sie getClass()
oder verwenden müssen instanceof
.
Jede der vorgeschlagenen Methoden reicht aus, aber nur etwas, das Sie in Bezug auf das Design beachten sollten.
In diesem Fall können wir Reflexion verwenden
objectName.getClass().getName();
Beispiel:-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getClass().getName();
}
In diesem Fall erhalten Sie den Namen der Klasse, die das Objekt an die HttpServletRequest
Schnittstellenreferenzvariable übergibt.
obj.getClass()
wird der Klassenname, Präfixex durch das Wortclass
request.getClass().getName();
druckt alle Pakete! zusammen mit Klassennamen
Es gibt auch eine .isInstance
Methode für die Class
Klasse " ". Wenn Sie die Klasse eines Objekts über erhalten myBanana.getClass()
, können Sie sehen, ob Ihr Objekt myApple
eine Instanz derselben Klasse wie myBanana
über ist
myBanana.getClass().isInstance(myApple)
Das Überprüfen mit isinstance()
würde nicht ausreichen, wenn Sie zur Laufzeit wissen möchten. verwenden:
if(someObject.getClass().equals(C.class){
// do something
}
Ich verwende die Blow-Funktion in meiner GeneralUtils-Klasse. Überprüfen Sie, ob sie nützlich sein kann
public String getFieldType(Object o) {
if (o == null) {
return "Unable to identify the class name";
}
return o.getClass().getName();
}
Ich habe Java 8-Generika verwendet, um die Objektinstanz zur Laufzeit abzurufen, anstatt Switch Case verwenden zu müssen
public <T> void print(T data) {
System.out.println(data.getClass().getName()+" => The data is " + data);
}
Übergeben Sie einen beliebigen Datentyp, und die Methode druckt den Datentyp, den Sie beim Aufrufen übergeben haben. z.B
String str = "Hello World";
int number = 10;
double decimal = 10.0;
float f = 10F;
long l = 10L;
List list = new ArrayList();
print(str);
print(number);
print(decimal);
print(f);
print(l);
print(list);
Es folgt die Ausgabe
java.lang.String => The data is Hello World
java.lang.Integer => The data is 10
java.lang.Double => The data is 10.0
java.lang.Float => The data is 10.0
java.lang.Long => The data is 10
java.util.ArrayList => The data is []