/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Objekter og Streams
Fra : Tim


Dato : 22-02-01 11:13

Antag jeg vil sende et objekt "myObj" af klassen "MyObject", som består af
en String og en int, over en stream. Jeg opretter objektet "myObj" med
int-værdi 18 og sender det på en ObjectOutputStream. Bagefter ændrer jeg
int-værdien fra 18 til 42 og sender objektet igen på den samme stream. Java
har oprettet en handle til objektet i en object/handle cache. Når man
modtager de to sendte objekter via en ObjectInputStream, får man to
objekter - begge med int-værdi 18, dvs. ændringen til 42 er gået tabt, fordi
objektet ikke blev serialiseret igen.

En løsning er selvfølgeligt at oprette et nyt objekt i stedet for at
modificere det gamle, men det er ikke en mulighed i min anvendelse. Jeg har
set, at man kan slette object/handle cache med "reset", men jeg tror ikke
det er den bedste løsning.

Nogen ideer?

Tim




 
 
Morten Nedertoft (23-02-2001)
Kommentar
Fra : Morten Nedertoft


Dato : 23-02-01 07:42

Tim wrote:
>
> Antag jeg vil sende et objekt "myObj" af klassen "MyObject", som består af
> en String og en int, over en stream. Jeg opretter objektet "myObj" med
> int-værdi 18 og sender det på en ObjectOutputStream. Bagefter ændrer jeg
> int-værdien fra 18 til 42 og sender objektet igen på den samme stream. Java
> har oprettet en handle til objektet i en object/handle cache. Når man
> modtager de to sendte objekter via en ObjectInputStream, får man to
> objekter - begge med int-værdi 18, dvs. ændringen til 42 er gået tabt, fordi
> objektet ikke blev serialiseret igen.
>
> En løsning er selvfølgeligt at oprette et nyt objekt i stedet for at
> modificere det gamle, men det er ikke en mulighed i min anvendelse. Jeg har
> set, at man kan slette object/handle cache med "reset", men jeg tror ikke
> det er den bedste løsning.
>
> Nogen ideer?

Har du overskrevet Object.hashCode og Object.equals, saa de passer til
API "kontrakten"?
Cachen anvender sandsynligvis en java.util.HashMap.

mvh. Morten N

Morten Nedertoft (23-02-2001)
Kommentar
Fra : Morten Nedertoft


Dato : 23-02-01 08:11

Morten Nedertoft wrote:
>
> Tim wrote:
> >
> > Antag jeg vil sende et objekt "myObj" af klassen "MyObject", som består af
> > en String og en int, over en stream. Jeg opretter objektet "myObj" med
> > int-værdi 18 og sender det på en ObjectOutputStream. Bagefter ændrer jeg
> > int-værdien fra 18 til 42 og sender objektet igen på den samme stream. Java
> > har oprettet en handle til objektet i en object/handle cache. Når man
> > modtager de to sendte objekter via en ObjectInputStream, får man to
> > objekter - begge med int-værdi 18, dvs. ændringen til 42 er gået tabt, fordi
> > objektet ikke blev serialiseret igen.
> >
> > En løsning er selvfølgeligt at oprette et nyt objekt i stedet for at
> > modificere det gamle, men det er ikke en mulighed i min anvendelse. Jeg har
> > set, at man kan slette object/handle cache med "reset", men jeg tror ikke
> > det er den bedste løsning.
> >
> > Nogen ideer?
>
> Har du overskrevet Object.hashCode og Object.equals, saa de passer til
> API "kontrakten"?
> Cachen anvender sandsynligvis en java.util.HashMap.

Jeg er blevet i tvivl om min egen holdning til dette.
Hvis to objekter med det samme indhold skrives til en objekt-stream, og
her faar den samme handle, saa faar man jo kun et objekt ud af
objekt-stream'en - det er ikke smart.
Jeg tror, at jeg vil studere API'en lidt.

mvh. Morten N

Morten Nedertoft (23-02-2001)
Kommentar
Fra : Morten Nedertoft


Dato : 23-02-01 08:32

