Search code examples
javaserializationreflectiontype-conversiondeserialization

Converting a String into a Constructor to make a new Object


@NotNull
public static String toString(@NotNull Object object, @NotNull Object[] variables, Class<?>... parameters) throws NoSuchMethodException {
    StringBuilder sb = new StringBuilder();
    sb.append(object.getClass().getConstructor(parameters)).append('\n');
    sb.append(object.getClass()).append(":");
    for (Object variable : variables){
        sb.append(" | ").append(variable.toString());
    }
    return sb.toString();
}

A brief explanation of the code, the toString() method uses an object, the variables of the constructor that the user wants to save, and the parameters of a constructor. This method would form the parameters in a way like this:

public User(java.lang.String,int)
class User: | username | 369172

I want to use this String format to convert the above into a new instance of the Object that was taken in using the method below:

public static Object toObject(@NotNull String formattedObject, @NotNull Object object, Class<?>... parameters){
    // The code I need to figure out.
}

I want to figure out: how to get all the variables cast into a form where I could use them to make a new instance of the object if I didn't know how many variables/parameters there are, how to use the method in the event the constructor of the Object is private, and if one of the parameters is an Object that prints out the default Object toString() method. How could I do this?

EDIT: I want to avoid using the Serialization interface


Solution

  • You are definitely reinventing the wheel

    • Java Object Serialization already does this, albeit that the serialization format is binary (and opaque).

    • Various JSON (or XML) <-> POJO binding mechanisms already do this, albeit that the serialization format can be verbose.

    (Now there are limits to what these schemes can do. For example, they cannot serialize a Thread or a Socket. But neither can your proposal ... for the same reasons. These classes have state that simply cannot be captured in a serialization.)

    But if you really want to invent the wheel, you can do it.

    • As noted, you can use reflection to access and call a public or private constructor on a non-abstract type.

    • There is also an "under the hood" Unsafe mechanism that JOS uses to create objects without invoking any constructor. Combine this with Unsafe methods for assigning values to fields.

    However, your approach implicitly assumes that the toString method returns a string that can be used later to reconstruct the object. This is not true, in general.

    • The default implementation returns a string consisting of the object's class name and its identity hashcode. (An example of the types affected by this is any array type.) You can't reconstruct an object from that.
    • And even for cases where the toString result does include the information needed for deserialization, the string format is rarely standardized. (The Collection APIs are the exception ...)

    In short, toString is not the answer.