Java: Warum die Notwendigkeit für Instanceof gieße Typ () in equals ()? Ist es als Referenz oder weniger Code?

stimmen
0

Java-Neuling hier, ich habe eine grundlegende Frage, die Hälfte von früheren Antworten in anderen Threads oder die Dokumentation beantwortet wird, aber ich verstehe immer noch nicht vollständig den Mechanismus, und ich will sicher sein decke ich die Grundlagen (Code unten, Fragen in Mitte).

Grundsätzlich bin ich Überschreiben der Methode equals () zu überprüfen , ob zwei MyDate Objekte das gleiche Datum haben. Ich habe eine instanceof prüfen , ob das o Objekt ein MyDate Objekt ist, dann geben Sie ein temporäres Objekt spezifisch an ein MyDate Objekt geworfen o, dann sind Sie Daten vergleichen. Warum Art Sie die temporäre Variable MyDate Klasse von o werfen, wenn es bereits der MyDate Klasse ist?

  1. Haben Sie temporären Variable als einfache Referenz Sie das gewünschte Objekt verwenden Sie das equals () Vergleich laufen? Weil Sie verwenden equals () als Vergleich MyDate.equals(MyOtherDate), in dem Code , wenn ich den Verweis eine Variable nicht bezeichnen zu halten , dann erhalten Sie verschiedene Fehler (Temp kann nicht als Variable, Typenkonflikt gelöst werden, usw. im Grunde der Compiler nicht sicher ist , wo zu sehen , wenn Sie ein paar mehr Code) schreiben.

2a. Einige der anderen Threads sagte etwas zu dem Effekt , dass , während instanceof überprüft , ob eine Instanz von einer Klasse ist, ist es die überprüft Basisklasse, aber keine Unterklasse überprüfen. Sie haben die Schublade gesteckt , weil Sie den Compiler speziell doch sagen , für diesen spezielles Objekt (Typ Gießen von einem allgemeinen Objekt zu einem bestimmten Objekt) zu überprüfen. HINWEIS: Dies könnte eine Version und Geschmack bestimmte Art Frage, ich habe ähnliche Fragen zu unterschiedlichen Antworten gesehen.

2b. Gießen ändert die Referenz, nicht das Objekt selbst. Also, wenn die Objekte aus der gleichen Klasse, aber verschiedene Unterklassen, wäre es nicht scheitern zur Laufzeit statt der Kompilierung. Und ich würde nicht einen Classcast bekommen?

public boolean equals(Object o) {
            if (o instanceof MyDate) {
                MyDate temp = (MyDate) o;
                if ((temp.day == day) && (temp.month == month) && (temp.year == year)) {
                    return true;
                }
            } 
            return false;
        }
Veröffentlicht am 14/01/2020 um 00:01
quelle vom benutzer
In anderen Sprachen...                            


2 antworten

stimmen
0

Der Java - Compiler nicht verstehen , die Typklasse des Objekts „o“ als MyDate zu sein. Dies geschieht , weil Sie einen Parameter des Typs Objekt erhalten haben , so dass es als ein Objekt gelesen wird. Um die Methoden und Eigenschaften des Parameters des bekannten Typ MyDate zugreifen zu können , müssen Sie den Compiler sagen , dass dies ein Objekt vom Typ ist MyDate. Dies ist die Art und Weise der Compiler verstehen wird , was du tust. Lassen Sie uns jetzt einen Blick in eine andere Ansicht Sicht nehmen.

Alle Arten in Java erweitert die Art , Objectdie bedeutet , dass jedes Mal , wenn Sie eine Klasse schreiben, sind Sie implizit die Verlängerung Objectpublic / geschützten Eigenschaften und Verhaltensweisen. Deshalb sollten Sie „Überschreiben“ , um die Methode , equalsdie gehört zu dem ObjectTyp. In Ordnung, wenn man einen Vergleich zwischen zwei Objekten tun überprüfen müssen Sie zuerst , wenn sie beide auf die gleiche Art gehört, wie Sie in Ihrem Beispiel haben mit: if (o instanceof MyDate) { ... }um sicherzustellen , dass oder Typ ist MyDate. Aber an diesem Punkt, da Sie nicht „o“ auf „MyDate“ hergegeben geben Sie nicht in der Lage sein , den Zugang MyDate spezifischen Eigenschaften oder Methoden. Also denken Sie an es für eine Weile, wenn ich eine Klasse, Adie meine Klasse erweitert Bich in der Lage sein , der Zugang B öffentlichen Methoden und Eigenschaften innen A, aber ich kann das gleiche auf B nicht tun , weil B kann nicht sehen , was passiert nach unten der Baum. Verstehst du?

Hoffnung kann ich Ihre Zweifel beantworten.

Beantwortet am 14/01/2020 um 00:16
quelle vom benutzer

stimmen
2

Java hat zwei verwandte aber trennbar Konzepte: den Typ eines Ausdrucks , und die Laufzeit-Typ eines Wertes .

Diese Konzepte sind in gewissem Maße kompatibel; wenn ein Ausdruck Typ hat MyDate, dann , wenn Sie diesen Ausdruck auswerten, erhalten Sie entweder einen Verweis auf ein Objekt , dessen Laufzeit-Typ ist entweder MyDateoder eine Unterklasse von MyDate, oder Sie ein NULL - Verweis erhalten, oder Sie eine Ausnahme oder Endlosschleife oder Dingsbums bekommen. Aber die Konzepte sind getrennt, und selbst wenn Ihre Runtime-Typen sind in Ordnung, manchmal müssen Sie dem Compiler einige zusätzliche Informationen über die Art geben.

> Warum Art Sie die temporäre Variable MyDate Klasse von o werfen, wenn es bereits der MyDate Klasse ist?

Die Variable oist vom Typ Object, nicht immer vom Typ MyDate. Es geschieht eine Referenz auf ein Objekt , dessen Laufzeit-Typ enthalten MyDate(oder einer Unterklasse MyDate), aber das hat keinen Einfluss auf die Art der o. So schreiben Sie (MyDate)oeinen Ausdruck mit dem gleichen Wert (und somit die gleiche Laufzeit-Typ) und den gewünschten Typ zu erstellen.

Wenn die Compiler klüger wären, könnte es vielleicht behandeln oals Typen mit MyDatein Ihrer if-Anweisung, so würden Sie nicht die Besetzung müssen; aber die aktuelle Java Language Specification erlaubt das nicht. (Und wenn es so wäre, könnte einige seltsame Auswirkungen haben , wenn es um statische Methode Versand kommt.)

Beantwortet am 14/01/2020 um 00:21
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more