Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializing a class with Byte Array in Java

I have a class with byte array in Java. When I serialize and deserialize the object of the class, the value of the Byte Array is changing.

How can I address this problem?

Please see the example code:

public class Test implements Serializable{

private static final long serialVersionUID = 3455892176538865707L;
public byte[] datakey;

public static void main(String[] args) {

    byte[] key=new byte[16];    
    Random rn = new Random(); //Trying to randomize the byte array to use as a cryptographic key
    rn.nextBytes(key);

    Test test = new Test();
    test.datakey=key;
    System.out.println("Byte Array Before serialization : "+test.datakey);
    test.serializeTest(test);
    Test loadedtest=test.deserializeTest();
    System.out.println("Byte Array After deserialization : "+loadedtest.datakey);


}


public void serializeTest(Test test)
{

    FileOutputStream fos;
    try {

            fos = new FileOutputStream("test.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(test);
            oos.flush();
            oos.close();;
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public Test deserializeTest()
{
    Test test=null; 
    String f="test.out";
    try
    {
            FileInputStream fis = new FileInputStream(f);
            ObjectInputStream ois = new ObjectInputStream(fis);
            test = (Test)ois.readObject();
            ois.close();
            fis.close();

    }
    catch(FileNotFoundException ex)
    {
            ex.printStackTrace();
    } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
    } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
    }

    return test;
}
}

Output of this:

Byte Array Before serialization : [B@15db9742
Byte Array After deserialization : [B@75b84c92
like image 275
sunil zacharias Avatar asked Jan 09 '23 14:01

sunil zacharias


2 Answers

The value of the byte array is not changing. You are just printing the toString() representation of the array.

The default toString() implementation from java.lang.Object will be used.

Because the initial and deserialized arrays are not the same objects (they are two independent objects with the same content), they will have different hashCode(). Arrays in Java does not override equals() and hashCode().

You should use Arrays.toString() to print the content of the array instead.

like image 166
Crazyjavahacking Avatar answered Jan 15 '23 06:01

Crazyjavahacking


When you pass an object to the System.out.println() method, the toString() method of that object will be called.

The default implementation of the toString method looks like this :

getClass().getName() + '@' + Integer.toHexString(hashCode())

In both your outputs, getClass().getName() returns [B but Integer.toHexString(hashCode()) returns different values. Now the only way this can happen is that hashCode() of the serialized object is different from that of the de-serialized object. This is exactly what happens. While not officially mentioned, the default implementation of the hashCode() seems to be returning the internal address of the object. The javadocs for the hashCode() method says this :

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

Since the serialized object will most likely be loaded into a different address when de-serialized, you get different hashCode values and thus, different outputs from toString

like image 27
Chetan Kinger Avatar answered Jan 15 '23 07:01

Chetan Kinger