Hvorfor bruger ArrayList forbigående lagring?
Det kan serialiseres; ArrayList
klasse tager sig bare af tingene selv, i stedet for at bruge standardmekanismen. Se på writeObject()
og readObject()
metoder i den klasse, som er en del af standard serialiseringsmekanismen.
Hvis du ser på kilden, ser du den writeObject()
gemmer ikke backing-arrayet. I stedet serialiserer den elementerne (inklusive nulværdier) én ad gangen op til size()
begrænse. Dette undgår omkostningerne ved at serialisere arrayet, og især eventuelle ubrugte slots i slutningen af arrayet. Ved deserialisering oprettes et nyt backing-array med den mindst nødvendige størrelse af readObject()
.
Hvorfor skal dette være forbigående?
Det gør det, fordi det giver brugerdefineret readObject
og writeObject
metoder, der gør et bedre job med serialisering end standarden. Specifikt skriver writeObject-metoden kun størrelsen og rækkefølgen af elementer. Dette undgår at serialisere det private array-objekt, som 1) har sin egen header og overhead, og 2) typisk er polstret med null
s. Pladsbesparelsen kan være betydelig.
Hvorfor kan denne klasse ikke serialiseres?
ArrayList
klasse som helhed kan serialiseres
1
. Object[]
kunne serialiseres direkte, men de valgte at markere det som transient
implementere serialiseringen på en anden måde.
1 - Faktisk afhænger dette af elementernes runtime-typer. For eksempel, hvis du forsøgte at serialisere en ArrayList
indeholdende Thread
referencer, så får du en runtime-undtagelse for den første ikke-nul reference.
ArrayList
implementerer Serializable
, så det kan serialiseres, det er præcis derfor, det private backing-array er transient
, så det serialiseres ikke sammen med andre data i klassen, da alt håndteres af ArrayList
's writeObject
og readObject
metoder.