Java 追加对象OutputStream时的ClassCastException

Java 追加对象OutputStream时的ClassCastException,java,serialization,classcastexception,java-io,Java,Serialization,Classcastexception,Java Io,我一直在尝试做一个需要可追加ObjectOutputStream的小项目。 我经历了几个解决方案,我发现它一开始似乎解决了我的问题。但随着我项目的进一步发展,我开始遇到意想不到的异常。 以下是我的课程 public class PPAccount implements Serializable { private Profile profile; private String email; private float accountBal; private boo

我一直在尝试做一个需要可追加ObjectOutputStream的小项目。 我经历了几个解决方案,我发现它一开始似乎解决了我的问题。但随着我项目的进一步发展,我开始遇到意想不到的异常。 以下是我的课程

public class PPAccount implements Serializable
{
    private Profile profile;
    private String email;
    private float accountBal;
    private boolean isActivated;
    private String activationCode;
    private ArrayList<Transaction> transactions;

    //a few functions   
}
public class PPRestrictedAccount extends PPAccount {
    private String parentEmail;
    private float withdrawLimit;

        //a few functions
}
public class PPBusinessAccount extends PPAccount {
    private ArrayList <PPRestrictedAccount> accountOperators;

        //a few functions
}
public class PPStudentAccount extends PPAccount {
    private String parentEmail;

        //a few functions
}
堆栈跟踪

java.lang.ClassCastException: java.lang.String cannot be cast to java.io.ObjectStreamClass
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at java.util.ArrayList.readObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(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.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 in.msitprogram.iiit.paypal.persistance.DataStore.lookupAccount(DataStore.java:50)
    at in.msitprogram.iiit.paypal.persistance.DataStore.writeAccount(DataStore.java:131)
    at in.msitprogram.iiit.paypal.console.PPNewAccountScreen.show(PPNewAccountScreen.java:78)
    at in.msitprogram.iiit.paypal.console.MainMenu.show(MainMenu.java:42)
    at in.msitprogram.iiit.paypal.PPSystem.main(PPSystem.java:17)
Exception in thread "main" java.lang.NullPointerException
    at in.msitprogram.iiit.paypal.persistance.DataStore.lookupAccount(DataStore.java:66)
    at in.msitprogram.iiit.paypal.persistance.DataStore.writeAccount(DataStore.java:131)
    at in.msitprogram.iiit.paypal.console.PPNewAccountScreen.show(PPNewAccountScreen.java:78)
    at in.msitprogram.iiit.paypal.console.MainMenu.show(MainMenu.java:42)
    at in.msitprogram.iiit.paypal.PPSystem.main(PPSystem.java:17)
lookUpAccount
从流中读取,而
writeAccount
写入流,下面是代码:

public static PPAccount lookupAccount(String email) throws IOException, ClassNotFoundException 
    {
        PPAccount account = null; //initialize it after reading from file
        // write code to open the files, read
        PPAccount foundAccount=null;
        ObjectInputStream ois=null;
        FileInputStream fis=null;
        File ff = new File(PPConstants.AllAccountDetails);
        if(!ff.exists())
        {
            //System.out.println("Required file not found");
            return null;
        }
        try
        {
            fis=new FileInputStream(PPConstants.AllAccountDetails);
            ois = new ObjectInputStream(fis);
            while(fis.available()>0 && foundAccount==null)
            {
                //Object o=null;
                PPAccount ppa=null;
                try
                {
                    ppa = (PPAccount)ois.readObject();
                    if(ppa==null)
                        return null;
                    System.out.println(ppa);
                }

                catch(ClassCastException cce)
                {
                    System.out.println("Class cast exception "+cce.getCause());
                    cce.printStackTrace();  
                }
                if(email.equals(ppa.getEmail()))
                {
                    foundAccount=ppa;
                    break;
                }
                if(ppa instanceof PPBusinessAccount)
                {
                    PPBusinessAccount ppba = (PPBusinessAccount)ppa;
                    ArrayList<PPRestrictedAccount> alist=ppba.getAccountOperators();
                    if(alist==null)
                        continue;
                    Iterator<PPRestrictedAccount> it = alist.iterator();
                    while(it.hasNext())
                    {
                        PPRestrictedAccount ppr=(PPRestrictedAccount) it.next();
                        System.out.println(ppr);
                        if(email.equals(ppr.getEmail()))
                        {
                            foundAccount = ppr;
                            break;
                        }
                    }//iterators while loop
                }//if it is a businessAccount
            }//outer while  
        }//try
        finally
        {
            if(ois!=null)
                ois.close();
            if(fis!=null)
                fis.close();
        }   
        return foundAccount;
    }
    public static void writeAccount(PPAccount account,Boolean append) throws IOException, ClassNotFoundException, DuplicateAccountException
    {
        ObjectOutputStream oos=null;
        FileOutputStream fos=null;
        try
        {
            if(!append)
            {
                fos= new FileOutputStream(PPConstants.AllAccountDetails);
                oos = new ObjectOutputStream(fos);
                //System.out.println("Not Appending");
                oos.writeObject(account);
            }
            else
            {
                File ff = new File(PPConstants.AllAccountDetails);
                if(!ff.exists())
                {
                    System.out.println("Required file not found");
                    return;
                }
                PPAccount aa=lookupAccount(account.getEmail());
                if(aa!=null)
                    throw new DuplicateAccountException("An Account already exits with this email-ID");
                oos = new AppendingObjectOutputStream(new FileOutputStream(PPConstants.AllAccountDetails,append));
                oos.writeObject(account);
            }
        }
        finally
        {
            if(oos!=null)
                oos.close();
            if(fos!=null)
                fos.close();
        }

    }
public static PPAccount lookupAccount(字符串电子邮件)引发IOException,ClassNotFoundException
{
PPAccount account=null;//从文件读取后初始化它
//编写代码打开文件,读取
PPAccount foundAccount=null;
ObjectInputStream ois=null;
FileInputStream fis=null;
文件ff=新文件(PPConstants.AllAccountDetails);
如果(!ff.exists())
{
//System.out.println(“未找到所需文件”);
返回null;
}
尝试
{
fis=新文件输入流(PPConstants.AllAccountDetails);
ois=新的ObjectInputStream(fis);
而(fis.available()>0&&foundAccount==null)
{
//对象o=null;
PPAccount ppa=null;
尝试
{
ppa=(PPAccount)ois.readObject();
如果(ppa==null)
返回null;
系统输出打印LN(ppa);
}
捕获(ClassCastException cce)
{
System.out.println(“类强制转换异常”+cce.getCause());
cce.printStackTrace();
}
if(email.equals(ppa.getEmail()))
{
foundAccount=ppa;
打破
}
if(PPBusinessAccount的ppa实例)
{
PPBusinessAccount ppba=(PPBusinessAccount)ppa;
ArrayList alist=ppba.getAccountOperators();
if(alist==null)
继续;
Iterator it=alist.Iterator();
while(it.hasNext())
{
PPRestrictedAccount ppr=(PPRestrictedAccount)it.next();
系统输出打印项次(ppr);
if(email.equals(ppr.getEmail()))
{
foundAccount=ppr;
打破
}
}//循环时的迭代器
}//如果是商业账户
}//外部时间
}//试一试
最后
{
如果(ois!=null)
ois.close();
如果(fis!=null)
fis.close();
}   
归还账户;
}
公共静态void writeAccount(pAccount帐户,布尔追加)引发IOException、ClassNotFoundException、DuplicateAccountException
{
ObjectOutputStream oos=null;
FileOutputStream=null;
尝试
{
如果(!追加)
{
fos=新的FileOutputStream(PPConstants.AllAccountDetails);
oos=新对象输出流(fos);
//System.out.println(“不追加”);
oos.书面对象(账户);
}
其他的
{
文件ff=新文件(PPConstants.AllAccountDetails);
如果(!ff.exists())
{
System.out.println(“未找到所需文件”);
返回;
}
PPAccount aa=lookupAccount(account.getEmail());
如果(aa!=null)
抛出新的DuplicateAccountException(“使用此电子邮件ID的帐户已退出”);
oos=新的AppendingObjectOutputStream(新的FileOutputStream(PPConstants.AllAccountDetails,append));
oos.书面对象(账户);
}
}
最后
{
如果(oos!=null)
oos.close();
如果(fos!=null)
fos.close();
}
}
像这样试试

readObject()
返回类型的
对象
对象
,因此需要显式将它们转换为其原始类型…

例如:


PPAccount pa=(PPAccount)readObject()

您没有明确的答案,但有一些想法和事情需要尝试:

  • 堆栈跟踪包括java.util.ArrayList.readObject(未知源)
中的
,这表明在反序列化包含
ArrayList的类时出现问题。通过注释掉
私有ArrayList事务来缩小问题范围

  • 如果不使用appender生成单个文件,是否会遇到同样的问题?如果是这样,请创建两种形式的相同内容:一种带有appender,另一种不带appender。差别

  • 我确实看到另一个类似的问题,没有解决办法。还使用相同的追加器:


  • 这里的问题是,前一张海报给了你一个可附加的
    ObjectOutputStream
    让你误入歧途。
    ObjectOutputStream
    /
    ObjectInputStream
    仅尝试存储每个对象一次,然后稍后再引用已存储的对象。也就是说,在流中,如果您有一堆相同类的对象,您可以得到如下结果:

    CLASS_1_DESCRIPTION
    OBJECT_1
    REF_TO_CLASS_1
    OBJECT_2
    REF_TO_CLASS_1
    OBJECT_3
    ...
    
    ObjectInputStream
    将流转换回一组对象时,它会维护一个列表,列出已经反序列化的内容。它告诉您的错误是,它试图反序列化一个对象,读取该对象类描述的引用,但是当它在其
    CLASS_1_DESCRIPTION
    OBJECT_1
    REF_TO_CLASS_1
    OBJECT_2
    REF_TO_CLASS_1
    OBJECT_3
    ...
    
      @Override
      protected void writeStreamHeader() throws IOException {
        // do not write a header, but reset the handle list
        reset();
      }