java.lang.ClassCastException套接字readObject

时间:2011-12-11 12:21:00

标签: java class exception casting

大家好我在我的控制台上遇到这个问题,但有时只出现..并不总是.. 如果可能的话,我希望得到你的帮助,谢谢

错误:

Exception in thread "Thread-2" java.lang.ClassCastException: cannot assign instance of java.lang.String to field Element.posElement of type java.awt.Point in instance of Personagem
    at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(Unknown Source)
    at java.io.ObjectStreamClass.setObjFieldValues(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at LaunchCliente$receberDoServidor.run(LaunchCliente.java:332)

这是我的代码,当我试图读取对象时:

Object a = inputStream.readObject();


if(a instanceof Mapa){
    Mapa novo = (Mapa) a;
    if(launchJogo.getListaObstaculos().size() == 0)
    launchJogo.setLista(novo.getListaObstaculos());
    launchJogo.setListaPers(novo.getListaPersonagens());
    launchJogo.setElements(novo.getElements());
    launchJogo.getFrame().pack();
}
else if(a instanceof logout){
    if(launchJogo != null)
    launchJogo.getFrame().dispose();
    novo.close();
}
else if(a instanceof updateList){
    Vector<String> novo = ((updateList) a).getUpdateList();
    if(novo.size() != 0){
        if(!nomeUtilizador.isEnabled()){
            modeloDaLista.clear();
            arrayDeJogos = new Vector&lt;String&gt;(novo);
            for (String x : arrayDeJogos) {
                modeloDaLista.addElement(x);
            }
            janela.validate();
        }
    }
    if(novo.size() == 0){
        modeloDaLista.clear();
    }
}
else if(a instanceof String){
    String b = a.toString();
    if(b.equals("COLOR:FALSE")){
        JOptionPane.showMessageDialog(c, "Essa cor já está em uso no jogo selecionado!" , "Cor já escolhida!",
        JOptionPane.WARNING_MESSAGE);
        launchJogo = null;
        cores.dispose();
        janela.setVisible(true);
    }
    else if(b.equals("CREATE:BUTTONSTART")){
        launchJogo.getOptions().showButton(true);
    }
    else if(b.equals("ACTIVE:BUTTONSTART")){
        if(!launchJogo.getOptions().isButtonEnabled()){
            launchJogo.getOptions().setBotaoState(true);
        }
    }
    else if(b.equals("COLOR:TRUE")){
        cores.dispose();
        out.writeObject(new addToAGame(corDoJogador, nomeJogador, jogoSelecionado));
        launchJogo = new LaunchJogo(launchCliente, jogoSelecionado, nomeJogador);
    }
    else if(b.equals("LAUNCH:GAME")){
        if(launchJogo != null)
        launchJogo.addPersonagemListener();
    }
}
} catch (ClassNotFoundException e) {
  System.out.println("Class not found!");
} catch (IOException e) {
  this.interrupt();
}

非常感谢你们,我会很感激帮助

3 个答案:

答案 0 :(得分:3)

错误消息告诉您在重建序列化对象时对象流遇到运行时错误。要反序列化的对象状态的字段String的值为Element.posElement ...根据您Point类的Element类的版本,它应该是Element.posElement应用程序正在使用。

问题在于您尝试读取的实际序列化对象。我怀疑在过去的某个时间您已将String字段的类型从Point更改为serialVersionId(反之亦然),并且您正在尝试反序列化由该类的其他版本与您当前使用的版本相同。

通常情况下,对象读者会抱怨版本不兼容,但我怀疑你有:    - 为您的类添加了serialVersionId个常量,以及    - 在进行更改后,Element未能更新ObjectOutputStream,使新版本与旧版本不兼容。


另一种可能性(参见@TInusTate&#39;评论)是有多个线程写入共享ObjectOutputStream实例而没有正确同步。这可能导致来自不同对象的字节混合起来&#34;。

如果你做了其他的事情,你可能会得到类似的效果:

  • 包含共享OutputStream的多个ObjectInputStream个实例。
  • 从同一{{1}}读取多个线程。

在某些情况下,解决方案是正确的同步。在其他情况下,问题是棘手的。没有任何流类本质上是线程安全的,并且多个线程在单个流上复用数据是一个难题,需要非常小心。


您将需要找到这些不兼容的序列化对象的来源,并将其删除或(以某种方式)替换它们。在将来,您需要更加小心地对可能已经序列化和持久化的类进行更改等等。

(这种问题是为什么ObjectStream序列化对于持久化状态可能会有问题的原因之一。)

答案 1 :(得分:1)

错误很明显。

cannot assign instance of java.lang.String 
  to field Element.posElement of type java.awt.Point

在发生错误的位置,您正在尝试分配一个字符串,其中存在“awt.Point”。

糟糕的是,我不确定您粘贴的代码中存在的问题。 检查LaunchCliente.java的第332行。

您应该能够调试问题并确定它是哪一行。

答案 2 :(得分:0)

前几点

  1. 您没有“Persongem的实例”
  2. 您没有捕获ClassCastException。可以用尽可能多的信息捕获它。
  3. 问题在于您的类的序列化版本。对于至少一个数据(丢失数据/行),它至少已经更改了一次。
  4. 线程确实使事情变得复杂。围绕它进行测试。
  5. 解决方案:您可以做的就是识别数据。疏远/纠正/记录并在这种情况下安全地失败。