4

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
2
  • sunil, see my answer for a detailed explanation of why you get different String representations of your serialized and deserialzed objects. Commented Apr 12, 2015 at 7:20
  • 1
    You're not printing the contents of the byte arrays. Commented Apr 12, 2015 at 7:33

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

10 Comments

Still doesn't explain why the hashcode value printed in the output is different? If the array being serialized is the same as the one being de-serialized, shouldn't the hashcode be equal?
Because arrays do not override hashCode() and equals() methods in Java.
@Crazyjavahacking Are you sure? After all, arrays must be internally implemented using a class.
@Crazyjavahacking Well, if they don't override equals and hashCode, it's all the more reason to believe that they are using the default implementaiton of the hashcode method which explains why we get two different values in the output. See my answer.
@Crazyjavahacking See this. stackoverflow.com/questions/2267790/…
|
2

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

6 Comments

getClass().getName() returns [B actually.
@EJP. Agreed. Edited.
The reason the hashcode is different is because the object is different. A different object must be loaded into a different address, but that's irrelevant.
But not correctly. It should read 'Because the deserialized object is distinct from the serialized object, it will therefore have a different hashcode, and therefore a different output from toString().
@EJP Agreed. But I guess this was indirectly implied from the two statements 1. The default hashCode method will be used and 2. The serialized object will be loaded into a different address when de-serialized. Thus, implying that the objects are distinct.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.