Generate Java Object from toString representation [duplicate] - java

This question already has answers here:
Converting back from toString to Object
(7 answers)
How to get back an object after performing .toString() on it? [duplicate]
(4 answers)
Closed 8 years ago.
We all know how to implement toString() method. It could be slightly custom implementation and different pattern how we print the object data.
Using the generated toString, can we recreate the Object? I am not talking about Serialization here.
Let me explain a scenario, You might have an application running happily in production and your log prints these objects when you received some request and doing some operations. And some issue might have raised.
To replicate certain hard bugs, you will go back to your unit test cases/mockito to recreate the problem with similar data.
Now If I can reproduce the object from it's toString representation,
since all of it's dependency objects also implements toString, I will
be able to clear most of these scenarios.
Is there any by default plugin/tool to do the same? If not, It could be my next try-on project :)

The toString() method was designed to return a readable representation of an object, not a full representation.
If you want to marshal your object into a string that can later be unmarshalled, the usual options are XML, JSON, flat file,... Check out JAXB perhaps.
You could opt for a custom format, the only requirement being that all the information you need to reconstruct the object is in there and you write a custom parser to build the object again. If said custom format also happens to be readable, you can plug it into toString().

No, there is no general way
(Consider the case of a toString method that returns the empty string)
Your best bet is to log more details in the case of an Exception, possibly on a finer log level

No you cannot.
toString() is only intended for logging and debug purposes. It is not intended for serializing the state of an Object.
If the object in question supports serialization then go with serialization and deserialization to find out how to do this.

Related

Serialization vs toString()

Since I'm writing/reading from files, I was wondering if there's any difference or there's any best practice between directly sending objects or using their representation as strings on files which in my case I personally find it easier to handle.
So when should I serialize instead of writing/reading objects as String?
There's typically not enough information in the string representation of an object to be used to recreate it.
Java serialization "just works", but does not give you a human-readable representation, if that's what you are looking for.
Another alternative is to read / write JSON representations of your objects. There are several JSON serialization / federalization libraries for Java that are popular, including GSon and Jackson.
The answer is in the javadoc for Object.toString().
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read.
Note that it says:
concise,
informative, and
easy for a person to read.
But it does NOT say:
complete,
unambiguous, or
easy for a computer to read.
Serialization is about producing a linear (not necessarily textual) form that can be read by a computer and used to reconstruct the state of the original object.
So a typical serialization is not particularly human readable (e.g. JSON, XML, YAML) or completely unreadable (e.g. Java Object Serialization, ASN.1). But the flip-side is that the information needed to reconstruct an object should all be present, in an unambiguous form.
(There is a lot more that could be said about various kinds serialization, their properties and their utility. However, it is beyond the scope of your question.)
Does this preclude toString() from being used for serializing data?
No, it doesn't.
But if you take that approach, you need to code your toString() methods carefully to make sure that what they produce is complete and unambiguous. Then you need to write a corresponding method to parse the toString() output and create an new object from it.
... or using their representation as strings on files which in my case I personally find it easier to handle.
I think that as you write larger and more complicated programs, you will get to the stage where that kind of code is tedious and time consuming to write, test and maintain.
Serialization allows you to convert the state of an object into a stream of bytes, which can then be saved to a file on the local disk, sent over the network to any other machine, or saved to the Database. Deserialization allows you to reverse the process, which means to reconvert the serialized byte stream into an object again. It's important to know that numbers or other types aren't as easy to write to files or treats as Strings. However, their initial states are not guaranteed to be maintained without being serialized.
Thus, it is convenient to use Strings, for simpler situations, which is not necessarily important to have a serialization, such as a college project. However, it is not recommended that this process be done, as there are other better solutions.

toString method in Java benefits [duplicate]

This question already has answers here:
Why must I override toString method instead of just creating another method?
(13 answers)
Closed 4 years ago.
What is the benefit in using toString method in java if it has always need to be overridden?
Example:
String var = "3";
byte [] var_inBytes = var.getBytes();
String var2 = var_inBytes.toString();
this will give me the name of the object followed by the hash code
okay then when we can use toSting method without overriding?
Every Class is inherited from Object Class in Java, Therefore the Object class methods are available to all Java classes.
According to the Java doc :
In general, the toString method returns a string that "textually
represents" this object. The result should be a concise but
informative representation that is easy for a person to read. It is
recommended that all subclasses override this method.
You may want to override the default toString() method in your current class to represent a different format string depend on your requirement but since the Object class has this method, All of the other classes have a default toString() method.
You can read more here :
https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#toString()
Good Luck!
toString() method is one of the programmer best friend. I use it on each business object or each entity at least, to list their variable members content.
At the time an unexpected problem occurs and that your are in big trouble, and especially if you are in emergency, it makes a great change if you can read : "Big trouble on item {Id : 125, name : Smith, Address : 15 King Square}", instead of "Big trouble on an item".
Not only you have the id you can use for your internal research, but you can also tell a end-user about who is really impacted : Mr Smith. May be your end-user will have a clue : "Oh yes, we were doing special operation on him, because..."
In plenty of logs, on TRACE or DEBUG level only of course, I dump many business object or entities content that way. If a really big problem happens, even in production, and that it is reproducible, I may (in the dire case) restart the application in TRACE mode and learn what really happens.
toString() is a life savior, I say.

