Java: Hvorfor må skrive kaste for instanceof () i equals ()? Er det for referanse eller mindre kode?

stemmer
0

Java nybegynner her, jeg har en grunnleggende spørsmål som er halvt besvart av tidligere svar i andre tråder eller docs, men jeg fortsatt ikke fullt ut forstår mekanismen, og jeg ønsker å være sikker på at jeg dekker det grunnleggende (kode nederst, spørsmål i midten).

I utgangspunktet er jeg overstyrer likhets () Metode for å sjekke om to MyDate objektene har samme dato. Jeg gjør en instanceof sjekke om o objektet er en MyDate objekt, så du skriver kastet en temp objekt spesifikt til en MyDate objekt o, så du sammenligne datoer. Hvorfor du skriver kastet temp variabel til MyDate klasse av o, når det allerede er for MyDate klassen?

  1. Bruker du temp variabel som en lettere referanse objektet du vil kjøre likhets () sammenligning? Fordi du bruker lik () som sammenligner MyDate.equals(MyOtherDate)i koden hvis jeg ikke utpeke en variabel til å holde referansen så du får forskjellige feil (temp kan ikke løses som en variabel, type mismatch, etc i utgangspunktet kompilatoren er ikke sikker på hvor å se med mindre du skrive en haug mer kode).

2a. Noen av de andre trådene sa noe om at mens instanceof kontrollerer om en forekomst er fra en klasse, det sjekker basen klassen, men sjekker ikke en underklasse. Du gjør typecasting fordi du er spesielt fortelle kompilatoren for å se etter at bestemt objekt (type casting fra en generell objekt til et bestemt objekt). MERK: Dette kan være en versjon og smak bestemt type spørsmål, har jeg sett ulike svar på lignende spørsmål.

2b. Casting endrer referanse, ikke selve objektet. Så, hvis objektene er fra samme klasse, men forskjellige underklasser, ville ikke det svikter under kjøring, i stedet for kompilering. Og jeg ville ikke få en ClassCastException?

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;
        }
Publisert på 14/01/2020 klokken 00:01
kilden bruker
På andre språk...                            


2 svar

stemmer
0

Java kompilatoren ikke forstår den type klasse av objektet "o" som MyDate. Dette skjer fordi du har fått en parameter av typen Object så det vil bli lest som et objekt. For å få tilgang til de metoder og egenskaper for parameter av kjent type MyDate, må du fortelle kompilatoren at dette er et objekt av type MyDate. Dette er måten kompilatoren kommer til å forstå hva du gjør. Nå la oss ta en titt på en annen visning av syne.

Hver typer i Java strekker den typen Objectsom betyr at hver gang du skriver en klasse, du er implisitt utvide Objectoffentlige / beskyttede egenskaper og atferd. Det er derfor du er "overordnede" metoden equalssom tilhører Objecttype. Alright, når du gjør en sammenligning mellom to objekter må du først sjekke om begge tilhører samme type, som du gjorde i ditt eksempel med: if (o instanceof MyDate) { ... }å sikre at oer av type MyDate. Men på dette punktet, så du ikke kaste "o" til "MyDate" type du vil ikke være i stand til å få tilgang MyDate spesifikke egenskaper eller metoder. Så tenk på det en stund, hvis jeg har en klasse Asom utvider klassen min Bvil jeg være i stand til å få tilgang til B offentlige metoder og egenskaper inne i en, men jeg kan ikke gjøre det samme på B fordi B ikke kan se hva som skjer ned treet. Følger du?

Håper jeg kunne svare på dine tvil.

Svarte 14/01/2020 kl. 00:16
kilden bruker

stemmer
2

Java har to relaterte-but-atskilt begreper: den typen av et uttrykk , og den kjøretids-type av en verdi .

Disse begrepene er kompatible til en viss grad; hvis et uttrykk har typen MyDate, så når man evaluerer det uttrykk kan enten få en referanse til en gjenstand hvis kjøretids-type er enten MyDateeller en underklasse av MyDate, eller man får en null-referanse, eller man får et unntak eller uendelig løkke eller hva. Men begrepene er separate, og selv når runtime-typer er fine, noen ganger må du gi kompilatoren litt ekstra informasjon om hvilke typer.

> Hvorfor du skriver kastet temp variabel til MyDate klasse av o, når det allerede er for MyDate klassen?

Variabelen oer av type Object, ikke noensinne av type MyDate. Det skjer for å inneholde en referanse til en gjenstand hvis kjøretidstype er MyDate(eller en underklasse av MyDate), men som ikke påvirker ikke den type o. Så du skriver (MyDate)ofor å skape et uttrykk med samme verdi (og dermed samme runtime-type) og ønsket type.

Hvis kompilatoren var smartere, kan det kanskje behandle osom å ha typen MyDateinni if-statement, slik at du ikke trenger skuespillere; men den nåværende Java Language Specification ikke tillater det. (Og hvis det gjorde, som kunne ha noen rare konsekvenser når det gjelder statiske metoden utsendelse.)

Svarte 14/01/2020 kl. 00:21
kilden bruker

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