javaserializablearraystoreexception

A problem with Serializable and ArrayStoreException


Let's suppose I have three classes: SerClass, SerClassA and SerClassB. SerClass is abstract and the other two classes are its non-abstract subclasses. All of them implements the Serializable interface.

Since those classes implement the Serializable interface, I can write them on files. Let's suppose again that in a specific directory there are a number of files, each one storing a SerClass object. If I wanted to load them back, I would write something like:

    public static SerClass[] loadArray(File directory) {
        Vector<SerClass> support = new Vector<SerClass>();

        for( File file : directory.listFiles() )
            support.add(loadObject(file));
        
        return convert(support);
    }
    
    // Utility methods
    public static <T> T[] convert(Vector<T> v) {
        if( v.size() == 0 )     return null;
        T example = null;
        for(T element : v)  
            if( element != null )   { example = element;        break; }
        
        @SuppressWarnings("unchecked")
        T[] output = (T[]) Array.newInstance(example.getClass(), v.size());
        for(int i=0 ; i<output.length; i++)     output[i] = v.get(i);
        return output;
    }
    public static <T extends Serializable> T loadObject(File file) {
        T output = null;
        ObjectInputStream objectStream = null;
        
        try {   objectStream = new ObjectInputStream(new FileInputStream(file));
            }   catch (FileNotFoundException e) {               e.printStackTrace();            }
                catch (SecurityException e) {                   e.printStackTrace();            }
                catch (StreamCorruptedException e) {            e.printStackTrace();            }
                catch (NullPointerException e) {                e.printStackTrace();            }
                catch (IOException e) {                         e.printStackTrace();            }
        
        try {   output = (T) objectStream.readObject();
            }   catch (ClassNotFoundException e) {              e.printStackTrace();            }
                catch (InvalidClassException e) {               e.printStackTrace();            }
                catch (StreamCorruptedException e) {            e.printStackTrace();            }
                catch (OptionalDataException e) {               e.printStackTrace();            }
                catch (IOException e) {                         e.printStackTrace();            }
        
        try {   objectStream.close();
            }   catch (IOException e) {                         e.printStackTrace();            }
        
        return output;
    }

I checked the utility methods and they works as they should. The method loadArray() however causes a java.lang.ArrayStoreException: when it passes the Vector to the method convert(), the latter one creates an array that stores either SerClassA or SerClassB, depending from which class is the first non-null element found.

I need to load both types of SerClass in a single array. Any ideas on how to do it?


Solution

  • Use the toArray method of the Vector class instead of your convert method:

     public static SerClass[] loadArray(File directory) {
        Vector<SerClass> support = new Vector<SerClass>();
    
        for( File file : directory.listFiles() )
            support.add(loadObject(file));
        
        return support.toArray(new SerClass[support.size()]);
    }