Get only one field in protocol buffer without deserializing whole object in java

I have POJO that serialized with protobuf. This object has many fields. I want to check one field. Is it possible to deserialize only one filed without deserializing the whole object in Java? I think it is probable in Python.
Yes, it is possible.
I have already implemented this in Scala and published as a library to the Maven central under:
cz.jkozlovsky:scala-protobuf-field-extractor_${scalaVersion}
In case you are comfortable with Scala, the usage of the library is explained within the README.
Also, the tests might give you a good idea of how to use the API.
In case you need Java native solution, you can easily implement it yourself.
For details, see the staticExtract method.
Here is a Scala snippet of the implementation (any decent IDE should automatically convert this to Java while pasting):
def staticExtract[T](codedInputStream: CodedInputStream, fieldDescriptor: FieldDescriptor, extractionMethod: CodedInputStream => T): T = {
while (!codedInputStream.isAtEnd) {
if (WireFormat.getTagFieldNumber(codedInputStream.readTag()) == fieldDescriptor.getNumber) {
return extractionMethod.apply(codedInputStream)
} else codedInputStream.skipField(codedInputStream.getLastTag)
}
fieldDescriptor.getDefaultValue.asInstanceOf[T]
}
all it does, is it iterates over the input stream until either:
the queried field is found
then the provided extraction method is applied upon the current stream state (e.g. CodedInputStream.readBool())
it is important to note, that the tag read by the CodedInputStream contains both the fieldNumber and the wireType (as explained here), so you have to first extract the fieldNumber in order to match it with the FieldDescriptor's number
the end is reached
in which case, the default value is returned

Why do loggers in Java rarely have the .toString() that System.out.println does?

I'm frequently annoyed by having
System.out.println(someObject);
and, when changing it to using whatever logger is required
LOG.info(someObject);
and having to add the .toString() to make it compile
LOG.info(someObject.toString());
I cannot recall having used a logger that does not simply take in an Object and tries do to .toString() on it, making me wonder if there is a specific reason for this. Surely I cannot be the only one annoyed by having to add .toString() to everything?
The key point is to understand the purpose of logging. Loggers are there to print human readable english messages regarding any event that occurs within an application. And the logging API's are built following this basic principle
LOG.info(someObject.toString());
The problem with the above line is that the basic concept of logging is somewhat different from what you are trying to achieve. You want to log an object which is already not a human readable entity and then to make it work by casting it either to a string or you could implement the toString() method or lastly you can take a look at one of the overloaded function
public void info(String format, Object... arguments)
Logging an object directly is mostly done by developers when they want to debug to lets say the contents of the object or something like that, so the best way to achieve that would be to correctly implement the toString() method.
I would also advise to take a look into the Project Lombok, it provides ready to use implementations of common hashCode() and toString() functions of your beans so you don't have to go through your code and implement the method one by one.

Java toString for debugging or actual logical use

This might be a very basic question, apologies if this was already asked.
Should toString() in Java be used for actual program logic or is it only for debugging/human reading only. My basic question is should be using toString() or write a different method called asString() when I need to use the string representation in the actual program flow.
The reason I ask is I have a bunch of classes in a web service that rely on a toString() to work correctly, in my opinion something like asString() would have been safer.
Thanks
Except for a few specific cases, the toString should be used for debugging, not for the production flow of data.
The method has several limitations which make it less suitable for use in production data flow:
Taking no parameters, the method does not let you easily alter the string representation in response to the environment. In particular, it is difficult to format the string in a way that is sensitive to the current locale.
Being part of the java.Object class, this method is commonly overridden by subclasses. This may be harmful in situations when you depend on the particular representation, because the writers of the subclass may have no idea of your restrictions.
The obvious exceptions to this rule are toString methods of the StringBuilder and the StringBuffer classes, because these two methods simply make an immutable string from the mutable content of the corresponding object.
It is not just for debugging/human reading only, it really depends on the context in which the object is being used. For example, if you have a table which is displaying some object X, then you may want the table to display a readable textual representation of X in which case you would usually implement the toString() method. This of course is a basic example but there are many uses in which case implementing toString() would be a good idea.

Categories