Java: Waarom de noodzaak instanceof met het type op te brengen voor () in gelijken ()? Is het voor referentie of minder code?

stemmen
0

Java newbie hier, ik heb een fundamentele vraag die de helft wordt beantwoord door de vorige reacties in andere threads of de documentatie, maar ik weet nog steeds niet volledig begrijpen van het mechanisme en ik wil er zeker van zijn I gaat over de fundamenten (code aan de onderkant, vragen in midden).

Kortom, ik ben overschrijven van de equals () methode om te controleren of twee MyDate objecten die op dezelfde datum. Ik doe een instanceof controleren of de o object is een MyDate object, dan typt u specifiek cast een temp object naar een MyDate object o, dan vergelijk je data. Waarom denk je typt werpen de temp variabele MyDate klasse van o, als het al is van de MyDate klas?

  1. Heeft u temp variabele het object dat u wilt de equals () vergelijking draaien gebruiken als een eenvoudiger referentie? Omdat je gelijk aan () te gebruiken als het vergelijken MyDate.equals(MyOtherDate), in de code als ik niet een variabele aanwijzen om de referentie te houden dan krijg je verschillende fouten (temp niet opgelost kan worden als een variabele, het type mismatch, etc principe de compiler is niet zeker waar te kijken, tenzij je schrijft een heleboel meer code).

2a. Enkele van de andere threads zei iets in die zin dat terwijl instanceof controleert of een instantie is van een klasse, controleert de basis klasse, maar controleert niet een subklasse. Je doet de typecasting omdat je specifiek vertellen de compiler om te controleren voor dat specifieke object (type casting van een algemeen doel om een specifiek object). LET OP: Dit zou een versie en smaak specifiek type vraag te zijn, heb ik verschillende antwoorden op soortgelijke vragen gezien.

2b. Casting verandert de referentie, niet het object zelf. Dus, als de objecten zijn afkomstig uit dezelfde klasse, maar verschillende subklassen, zou het niet vallen op runtime, in plaats van het compileren. En zou ik niet een ClassCastException krijgen?

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;
        }
De vraag is gesteld op 14/01/2020 om 00:01
bron van user
In andere talen...                            


2 antwoorden

stemmen
0

De Java-compiler begrijpt niet het type klasse van uw object "o" als zijnde MyDate. Dit gebeurt omdat je een parameter van het type object hebben ontvangen dus het zal worden gelezen als een object. Om toegang te krijgen tot de methoden en eigenschappen van de parameter van een bekend type MyDate, moet je de compiler vertellen dat dit is een object van het type MyDate. Dit is de manier waarop de compiler gaat om te begrijpen wat je doet. Laten we nu eens een kijkje nemen naar een andere weergave zicht.

Iedere types in Java breidt de soort Object, wat betekent dat elke keer dat je een klasse schrijft, je impliciet de uitbreiding van de Objectpubliek / beschermde eigenschappen en gedragingen. Dat is de reden waarom u de methode "dwingende" equalsdat behoort tot het Objecttype. Oke, als je aan het doen bent een vergelijking tussen twee objecten moet u eerst controleren of beiden behoort tot dezelfde soort, zoals u in uw voorbeeld met deed: if (o instanceof MyDate) { ... }om ervoor te zorgen dat ois van het type MyDate. Maar op dit punt, als je niet "o" wierpen op "MyDate" type je zult niet in staat om specifieke eigenschappen of methoden toegang MyDate's. Dus denk aan het voor een tijdje, als ik heb een klasse Adat mijn klasse breidt Bzal ik in staat om toegang B publieke methoden en eigenschappen in A, maar ik kan niet hetzelfde te doen op B, omdat B niet kan zien wat er gebeurt naar beneden de boom. Volg jij?

Hoop dat ik kan uw twijfels beantwoorden.

antwoordde op 14/01/2020 om 00:16
bron van user

stemmen
2

Java twee verwante, maar verschillende begrippen-: de soort van de expressie en de runtime-type van een waarde .

Deze concepten zijn compatibel enigszins; Als een expressie heeft soort MyDate, dan wanneer je de uitdrukking uit, je ofwel een verwijzing naar een object waarvan de runtime-type ofwel MyDateof een subklasse van MyDateof een null-referentie krijgt of u een beperking of oneindige lus of wat krijgen. Maar de concepten zijn gescheiden, en zelfs als uw runtime-types zijn prima, soms moet je de compiler wat extra informatie over de soorten geven.

> Waarom denk je typt werpen de temp variabele MyDate klasse van o, als het al is van de MyDate klas?

De variabele ois van het type Object, niet altijd van het type MyDate. Het gebeurt een verwijzing naar een object waarvan de runtime-type bevat MyDate(of een subklasse van MyDate), maar dat heeft geen invloed op het type o. Dus schrijf je (MyDate)oeen uitdrukking met dezelfde waarde (en dus dezelfde runtime-type) en het gewenste type te maken.

Als de compiler slimmer zou zijn, zou het misschien te behandelen oals het hebben van het type MyDatein uw if-statement, zodat u de cast niet nodig zou hebben; maar de huidige Java-taal specificatie worden niet toestaan. (En als dat zo was, dat kon wel wat rare gevolgen hebben als het gaat om statische methode verzending.)

antwoordde op 14/01/2020 om 00:21
bron van user

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