Vic
Vic

Reputation: 211

Ways to serialize a class with Object field?

I've been using a class:

public class Change {
    Object affectedObj;  //takes an instance of any class
    String affectedFieldName;
    float shift;
    ...

    public void apply() {
        affectedObj.getClass().getField(affectedFieldName).setFloat(affectedObj, shift);
    }
}

which I now need to serialize. Since Object is not serializable, how can I make my class serializable?

One thing that came to my mind is to replace Object with generic <T> type:

public class Change<T> {
    T affectedObj;  //takes an instance of any class
    String affectedFieldName;
    float shift;
    ...

    public void apply() {
        affectedObj.getClass().getField(affectedFieldName).setFloat(affectedObj, shift);
    }
}

But I can't judge about the downsides of this approach. If it's a good way to go what are the pitfalls here regarding serialization?

PS

Thank you, guys, for your reply. They all were revealing and helpful to me.

Upvotes: 2

Views: 6224

Answers (3)

Boann
Boann

Reputation: 50051

There is not necessarily any problem. Object is not Serializable, but it's also not not Serializable. You can still serialize a class which declares Object fields, provided that at the moment of serialization the fields happen to be either null or they point to instances of Serializable objects. (Otherwise, serialization will fail with a NotSerializableException.)

If you really need affectedObj to be "any class", well then you do have a problem, because there are some things that cannot be serialized no matter how hard you try (open net connections, for example).

If you want to restrict affectedObj to Serializable objects, simply declare the field as type Serializable:

public class Change implements Serializable {
    Serializable affectedObj; // takes an instance of any Serializable class
    ...
}

It is not necessary to use generics for this. You can still use generics if you want it for other reasons, for example if you want users of the class to be able to set and get that field in a fully-typed way. It doesn't affect serialization however.

Upvotes: 6

David Rabinowitz
David Rabinowitz

Reputation: 30448

Making your class generic wont help you unless you restrict T to be Serializable by adding Change<T extends Serializable>, however it will restrict the types your class can accept.

Another option is to implement Externalizable but then you would need to implement both read() and write() and will have to serialize an unknown object anyway.

Is there any reason not to use a non java specific format such as json, thrift, msgpack or other?

Upvotes: 1

Mena
Mena

Reputation: 48444

It doesn't look like a bad approach, but I would definitely upper-bind your generic parameter as such:

public class Change<T extends Serializable> {
    ...
}

This will ensure you can't parametrize your class with non-serializable types.

Upvotes: 0

Related Questions