Morten Nedertoft wrote:
>
> Morten Nedertoft wrote:
> >
> > Tim wrote:
> > >
> > > Antag jeg vil sende et objekt "myObj" af klassen "MyObject", som består af
> > > en String og en int, over en stream. Jeg opretter objektet "myObj" med
> > > int-værdi 18 og sender det på en ObjectOutputStream. Bagefter ændrer jeg
> > > int-værdien fra 18 til 42 og sender objektet igen på den samme stream. Java
> > > har oprettet en handle til objektet i en object/handle cache. Når man
> > > modtager de to sendte objekter via en ObjectInputStream, får man to
> > > objekter - begge med int-værdi 18, dvs. ændringen til 42 er gået tabt, fordi
> > > objektet ikke blev serialiseret igen.
> > >
> > > En løsning er selvfølgeligt at oprette et nyt objekt i stedet for at
> > > modificere det gamle, men det er ikke en mulighed i min anvendelse. Jeg har
> > > set, at man kan slette object/handle cache med "reset", men jeg tror ikke
> > > det er den bedste løsning.
> > >
> > > Nogen ideer?
> >
> > Har du overskrevet Object.hashCode og Object.equals, saa de passer til
> > API "kontrakten"?
> > Cachen anvender sandsynligvis en java.util.HashMap.
>
> Jeg er blevet i tvivl om min egen holdning til dette.
> Hvis to objekter med det samme indhold skrives til en objekt-stream, og
> her faar den samme handle, saa faar man jo kun et objekt ud af
> objekt-stream'en - det er ikke smart.
> Jeg tror, at jeg vil studere API'en lidt.

Jeg har nu kigget i kildekoden til ObjectOutputStream.
Den bruger heldigvis ikke java.util.HashMap til at finde en 'handle',
saa du behoever ikke at overskrive hashCode og equals.
Jeg kan ikke se anden udvej end at 'reset'-te object-stroemmen.

mvh. Morten N

Niels Ull Harremoës (27-02-2001)
Kommentar
Fra : Niels Ull Harremoës


Dato : 27-02-01 22:07


"Tim" <trigger@get2net.dk> skrev i en meddelelse
news:tB5l6.65$jD1.2977@news.get2net.dk...
> Antag jeg vil sende et objekt "myObj" af klassen "MyObject", som består af
> en String og en int, over en stream. Jeg opretter objektet "myObj" med
> int-værdi 18 og sender det på en ObjectOutputStream. Bagefter ændrer jeg
> int-værdien fra 18 til 42 og sender objektet igen på den samme stream.
Java
> har oprettet en handle til objektet i en object/handle cache. Når man
> modtager de to sendte objekter via en ObjectInputStream, får man to
> objekter - begge med int-værdi 18, dvs. ændringen til 42 er gået tabt,
fordi
> objektet ikke blev serialiseret igen.

Som du er klar over, er problemet at du bruger det samme objekt to gange -
du bliver nødt til at resette ind i mellem - eller også er
ObjectInput/OutputStream bare ikke den rigtige løsning for dig. De streams
er beregnet til at sende en hel datastruktur inkl. referencer mellem
objekterne.

Prøv at tænke på, hvad der ville ske, hvis du også serialiserede en
reference til objektet, fx

ObjectOutputStream oos = ...
MyObject obj1 = new MyObject;
obj1.name = "Hello"
obj1.intVal = 18;

MyOtherObject obj2 = new MyOtherObject();
obj2.ref = obj1;

oos.writeObject(obj1);
oos.writeObject(obj2);
obj1.intVal = 6*9;
oos.writeObject(obj1);

....
ObjectInputStream ois = ...
MyObject obj1 = (MyObject)ois.readObject();
MyObject obj2 = (MyOtherObject)new MyObject;
MyObject obj3 = (MyObject)new MyObject;

Hvad ville du nu forvente at det genindlæste obj2 refererede til? obj1 eller
obj3? Ligegyldig hvad du vælger, så får du ikke den samme datastruktur ud,
som du puttede ind.



> En løsning er selvfølgeligt at oprette et nyt objekt i stedet for at
> modificere det gamle, men det er ikke en mulighed i min anvendelse. Jeg
har
> set, at man kan slette object/handle cache med "reset", men jeg tror ikke
> det er den bedste løsning.

Så vidt jeg kan se, er det lige præcis reset, du har brug for. Alternativt
skal du bare ikke bruge Object Streams til den del af din lagring.
En anden mulig løsning er, hvis dine MyObject objekter kun refereres til fra
een "ejerinstans", at lade ejeren markere dem som trasient og så selv skrive
og læse dem i writeObject/readObject metoder.

Endelig kan du muligvis lave noget smart med writeReplace() og
readResolve() - men det afhnænger meget af, hvor mange referencer du har til
hvert MyObject.

> Nogen ideer?
>
> Tim




Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408929
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste