Upcasting ist in Java zulässig, Downcasting führt jedoch zu einem Kompilierungsfehler.
Der Kompilierungsfehler kann durch Hinzufügen einer Umwandlung behoben werden, würde aber zur Laufzeit trotzdem unterbrochen.
In diesem Fall, warum erlaubt Java Downcasting, wenn es zur Laufzeit nicht ausgeführt werden kann?
Gibt es eine praktische Verwendung für dieses Konzept?
public class demo {
public static void main(String a[]) {
B b = (B) new A(); // compiles with the cast,
// but runtime exception - java.lang.ClassCastException
}
}
class A {
public void draw() {
System.out.println("1");
}
public void draw1() {
System.out.println("2");
}
}
class B extends A {
public void draw() {
System.out.println("3");
}
public void draw2() {
System.out.println("4");
}
}
Antworten:
Downcasting ist zulässig, wenn die Möglichkeit besteht, dass es zur Laufzeit erfolgreich ist:
In einigen Fällen wird dies nicht gelingen:
Wenn ein Cast (wie dieser letzte) zur Laufzeit fehlschlägt,
ClassCastException
wird a geworfen.In anderen Fällen wird es funktionieren:
Beachten Sie, dass einige Casts beim Kompilieren nicht zulässig sind, da sie niemals erfolgreich sein werden:
quelle
Object o = new Object(); String s = (String) o;
Es funktioniert gut für mich ..: O wie?Anhand Ihres Beispiels können Sie Folgendes tun:
quelle
Ich glaube, dass dies für alle statisch typisierten Sprachen gilt:
Der Typecast sagt effektiv: Nehmen Sie an, dass dies ein Verweis auf die Besetzungsklasse ist, und verwenden Sie ihn als solchen. Nehmen wir nun an, o ist wirklich eine Ganzzahl, vorausgesetzt, dies ist ein String, macht keinen Sinn und führt zu unerwarteten Ergebnissen. Daher muss eine Laufzeitprüfung und eine Ausnahme durchgeführt werden, um die Laufzeitumgebung darüber zu informieren, dass etwas nicht stimmt.
In der Praxis können Sie Code schreiben, der an einer allgemeineren Klasse arbeitet, ihn jedoch in eine Unterklasse umwandeln, wenn Sie wissen, um welche Unterklasse es sich handelt, und ihn als solche behandeln müssen. Ein typisches Beispiel ist das Überschreiben von Object.equals (). Angenommen, wir haben eine Klasse für Auto:
quelle
Wir alle können sehen, dass der von Ihnen bereitgestellte Code zur Laufzeit nicht funktioniert. Das ist , weil wir wissen , dass der Ausdruck
new A()
kann nie ein Objekt vom Typ seinB
.Aber so sieht es der Compiler nicht. Wenn der Compiler prüft, ob die Umwandlung zulässig ist, sieht er nur Folgendes:
Und wie andere gezeigt haben, ist diese Art der Besetzung vollkommen legal. Der Ausdruck auf der rechten Seite könnte sehr gut zu einem Objekt vom Typ ausgewertet werden
B
. Der Compiler sieht dasA
undB
hat eine Subtyp-Beziehung, sodass mit der "Ausdruck" -Ansicht des Codes die Umwandlung möglicherweise funktioniert.Der Compiler berücksichtigt den Sonderfall nicht, wenn er genau weiß , welchen Objekttyp er
expression_of_type_A
wirklich haben wird. Es sieht nur den statischen Typ alsA
und betrachtet den dynamischen Typ alsA
oder einen Nachkommen davonA
, einschließlichB
.quelle
Ich glaube, das liegt daran, dass der Compiler zur Kompilierungszeit nicht wissen kann, ob die Besetzung erfolgreich sein wird oder nicht. In Ihrem Beispiel ist es einfach zu erkennen, dass die Besetzung fehlschlägt, aber es gibt andere Zeiten, in denen dies nicht so klar ist.
Stellen Sie sich zum Beispiel vor, dass die Typen B, C und D alle den Typ A erweitern, und dann gibt eine Methode
public A getSomeA()
abhängig von einer zufällig generierten Zahl eine Instanz von B, C oder D zurück. Der Compiler kann nicht wissen, welcher genaue Laufzeittyp von dieser Methode zurückgegeben wird. Wenn Sie also die Ergebnisse später umwandeln, können Sie nicht feststellenB
, ob die Umwandlung erfolgreich ist (oder fehlschlägt). Daher muss der Compiler davon ausgehen, dass Casts erfolgreich sind.quelle
@ Original Poster - siehe Inline-Kommentare.
quelle
Downcast funktioniert in dem Fall, in dem es sich um ein Upcast-Objekt handelt. Upcasting:
Jetzt kann diese
objValue
Variable immer herabgestuft werden,int
da das gegossene Objekt einInteger
,aber weil
objValue
es ein Objekt ist, kann es nicht gewirkt werden,String
weil es nicht gewirkt werdenint
kannString
.quelle
Downcasting ist sehr nützlich in dem folgenden Code-Snippet, das ich ständig benutze. Dies beweist, dass Downcasting nützlich ist.
Ich speichere String in der verknüpften Liste. Wenn ich die Elemente der verknüpften Liste abrufe, werden Objekte zurückgegeben. Um auf die Elemente als Strings (oder andere Klassenobjekte) zuzugreifen, hilft mir das Downcasting.
Mit Java können wir Downcast-Code kompilieren und uns darauf verlassen, dass wir das Falsche tun. Wenn Menschen einen Fehler machen, wird er zur Laufzeit abgefangen.
quelle
void*
Zeigern in C ++. Es klingt für mich überhaupt nicht nach einer guten Idee.Betrachten Sie das folgende Beispiel
Hier erstellen wir das Objekt der Unterklasse Bone und weisen es der Superklasse AOne-Referenz zu. Jetzt kennt die Superklasse-Referenz die Methode method2 in der Unterklasse, dh Bone, während der Kompilierungszeit nicht. Daher müssen wir diese Referenz der Superklasse auf die Unterklassenreferenz herabstufen, um Die resultierende Referenz kann über das Vorhandensein von Methoden in der Unterklasse, dh Knochen, informiert werden
quelle
Um Downcasting in Java durchzuführen und Laufzeitausnahmen zu vermeiden, verweisen Sie auf den folgenden Code:
Hier ist Tier die Elternklasse und Hund die Kinderklasse.
instanceof ist ein Schlüsselwort, mit dem überprüft wird, ob eine Referenzvariable einen bestimmten Typ von Objektreferenz enthält oder nicht.
quelle
Eine Downcasting-Transformation von Objekten ist nicht möglich. Nur
ist möglich
quelle