1. Egenskaber: getters og sættere
Når et stort projekt udvikles af snesevis af programmører på samme tid, dukker der ofte problemer op, hvis de håndterer dataene, der er lagret i klassefelter, forskelligt.
Måske undlader folk at studere klassens dokumentation i detaljer, eller måske beskriver den ikke alle tilfælde. Som følge heraf er der hyppige situationer, hvor et objekts interne data kan blive "ødelagt", hvilket gør objektet ugyldigt.
For at undgå disse situationer er det sædvanligt at gøre alle klassefelter private i Java . Kun klassens metoder kan ændre klassens variabler. Ingen metoder fra andre klasser kan få direkte adgang til variablerne.
Hvis du ønsker, at andre klasser skal kunne hente eller ændre data inde i objekter i din klasse, skal du tilføje to metoder til din klasse - en get-metode og en sæt-metode. Eksempel:
Kode | Bemærk |
---|---|
|
private navnefelt Initialisering af feltet via konstruktøren getName() — Denne metode returnerer værdien af navnefeltet setName() — Denne metode ændrer værdien af navnefeltet |
Ingen anden klasse kan ændre værdien af navnefeltet direkte. Hvis nogen har brug for at få værdien af navnefeltet, bliver de nødt til at kalde metoden getName()
på et Person
objekt. Hvis en kode ønsker at ændre værdien af navnefeltet, skal den kalde setName()
metoden på et Person
objekt.
Metoden getName()
kaldes også " getter for navnefeltet", og metoden setName()
kaldes "sætteren for navnefeltet".
Dette er en meget almindelig tilgang. I 80-90% af al Java-kode vil du aldrig se offentlige variabler i en klasse. I stedet vil de blive erklæret private
(eller protected
), og hver variabel vil have offentlige gettere og sættere.
Denne tilgang gør koden længere, men mere pålidelig.
At få direkte adgang til en klassevariabel er som at dreje din bil gennem dobbelte gule linjer : det er nemmere og hurtigere, men hvis alle gør det, så bliver tingene værre for alle.
Lad os sige, at du vil oprette en klasse, der beskriver et punkt ( x
, y
). Sådan vil en nybegynder programmør gøre det:
class Point
{
public int x;
public int y;
}
Sådan ville en erfaren Java-programmør gøre det:
Kode |
---|
|
Er koden længere? Utvivlsomt.
Men du kan tilføje parametervalidering til gettere og sættere. For eksempel kan du sikre dig, at x
og y
altid er større end nul (eller ikke mindre end nul). Eksempel:
Kode | Bemærk |
---|---|
|
2. Objektlevetid
Du ved allerede, at objekter oprettes ved hjælp af new
operatoren, men hvordan slettes objekter? De eksisterer ikke for evigt. Der er ikke nok hukommelse til det.
I mange programmeringssprog, såsom C++, er der en speciel delete
operator til at slette objekter. Men hvordan fungerer dette i Java?
I Java er alt indrettet lidt anderledes. Java har ingen delete-operator. Betyder det, at objekter ikke slettes i Java? Nej, de slettes selvfølgelig. Ellers ville Java-applikationer hurtigt løbe tør for hukommelse, og der ville ikke være tale om programmer, der kører uden afbrydelser i flere måneder.
I Java er sletningen af objekter fuldstændig automatiseret. Java-maskinen håndterer selv sletning af objekter. Denne proces kaldes garbage collection, og mekanismen, der samler affald, kaldes garbage collector ( GC ).
Så hvordan ved Java-maskinen, hvornår den skal slette et objekt?
Skraldesamleren opdeler alle genstande i "tilgængelige" og "utilgængelige". Hvis der er mindst én reference til et objekt, anses det for at være tilgængeligt. Hvis der ikke er nogen variabel, der refererer til et objekt, betragtes objektet som uopnåeligt og erklæres for skrald, hvilket betyder, at det kan slettes.
I Java kan du ikke oprette en reference til et eksisterende objekt - du kan kun tildele referencer, som du allerede har. Hvis vi sletter alle referencer til et objekt, så er det tabt for altid.
Cirkulære referencer
Den logik lyder fantastisk, indtil vi støder på et simpelt modeksempel: antag, at vi har to objekter, der refererer til hinanden (lagre referencer til hinanden). Ingen andre objekter gemmer referencer til disse objekter.
Disse objekter kan ikke tilgås fra koden, men der refereres stadig til dem.
Dette er grunden til, at skraldeopsamleren opdeler objekter i tilgængelige og utilgængelige i stedet for "refererede" og "ikke-referencer".
Tilgængelige objekter
Først føjes objekter, der er 100 % i live, til listen, der kan nås. For eksempel den aktuelle tråd ( Thread.current()
) eller konsollens InputStream ( System.in
).
Derefter udvides listen over objekter, der kan nås, til at omfatte objekter, der refereres til af det indledende sæt af tilgængelige objekter. Derefter udvides det igen til at inkludere objekter, der refereres til af dette forstørrede sæt, og så videre.
Det betyder, at hvis der er nogle objekter, der kun refererer til hinanden, men der ikke er nogen måde at nå dem fra tilgængelige objekter, så vil disse objekter blive betragtet som skrald og vil blive slettet.
3. Affaldsindsamling
Hukommelsesfragmentering
Et andet vigtigt punkt relateret til objektsletning er hukommelsesfragmentering. Hvis du konstant opretter og sletter objekter, vil hukommelsen snart blive stærkt fragmenteret: områder med optaget hukommelse vil blive afbrudt med områder med ledig hukommelse.
Som et resultat kan vi nemt komme i en situation, hvor vi ikke kan skabe et stort objekt (f.eks. et array med en million elementer), fordi der ikke er en stor del af ledig hukommelse. Med andre ord kan der være ledig hukommelse, endda meget af den, men der er muligvis ikke en stor sammenhængende blok af ledig hukommelse
Hukommelsesoptimering (defragmentering)
Java-maskinen løser dette problem på en bestemt måde. Det ser sådan ud:
Hukommelsen er opdelt i to dele. Alle objekter oprettes (og slettes) i kun den ene halvdel af hukommelsen. Når det bliver tid til at rydde op i hullerne i hukommelsen, kopieres alle objekter i første halvdel til anden halvdel. Men de er kopieret lige ved siden af hinanden, så der ikke er huller.
Processen ser nogenlunde sådan ud:
Trin 1: Efter oprettelse af objekter
Trin 2: Udseende af "huller"
Trin 3: Eliminering af "huller"
Og det er derfor, du ikke behøver at slette objekter. Java-maskinen kopierer simpelthen alle tilgængelige objekter til en ny placering og frigør hele hukommelsesområdet, hvor objekterne plejede at blive gemt.
GO TO FULL VERSION