En guide til oprettelse af objekter i Java

1. Oversigt

Kort sagt, inden vi kan arbejde med et objekt på JVM, skal det initialiseres.

I de følgende afsnit ser vi på forskellige måder, vi kan initialisere primitive typer og objekter på.

2. Erklæring vs. initialisering

Lad os starte med at sikre, at vi er på samme side.

Erklæring er processen med at definere variablen sammen med dens type og navn.

Her erklærer vi id variabel:

int id;

Initialisering handler derimod om at tildele en værdi; for eksempel:

id = 1;

For at demonstrere opretter vi en Bruger klasse med en navn og id ejendomme:

offentlig klasse bruger {privat strengnavn; privat int id; // standard konstruktør, getters, setters,}

Derefter ser vi, at initialisering fungerer forskelligt afhængigt af typen af ​​felt, vi initialiserer.

3. Objekter vs. primitiver

Java giver to typer datarepræsentation: primitive typer og referencetyper. I dette afsnit vil vi diskutere forskellene mellem de to med hensyn til initialisering.

Java har otte indbyggede datatyper, kaldet primitive Java-typer; variabler af denne type holder deres værdier direkte.

Referencetyper indeholder referencer til objekter (forekomster af klasser). I modsætning til primitive typer, der holder deres værdier i hukommelsen, hvor variablen er tildelt, har referencer ikke værdien af ​​det objekt, de henviser til.

I stedet, en reference peger på et objekt ved at lagre hukommelsesadressen, hvor objektet er placeret.

Bemærk, at Java ikke tillader os at finde ud af, hvad den fysiske hukommelsesadresse er. Vi kan snarere kun bruge henvisningen til at henvise til objektet.

Lad os se på et eksempel, der erklærer og initialiserer en referencetype ud af vores Bruger klasse:

@Test offentlig ugyldig nårIntializedWithNew_thenInstanceIsNotNull () {Brugerbruger = ny bruger (); assertThat (bruger) .isNotNull (); }

Som vi kan se her, kan en henvisning tildeles en ny ved hjælp af nøgleordet ny, som er ansvarlig for at skabe det nye Bruger objekt.

Lad os fortsætte med at lære mere om oprettelse af objekter.

5. Oprettelse af objekter

I modsætning til primitiver er oprettelsen af ​​objekter lidt mere kompleks. Dette skyldes, at vi ikke bare tilføjer værdien til feltet; i stedet udløser vi initialiseringen ved hjælp af ny nøgleord. Dette til gengæld påkalder en konstruktør og initialiserer objektet i hukommelsen.

Lad os diskutere konstruktører og ny nøgleord i yderligere detaljer.

Det ny nøgleord er ansvarlig for at allokere hukommelse til det nye objekt gennem en konstruktør.

En konstruktør bruges typisk til at initialisere instansvariabler, der repræsenterer de vigtigste egenskaber for det oprettede objekt.

Hvis vi ikke leverer en konstruktør eksplicit, opretter compileren en standardkonstruktør, der ikke har nogen argumenter og kun tildeler hukommelse til objektet.

En klasse kan have mange konstruktører, så længe deres parameterlister er forskellige (overbelaste). Hver konstruktør, der ikke kalder en anden konstruktør i samme klasse, har et opkald til sin overordnede konstruktør, uanset om den blev skrevet eksplicit eller indsat af compileren gennem super().

Lad os tilføje en konstruktør til vores Bruger klasse:

offentlig bruger (strengnavn, int-id) {dette.navn = navn; this.id = id; }

Nu kan vi bruge vores konstruktør til at oprette en Bruger objekt med indledende værdier for dets egenskaber:

Brugerbruger = ny bruger ("Alice", 1);

6. Variabelt anvendelsesområde

I de følgende afsnit tager vi et kig på de forskellige typer anvendelsesområder, som en variabel i Java kan eksistere inden for, og hvordan dette påvirker initialiseringsprocessen.

6.1. Instans- og klassevariabler

Instans- og klassevariabler kræver ikke, at vi initialiserer dem. Så snart vi erklærer disse variabler, får de en standardværdi som følger:

Lad os nu prøve at definere nogle instans- og klasse-relaterede variabler og teste, om de har en standardværdi eller ej:

@Test offentlig ugyldig nårValuesAreNotInitialized_thenUserNameAndIdReturnDefault () {Bruger bruger = ny bruger (); assertThat (user.getName ()). er Null (); assertThat (user.getId () == 0); }

6.2. Lokale variabler

Lokale variabler skal initialiseres inden brug, da de ikke har en standardværdi, og compileren ikke lader os bruge en ikke-initialiseret værdi.

For eksempel genererer følgende kode en compiler-fejl:

offentlig ugyldig udskrivning () {int i; System.out.println (i); }

7. Den Endelig Nøgleord

Det endelig nøgleord anvendt på et felt betyder, at feltets værdi ikke længere kan ændres efter initialisering. På denne måde kan vi definere konstanter i Java.

Lad os tilføje en konstant til vores Bruger klasse:

privat statisk endelig int ÅR = 2000;

Konstanter skal initialiseres enten når de er erklæret eller i en konstruktør.

8. Initialiserer i Java

I Java er en initializer er en blok kode, der ikke har noget tilknyttet navn eller datatype og placeres uden for enhver metode, konstruktør eller anden blok kode.

Java tilbyder to typer initialiseringer, statiske initialiserings- og instansestartere. Lad os se, hvordan vi kan bruge hver af dem.

8.1. Instans initialisering

Vi kan bruge disse til at initialisere instansvariabler.

Lad os give en bruger en værdi for at demonstrere id ved hjælp af en instans initialisering i vores Bruger klasse:

{id = 0; }

8.2. Statisk initialiseringsblok

En statisk initialisering eller statisk blok - er en blok med kode, der bruges til at initialisere statisk felter. Med andre ord er det en simpel initialisering, der er markeret med nøgleordet statisk:

privat statisk Stringforum; statisk {forum = "Java"; }

9. Initialiseringsrækkefølge

Når vi skriver kode, der initialiserer forskellige typer felter, skal vi selvfølgelig holde øje med initialiseringsrækkefølgen.

I Java er rækkefølgen for initialiseringserklæringer som følger:

  • statiske variabler og statiske initialiserere i rækkefølge
  • instansvariabler og instansinitialiserere i rækkefølge
  • konstruktører

10. Objektets livscyklus

Nu hvor vi har lært at erklære og initialisere objekter, lad os opdage, hvad der sker med objekter, når de ikke er i brug.

I modsætning til andre sprog, hvor vi skal bekymre os om objektdestruktion, tager Java sig af forældede objekter gennem sin affaldssamler.

Alle objekter i Java er gemt i vores programs hukommelse. Faktisk repræsenterer bunken en stor pool af ubrugt hukommelse, der er allokeret til vores Java-applikation.

På den anden side er garbage collector er et Java-program, der tager sig af automatisk hukommelsesstyring ved at slette objekter, der ikke længere er tilgængelige.

For at et Java-objekt kan nås, skal det støde på en af ​​følgende situationer:

  • Objektet har ikke længere nogen henvisninger, der peger på det
  • Alle referencer, der peger på objektet, er uden for omfanget

Afslutningsvis oprettes et objekt først fra en klasse, normalt ved hjælp af nøgleordet ny. Så lever objektet sit liv og giver os adgang til dets metoder og felter.

Endelig, når det ikke længere er nødvendigt, ødelægger affaldssamleren det.

11. Andre metoder til oprettelse af objekter

I dette afsnit tager vi et kort kig på andre metoder end ny nøgleord for at oprette objekter, og hvordan man anvender dem, specifikt refleksion, kloning og serialisering.

Refleksion er en mekanisme, vi kan bruge til at inspicere klasser, felter og metoder i løbetid. Her er et eksempel på at skabe vores Bruger objekt ved hjælp af refleksion:

@Test offentlig ugyldig nårInitializedWithReflection_thenInstanceIsNotNull () kaster undtagelse {Bruger bruger = User.class.getConstructor (String.class, int.class) .newInstance ("Alice", 2); assertThat (bruger) .isNotNull (); }

I dette tilfælde bruger vi refleksion til at finde og påkalde en konstruktør af Bruger klasse.

Den næste metode, kloning, er en måde at oprette en nøjagtig kopi af et objekt på. Til dette, vores Bruger klasse skal implementere Klonabel grænseflade:

public class User implementerer Cloneable {// ...}

Nu kan vi bruge klon () metode til at oprette en ny klonetBruger objekt, der har de samme egenskabsværdier som bruger objekt:

@Test offentlig ugyldig nårCopiedWithClone_thenExactMatchIsCreated () kaster CloneNotSupportedException {Bruger bruger = ny bruger ("Alice", 3); User clonedUser = (User) user.clone (); assertThat (clonedUser) .isEqualTo (bruger); }

Vi kan også bruge sun.misc. usikker klasse til at tildele hukommelse til et objekt uden at ringe til en konstruktør:

Bruger u = (Bruger) unsafeInstance.allocateInstance (User.class);

12. Konklusion

I denne vejledning dækkede vi initialisering af felter i Java. Vi opdagede forskellige datatyper i Java og hvordan man bruger dem. Vi gennemgik også flere måder at skabe objekter i Java på.

Den fulde implementering af denne vejledning kan findes på Github.