Avatar billede langthjem Nybegynder
22. april 2009 - 11:21 Der er 12 kommentarer og
1 løsning

Exception ved readObject() med en ArrayList<>

Jeg har denne metode som skal loade et ArrayList<Person> fra en fil jeg har gemt med ObjectOutputStream. Filen bliver rigtigt gemt, men når jeg kører nedenstående metode får jeg følgende exception: incompatible types - found java.lang.Object but expected java.util.ArrayList<Person>

Jeg er godt med på at det er fordi den ikke kan se at det er en ArrayList, men hvordan tvinger jeg den til at lave objektet om?
 
public void loadFromFile() throws IOException
{
    FileInputStream f = new FileInputStream("addressbook.dat");
    ObjectInputStream s = new ObjectInputStream(f);
       
    persons = s.readObject();
}
Avatar billede arne_v Ekspert
22. april 2009 - 15:04 #1
persons = (ArrayList<Person>)s.readObject();
Avatar billede arne_v Ekspert
22. april 2009 - 15:05 #2
Hvis de filer skal gemmes i lidt laengere tid, saa ville jeg bruge XML serialisering fremfor den binaere serialisering.

Du kan komme i problemer hvis du aendrer i definitionen af Person klassen.
Avatar billede langthjem Nybegynder
22. april 2009 - 18:02 #3
Den løsning du foreslår har jeg prøvet uden held.
Har du måske et link til en nem/god måde at bruge XML serialisering?
Avatar billede langthjem Nybegynder
22. april 2009 - 18:26 #4
Nu har jeg leget lidt med XMLEncoder. Den giver mig dog en fejl som hedder: java.lang.Exception: XMLEncoder: discarding statement ArrayList.add(Person);

Har læst nogle steder at jeg skal bruge en no-args constructor. Efter hvad jeg ved skal det vel bare være en constructor uden args som sætter alle variable til en default værdi? Eller hvad?

Er ret ny indenfor Java, så bær over med mig.
Avatar billede arne_v Ekspert
22. april 2009 - 18:54 #5
Jeg proever at lave et eksempel.
Avatar billede arne_v Ekspert
22. april 2009 - 19:11 #6
package april;

import java.io.Serializable;

public class Data implements Serializable {
    private int iv;
    private String sv;
    public Data(){
        this(0, "");
    }
    public Data(int iv, String sv) {
        this.iv = iv;
        this.sv = sv;
    }
    public int getIv() {
        return iv;
    }
    public void setIv(int iv) {
        this.iv = iv;
    }
    public String getSv() {
        return sv;
    }
    public void setSv(String sv) {
        this.sv = sv;
    }
    @Override
    public String toString() {
        return "[" + iv + "," + sv + "]";
    }
}
Avatar billede arne_v Ekspert
22. april 2009 - 19:11 #7
package april;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;

public class MultiSer {
    public static void main(String[] args) throws IOException, ClassNotFoundException, JAXBException {
        List<Data> lst = new ArrayList<Data>();
        lst.add(new Data(1, "A"));
        lst.add(new Data(2, "BB"));
        lst.add(new Data(3, "CCC"));
        // binary
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\bin.dat"));
        oos.writeObject(lst);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\bin.dat"));
        List<Data> binlst = (List<Data>)ois.readObject();
        ois.close();
        for(Data d : binlst) {
            System.out.println(d);
        }
        // old XML
        XMLEncoder xe = new XMLEncoder(new FileOutputStream("C:\\xmlencdec.xml"));
        xe.writeObject(lst);
        xe.close();
        XMLDecoder xd = new XMLDecoder(new FileInputStream("C:\\xmlencdec.xml"));
        List<Data> oldxmllst = (List<Data>)xd.readObject();
        xd.close();
        for(Data d : oldxmllst) {
            System.out.println(d);
        }
        // new XML
        JAXBContext jxbctx = JAXBContext.newInstance(Wrapper.class);
        OutputStream os = new FileOutputStream("C:\\xmljaxb.xml");
        Marshaller m = jxbctx.createMarshaller();
        m.marshal(new Wrapper(lst), os);
        os.close();
        InputStream is = new FileInputStream("C:\\xmljaxb.xml");
        Unmarshaller um = jxbctx.createUnmarshaller();
        List<Data> newxmllst = ((Wrapper)um.unmarshal(is)).getLst();
        is.close();
        for(Data d : oldxmllst) {
            System.out.println(d);
        }
    }
}

@XmlRootElement
class Wrapper {
    private List<Data> lst;
    public Wrapper() {
        this(null);
    }
    public Wrapper(List<Data> lst) {
        this.lst = lst;
    }
    public List<Data> getLst() {
        return lst;
    }
    public void setLst(List<Data> lst) {
        this.lst = lst;
    }
}
Avatar billede arne_v Ekspert
22. april 2009 - 21:43 #8
Hvis du koerer programmet og kigger paa de 2 XML filer vil du se hvorman man valgte at lave noget nyt !
Avatar billede langthjem Nybegynder
23. april 2009 - 08:38 #9
Jeg vil afprøve det og vende tilbage... tak indtil videre.
Avatar billede langthjem Nybegynder
23. april 2009 - 10:04 #10
Har leget lidt med det, og det virker. Nu er mit spørgsmål så bare; hvordan sender jeg min ArrayList til metoden?
Avatar billede arne_v Ekspert
23. april 2009 - 14:35 #11
Øh.

Jeg har brugt en ArrayList<Data> - præcis samme metode bør virke med din ArrayList<Person>.
Avatar billede langthjem Nybegynder
26. april 2009 - 12:01 #12
Ok, tak for hjælpen, smid et svar ;-)
Avatar billede arne_v Ekspert
26. april 2009 - 16:45 #13
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester