Skip to content

Hva er en NullPointerException?

Et godt sted a starte er JavaDocs. De har dette dekket:

Kastet nar et program forsoker a bruke null i et tilfelle der en gjenstand er nodvendig. Disse inkluderer:

Kaller instansmetoden til et nullobjekt. Fa tilgang til eller endre feltet til et null objekt. Tar lengden pa null som om det var en matrise. A fa tilgang til eller endre slots null som om det var en matrise. Kaster null som om det var en odeleggende verdi.

Programmer bor kaste forekomster av denne klassen for a indikere andre ulovlige bruksomrader for nullobjektet.

Det er ogsa tilfelle at hvis du forsoker a bruke nullreferanse med synkronisert, vil det ogsa kaste dette unntaket, per JLS:

Ellers, hvis verdien av uttrykket er null, kastes en NullPointerException.

Hvordan loser jeg det?

Sa du har en NullPointerException. Hvordan loser du det? La oss ta et enkelt eksempel som kaster en NullPointerException:

Identifiser nullverdiene.

Det forste trinnet er a identifisere noyaktig hvilke verdier som forarsaker unntaket. For dette ma vi gjore noen feilsoking. Det er viktig a l re a lese en stacktrace. Dette vil vise deg hvor unntaket ble kastet:

Her ser vi at unntaket er kastet pa linje 13 (i printString-metoden). Se pa linjen og kontroller hvilke verdier som er null ved a legge til loggingsopplysninger eller bruke en debugger. Vi finner ut at s er null, og kaller lengdemetoden pa den kaster unntaket. Vi kan se at programmet slutter a kaste unntaket nar s.length () er fjernet fra metoden.

Spor hvor disse verdiene kommer fra.

Neste sjekk hvor denne verdien kommer fra. Ved a folge de som ringer til metoden ser vi at s er sendt inn med printString (navn) i utskriften () -metoden, og dette.navnet er null.

Spor hvor disse verdiene skal settes.

Hvor er dette.navnet sett? I setName (String) -metoden. Med litt mer feilsoking kan vi se at denne metoden ikke kalles i det hele tatt. Hvis metoden ble kalt, sorg for a sjekke rekkefolgen som disse metodene kalles, og den angitte metoden kalles ikke etter utskriftsmetoden.

Dette er nok til a gi oss en losning: Legg til et anrop til printer.setName () for du ringer printer.print ().

Andre reparasjoner.

Variabelen kan ha en standardverdi (og setName kan forhindre at den blir satt til null):

Enten kan utskrifts- eller printString-metoden sjekke for null, for eksempel:

Eller du kan designe klassen slik at navnet alltid har en ikke-null verdi:

Jeg kan fortsatt ikke finne problemet.

Hvis du provde a feilsoke problemet og fortsatt ikke har en losning, kan du legge inn et sporsmal for mer hjelp, men sorg for a inkludere det du har provd sa langt. I det minste skal du inkludere stacktrace i sporsmalet, og markere de viktige linjene i koden. Prov ogsa a forenkle koden forst (se SSCCE).

Sporsmal: Hva forarsaker en NullPointerException (NPE)?

Som du burde vite, er Java-typer delt inn i primitive typer (boolean, int, etc.) og referansetyper. Referansetyper i Java lar deg bruke den spesielle verdien null som er Java-maten a si "ingen objekt".

En NullPointerException kastes ved kjoretid nar programmet forsoker a bruke null som om det var en reell referanse. For eksempel, hvis du skriver dette:

uttalelsen merket "HER" skal forsoke a kjore lengden () -metoden pa null-referanse, og dette vil kaste en NullPointerException.

Det er mange mater du kan bruke en nullverdi som vil resultere i en NullPointerException. Faktisk er de eneste tingene du kan gjore med null uten a forarsake en NPE:

tilordne den til en referansevariabel eller lese den fra en referansevariabel, tilordne den til et arrayelement eller lese det fra et arrayelement (forutsatt at array referansen selv er null!), send den som en parameter eller returner den som en parameter Resultat, eller test det ved hjelp av == eller! = operatorene, eller instanceof.

Sporsmal: Hvordan leser jeg NPE stacktrace?

Anta at jeg kompilerer og driver programmet ovenfor:

Forste observasjon: Samlingen lykkes! Problemet i programmet er IKKE en kompileringsfeil. Det er en runtime feil. (Noen IDEer kan varsle programmet vil alltid kaste et unntak. Men standard javac-kompilatoren gjor det ikke.)

Andre observasjon: Nar jeg kjorer programmet, blir det to linjer med "gobbledy-gook". FEIL!! Det er ikke gobbledy-gook. Det er en stacktrace. og det gir viktig informasjon som vil hjelpe deg med a spore feilen i koden din, hvis du tar deg tid til a lese den noye.

Sa la oss se pa hva det star:

Den forste linjen i stakkesporet forteller deg en rekke ting:

Den forteller deg navnet pa Java-traden der unntaket ble kastet. For et enkelt program med en trad (som denne), blir den "main". La oss ga videre . Det forteller deg det fulle navnet pa unntaket som ble kastet; dvs. java.lang.NullPointerException. Hvis unntaket har en tilknyttet feilmelding, blir den sendt ut etter unntaksnavnet. NullPointerException er uvanlig i denne forbindelse, fordi den sjelden har en feilmelding.

Den andre linjen er den viktigste i a diagnostisere en NPE.

Dette forteller oss en rekke ting:

"pa Test.main" sier at vi var i hovedklassen for testklassen. "Test.java:4" gir kilden filnavn av klassen, og det forteller oss at setningen der dette skjedde er i linje 4 i filen.

Hvis du teller linjene i filen ovenfor, er linje 4 den jeg merket med "HER" kommentaren.

Merk at i et mer komplisert eksempel vil det v re mange linjer i NPE-stakkesporingen. Men du kan v re sikker pa at den andre linjen (den forste "pa" linjen) vil fortelle deg hvor NPE ble kastet 1.

Kort sagt, stakkesporet forteller oss utvetydig hvilken erkl ring av programmet som har kastet NPE.

1 - Ikke helt sant. Det er ting som kalles nestede unntak.

Sporsmal: Hvordan sporer jeg arsaken til NPE-unntaket i koden min?

Dette er den harde delen. Det korte svaret er a anvende logisk inngripen til bevisene fra stakkespor, kildekoden og den relevante API-dokumentasjonen.

La oss illustrere med det enkle eksempelet (ovenfor) forst. Vi starter med a se pa linjen som stakkesporet har fortalt oss, er hvor NPE skjedde:

Hvordan kan det kaste en NPE?

Faktisk er det bare en mate: det kan bare skje hvis foo har verdien null. Vi prover a kjore lengden () -metoden pa null og. BANG!

Men (jeg horer deg si) hva om NPE ble kastet i lengden () metodeanropet?

Vel, hvis det skjedde, ville stakkesporet se annerledes ut. Den forste "pa" -linjen vil si at unntaket ble kastet i en eller annen linje i java.lang.String-klassen, og linje 4 i Test.java ville v re den andre "pa" -linjen.

Sa hvor kom det null fra? I dette tilfellet er det apenbart, og det er apenbart hva vi ma gjore for a fikse det. (Tilordne en ikke-null verdi til foo.)

OK, sa la oss prove et litt vanskeligere eksempel. Dette vil kreve noe logisk fradrag.

Sa na har vi to "pa" linjer. Den forste er for denne linjen:

og den andre er for denne linjen:

Ser du pa den forste linjen, hvordan kunne det kaste en NPE? Det er to mater:

Hvis verdien av baren er null, vil bar [pos] kaste en NPE. Hvis verdien av linjen [pos] er null, vil ringelengden () pa den kaste en NPE.

Deretter ma vi finne ut hvilke av disse scenariene som forklarer hva som faktisk skjer. Vi vil begynne med a utforske den forste:

Hvor kommer linjen fra? Det er en parameter til testmetoden, og hvis vi ser pa hvordan testen ble kalt, kan vi se at den kommer fra den foo statiske variabelen. I tillegg ser vi tydelig at vi initialiserte foo til en ikke-null verdi. Det er nok til a forsoke a avvise denne forklaringen. (I teorien kan noe annet endre foo til null, men det skjer ikke her.)

Sa hva med vart andre scenario? Vel, vi kan se at pos er 1, sa det betyr at foo [1] ma v re null. Er det mulig?

