Brugerdefineret serialisering: writeObject og readObject
Tilsidesæt writeObject og readObject til kryptering, komprimering eller brugerdefineret felthåndtering.
Brugerdefineret serialisering: writeObject og readObject er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.
Når standardserialisering ikke er nok
Standardserialisering gemmer alle ikke-transient-felter, som de er. Nogle gange har du brug for kryptering, komprimering eller en anden repræsentation. Det er her, hook-metoderne writeObject og readObject kommer ind i billedet.
Deklarering af writeObject
Tilføj en private void writeObject(ObjectOutputStream oos)-metode. Java kalder den i stedet for standardmekanismen. Du bestemmer præcis, hvad der skrives.
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); // write non-transient fields normally
oos.writeUTF(encrypt(this.secret)); // write encrypted secret
}Deklarering af readObject
Tilføj en private void readObject(ObjectInputStream ois)-metode. Java kalder den under deserialisering. Du læser dataene i præcis den samme rækkefølge, som du skrev dem.
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // restore non-transient fields
this.secret = decrypt(ois.readUTF()); // decrypt and restore
}Rækkefølgen er vigtig
Alt, du skriver i writeObject, skal læses tilbage i samme rækkefølge i readObject. En forkert rækkefølge forårsager en StreamCorruptedException.
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.writeInt(version);
oos.writeUTF(data);
}
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
this.version = ois.readInt(); // same order
this.data = ois.readUTF();
}Komprimering af data under serialisering
Pak strømmen ind i GZIPOutputStream i writeObject for at komprimere store felter, og brug derefter GZIPInputStream i readObject til at dekomprimere dem.
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (GZIPOutputStream gz = new GZIPOutputStream(bos)) {
gz.write(largePayload.getBytes());
}
oos.writeObject(bos.toByteArray());
}readResolve-hooket
readResolve() kaldes efter deserialisering. Returnér et erstatningsobjekt — det er nyttigt for singletoner og enum-typer, så der kun findes én instans efter deserialisering.
public class AppConfig implements Serializable {
private static final AppConfig INSTANCE = new AppConfig();
private AppConfig() {}
public static AppConfig getInstance() { return INSTANCE; }
private Object readResolve() { return INSTANCE; } // return singleton
}writeReplace-hooket
writeReplace() kaldes før serialisering. Returnér et andet objekt, der skal serialiseres i stedet — det er nyttigt til proxymønstre og serialiseringssurrogater.
private Object writeReplace() {
return new UserProxy(this.id); // serialize a lightweight proxy
}Validering af felter i readObject
Du kan tilføje valideringslogik i readObject for at afvise ugyldige eller manipulerede data som en del af en strategi med flere forsvarslag.
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
if (age < 0 || age > 150) {
throw new InvalidObjectException("Invalid age: " + age);
}
}Håndtering af versionsændringer
Brug et versionsfelt i writeObject, så readObject kan håndtere både gamle og nye formater på en smidig måde under migreringer.
private static final int SERIAL_VERSION = 2;
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeInt(SERIAL_VERSION);
if (SERIAL_VERSION >= 2) oos.writeUTF(email); // new field
}
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
int v = ois.readInt();
if (v >= 2) this.email = ois.readUTF();
}Serialiseringsproxymønsteret
En robust tilgang er at skrive en privat static indre klasse, der gemmer den mindst mulige tilstand, og derefter bruge writeReplace til at skrive proxyen og dens readResolve til at genskabe originalen.
Ydeevneovervejelser
Tilpasset serialisering medfører ekstraomkostninger fra metodekald, men kan reducere datamængden betydeligt. Mål ydeevnen, før du optimerer; brug Externalizable for maksimal kontrol.
Hurtigt tjek
Hvilken sammenhæng skal der være mellem rækkefølgen i writeObject og readObject?
Opsummering
Tilsidesæt writeObject og readObject til kryptering, komprimering eller tilpassede formater. Brug readResolve til singletoner. Læs altid i den samme rækkefølge, som du skriver.
Lær Java med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 104
- Lektioner
- 374
Ofte stillede spørgsmål
Er lektionen “Brugerdefineret serialisering: writeObject og readObject” gratis?
Ja — hele teksten til “Brugerdefineret serialisering: writeObject og readObject” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Brugerdefineret serialisering: writeObject og readObject”?
Tilsidesæt writeObject og readObject til kryptering, komprimering eller brugerdefineret felthåndtering. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Java Academy?
Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Brugerdefineret serialisering: writeObject og readObject”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Java Academy-lektion?
Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Grundlæggende Java-serialisering
- transient-felter og serialVersionUID
- Brugerdefineret serialisering: writeObject og readObject
- Moderne alternativer: JSON og Protocol Buffers