1

It is possible to make a generic serialize method? In which I can pass any object and serialize it acording to it's class? Something like this:

public void serializeObject(T Object) {

    try (ObjectOutputStream clientOutputStream = new ObjectOutputStream(socketConnection.getOutputStream());) {

        clientOutputStream.writeObject(Object);

        System.out.println(user.getUsername());

        //clientOutputStream.close();

    } catch (Exception e) {
        System.out.println(e);
    }
}
Octavian Marian
  • 65
  • 3
  • 11
  • 3
    Now the question is: why would you need generics for that? `public void serializeObject(Serializable object)` would be enough. – Tom Apr 12 '17 at 11:37
  • Because I have a lot of classes that need to be serialized and send to a server, then modified and send back to client and deserialized there. So I didn't want to write these methods for all of them. – Octavian Marian Apr 12 '17 at 11:40
  • You don't need to. All your objects implement `Serializable` so using that as the parameter type is find. And if you really want to use generics, then use `Serializable` as the upper bound for `T`. – Tom Apr 12 '17 at 11:44
  • 1
    Use a library built for this purpose, eg [jackson](https://github.com/FasterXML/jackson), if you want ease of use and can use standard formats like JSON or XML. Jackson will automatically serialize and deserialize objects you give it. – Jure Kolenko Apr 12 '17 at 11:44
  • 1
    To expand on what Tom says, you'll notice that the `writeObject` method accepts *any* `Object`, not an object of any particular type. So there isn't anything that you need to do to write the method differently for each class. Java automatically checks what class the object is and serializes that. Limiting yourself to `Serializable` merely prevents exceptions from being thrown. – RealSkeptic Apr 12 '17 at 11:46
  • @RealSkeptic *"Limiting yourself to Serializable merely prevents exceptions from being thrown."* Correct, but it is still possible that a field my not be serializable itself. This still can cause an exception (just a note). – Tom Apr 12 '17 at 11:50
  • @RealSkeptic Ok, but this rise my next question: what if I want to deserialize that Object? Can I make some kind of upcast to it's specific class? What I mean is: I have to make a specific deserialization method for each class? – Octavian Marian Apr 12 '17 at 14:18

3 Answers3

1

You could build something like this using reflection. You inspect the object to dump; retrieve all its fields; and then try to serialize those. Of course, that will turn out to be hard, because you have to detect "cycles", to avoid serializing A pointing to B pointing to C pointing back to A for example.

And you would have to understand all the subtle issues, like having inner objects and whatnot. Seriously: this is hard.

Then: serialization isn't the even real problem in this challenge!

The problem is to rebuild objects of generic classes from the serialized data.

So, the real answer is: this is an advanced task where you can easily waste many hours of time. Meaning: you rather step back and clarify your requirements. Instead of re-inventing the wheel, you should use your energy to find an existing framework that matches your needs. Start reading here.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Couldn't agree more on this part '..you can easily waste many hours of time'. That is indeed a challenge that works best with primitive object types. But it also unleashes a treasure trove of some interesting aspects of serialization and object streams otherwise hidden. – Rajeev Sreedharan Apr 12 '17 at 12:19
  • Sure. I think one could learn *a lot* when trying to implement this. Question is: does one have that time? And is there a plan B when thinks will not work out in the end (which, well, they won't) – GhostCat Apr 12 '17 at 12:26
0

Try out-of-the-box mappers, e.g. Jackson JSON mapper

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
String jsonInString = mapper.writeValueAsString(yourObject);

YourClass yourObject = mapper.readValue(jsonInString, YourClass.class);
Tomas F.
  • 610
  • 1
  • 6
  • 13
0

It is not possible to create Generic Serializer. Instead you can convert your object to common object that supports serialization.

For example, You can convert your object to String using GSON and serialize the string. During deserialization you pass the deserialized string object to gson to get your object back.

public <T> void serializeObject(T object) throws Exception{
    Gson gson = new Gson();
    String stringToSerialize = gson.toJson(object).toString();
    try(ObjectOutputStream oStream = new ObjectOutputStream(new FileOutputStream("generic.ser"))){
        oStream.writeObject(stringToSerialize);
    }
}

public <T> T deSerializeObject(Class className) throws Exception{
    Gson gson = new Gson();
    try(ObjectInputStream iStream = new ObjectInputStream(new FileInputStream("generic.ser"))){
        String object = (String)iStream.readObject();
        return (T) gson.fromJson(object,className);
    }
}

Ofcourse this solution comes with performance degrade. It completely depends on our requirement.

Vijayakumar
  • 303
  • 4
  • 10