Det skal v re sikkert! Og det er problemet. Nar vi initialiserer slik:

Vi tildeler en streng [] med to elementer som initialiseres til null. Etter det har vi ikke endret innholdet i foo. sa foo [1] vil fortsatt v re null.

Et nullpunkts unntak er forarsaket nar du dereference en variabel som peker til null. Se folgende kode:

Et nullpunkts unntak kastes nar et program forsoker a bruke null i et tilfelle der et objekt er nodvendig. Disse inkluderer:

Kaller instansmetoden til et nullobjekt. Fa tilgang til eller endre feltet til et null objekt. Tar lengden pa null som om det var en matrise. A fa tilgang til eller endre slots null som om det var en matrise. Kaster null som om det var en odeleggende verdi.

Programmer bor kaste forekomster av denne klassen for a indikere andre ulovlige bruksomrader for nullobjektet.

En NULL-peker er en som peker til ingensteds. Nar du dereferrer en peker p, sier du "gi meg dataene pa stedet lagret i" p ". Nar p er nullpunkt, er plasseringen som er lagret i p ingen steder, du sier" gi meg dataene pa stedet 'ingensteds' ". Det kan selvsagt ikke gjore dette, sa det kaster et NULL-pekers unntak.

Generelt er det fordi noe ikke har blitt initialisert riktig.

Mange forklaringer er allerede til stede for a forklare hvordan det skjer, og hvordan du fikser det, men du bor ogsa folge gode fremgangsmater for a unnga NullPointerException i det hele tatt.

Bruk den endelige modifikatoren for a handheve god initialisering. Unnga a returnere null i metoder, for eksempel a returnere tomme samlinger nar det er aktuelt. Bruk notater @NotNull og @Nullable Fail raskt og bruk hevder a unnga spredning av nullobjekter gjennom hele applikasjonen nar de ikke skal v re null. Bruk er lik med et kjent objekt forst: hvis ("knownObject" .equals (unknownObject) Foretrukket verdiOf () over toString (). Bruk null sikker StringUtils metoder StringUtils.isEmpty (null).

Et nullpunkts unntak er en indikator pa at du bruker et objekt uten a initialisere det.

For eksempel, nedenfor er en student klasse som vil bruke den i var kode.

Nedenfor koden gir deg et nullpunkts unntak.

Fordi du bruker Obj_Student, men du glemte a initialisere den som i riktig kode som er vist nedenfor:

I Java er alt i form av en klasse.

Hvis du vil bruke noe objekt, har du to faser:

Samme for gruppekonseptet.

Hvis du ikke gir initialiseringsseksjonen, oppstar NullpointerException.

I Java er alle variablene du erkl rer faktisk "referanser" til objektene (eller primitiver) og ikke objektene selv.

Nar du forsoker a utfore en objektmetode, spor referansen det levende objektet for a utfore den metoden. Men hvis referansen refererer til NULL (ingenting, null, tomrom, nada) sa er det ingen mate metoden blir utfort. Sa kjoretiden lar deg vite dette ved a kaste en NullPointerException.

Din referanse er "peker" til null, dermed "Null -> Pointer".

Objektet lever i VM-minneplassen, og den eneste maten a fa tilgang til den, er a bruke disse referansene. Ta dette eksempelet:

Dette er en viktig ting a vite - nar det ikke er flere referanser til et objekt (i eksemplet ovenfor nar referanse og andreReferanse peker til null), er objektet "unreachable". Det er ingen mate vi kan jobbe med, sa dette objektet er merket for a bli soppel samlet, og pa et tidspunkt vil VM frigjore minnet som brukes av dette objektet og vil tildele en annen.

En annen forekomst av en NullPointerException oppstar nar man erkl rer en objektmatrise, og forsoker deretter a analysere elementene i den.

Denne spesielle NPE kan unngas hvis sammenligningsordren er reversert; nemlig bruk .equals pa et garantert ikke-null objekt.

Alle elementene inne i en matrise er initialisert til sin felles innledende verdi; for alle typer objektmatrise, betyr det at alle elementene er null.

Du ma initialisere elementene i arrayet for du far tilgang til eller dereferrer dem.


Hallo! Vil du spille i det mest populære kasinoet? Vi samlet det for deg. Gå her nå!