Getting weird text back with EditText.toString() method in Android project. Why? - java

I appear to have a fundamental gap in my understanding of an EditText object. I have an Activity+Layout with a single EditText object. After I type a few characters into the EditText object and hit the Enter key, I retrieve the text in my onKey() listener. When I use the toString() method to retrieve the text I get back a weird string like:
android.widget.EditText#43749ff0
Despite the fact the EditText.mText property does show the string I entered, "123" during my tests. Why is toString() returning a different result and what appears to be some kind of "uninitalize" value? How do I get the desired string currently in the mText property and what is that strange value?
-- roschler

Passing glance at the API suggests you should use the getText() method. toString() is a general method that applies to Object and all its subclasses (i.e., everything that isn't a primitive, to my knowledge). It's often overridden to supply more useful strings, but by default, it reports something just like what you posted - a sparse description and the object's hashcode. To be clear, the API defines toString() as:
getClass().getName() + '#' + Integer.toHexString(hashCode())

You can't use the 'toString'-method on this, use 'getText().toString()' in stead.

You are calling toString() on a View Object, which probably does not have a toString() defined.
I believe you want to call this:
editText.getText().toString()

Try EditText.getText().toString()

Take a moment to read the java API: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#toString%28%29
toString
public String 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. It is recommended that
all subclasses override this method.
The toString method for class Object
returns a string consisting of the
name of the class of which the object
is an instance, the at-sign character
`#', and the unsigned hexadecimal
representation of the hash code of the
object. In other words, this method
returns a string equal to the value
of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
Returns: a string representation of
the object.

Related

Is there any custom toString() method with limited characters number of returned string?

I have a Map which represents Json object (so Map might have nested maps), and I want to log this Map in some places but I don't want to write to the console long strings. I'm looking for some way to get something like toString() but with ability of configuring max length of returned string.
Overriding toString() with implementation like
#Override
public String toString() {
return super.toString().substring(0, 100);
}
is not an option, because super.toString() might return really long (with >1000 length) string, which undesirable will fall into heap.
So can anybody tell if there is another way exists to get limited string of the object?

Am I abusing toString()?

Javadoc for Object.toString() says:
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. It is recommended that all
subclasses override this method. The toString method for class Object
returns a string consisting of the name of the class of which the
object is an instance, the at-sign character '#', and the unsigned
hexadecimal representation of the hash code of the object. In other
words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
Therefore, I am questioning myself if I'm abusing this when I am overriding toString() of a class Foo just so that a ComboBox control (doesn't matter it's JavaFX or Swing control) can render a list of Foo correctly without me doing anything explicit in the ComboBox.
class Foo {
private String name;
public final String getName() { return name; }
public final void setName(String n) { name = n; }
#Override
public String toString() {
return name;
}
}
List<Foo> foos = getFoos(); // Get list of Foos from somewhere
ComboBox comboBox = ....; // Some ComboBox control
comboBox.addItems(foos); // Add the list to the ComboBox
The default implementation of toString() that most IDE generates are JSON representation of the class. I am suspecting this allows easy serialization/deserialization of class objects. Although I do not need to serialize or deserialize through this method, but I am definitely breaking this possibility by overriding like this.
Edit
I've read the comments of many people, as well as the answer given by VGR. I can see that the general consensus is that there is no hard and fast rule on this. I see that it is generally agreed that toString() is better left for debugging purposes.
The biggest reason why I am doing this "hack" is because I have ComboBox in quite a number of different places. Of course the indisputably correct and clean way is to use a "renderer" to do this job, but it is causing a significant amount of code duplication.
I will mull over this for a few days before I decide which is the best way to do it. Thanks a lot for the bunch of comments and answer.
For Swing, you definitely need to override the toString method of some class. That’s how Swing model objects work. (Do not use cell renderers to convert a value to String; that will break accessibility, keyboard navigation, and built-in sorting of JTables.)
Usually you’d want to separate your display logic from your data, such as by creating a wrapper class, but since you are just returning the raw value of a property (as opposed to formatting it or concatenating it with other information), what you’re doing is fine.
JavaFX is another matter: Controls use cell factory callback objects to determine what text appears in a cell, so a data class probably should not override toString with a display value in a JavaFX application.
I’m not familiar with IDEs’ auto-generated toString methods, but converting an object to JSON in a toString method is a horrible idea in my opinion. Swing model objects should have a toString method that returns a human-readable form of the object; most other classes should return a one-line string with a summary of the object’s state (which does not have to be every property in the object), like getClass().getName() + "[" + getName() + "]".
In summary, you are not abusing toString. For Swing, you’re doing the right thing. For JavaFX, it’s better to return a string useful for debugging.

Casting to String by parentheses gives crash on Android

I know how to get a String from a TextView with toString(), but i would like to understand why if i cast the TextView's text to String by parentheses, it leads Android to crash at runtime ?
e.g "String text = (String)((TextView)findViewById(R.id.myTextViewId)).getText();"
This is because getText() returns CharSequence (which you can cast to Spannable or Editable in some cases) which you cannot cast to string directly.
Using toString() gives you a conversion to string class.
From android developer documentation:
public CharSequence getText ()
Return the text the TextView is displaying. If setText() was called with an argument of BufferType.SPANNABLE or BufferType.EDITABLE, you can cast the return value from this method to Spannable or Editable, respectively. Note: The content of the return value should not be modified. If you want a modifiable one, you should make your own copy first.
Source: http://developer.android.com/reference/android/widget/TextView.html
When you use the “toString()” you’re actually doing a conversion. You’re calling the objects toString() method who understands what the object is and how to convert it to a string which “makes sense”.
When you use the “(String)” syntax you’re using a cast which doe NO conversion. It just says take the object and, with no changes at all, treat it as though it were a String. Since the object is not a String, you can get errors calling methods which do not apply on what the object actually is.
try this...
String text = ((TextView)findViewById(R.id.myTextViewId)).getText().toString();
because getText() returns CharSequence object

Is it useful to log an object hashcode?

I see a lot of the following line in projects I took over:
log.debug(submitObject(" + object + ")");
log.debug(registerUser(" + user + ")");
and so on.
In the logs this prints out something like:
SubmitObject(java.lang.Object#13a317a)
Is it useful to log just the object type and its hashcode? Say I want to know the name of the user object but I only have the hashcode, would it be possible for me to reconstruct the object based on the hashcode?
From 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. It is recommended that all
subclasses override this method. The toString method for class Object
returns a string consisting of the name of the class of which the
object is an instance, the at-sign character `#', and the unsigned
hexadecimal representation of the hash code of the object. In other
words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
Returns: a string representation of the object.
I myself always override the toString() of a custom object so it prints out all the fields of the object. Should I start printing the object code instead?
You could use ReflectionToStringBuilder from org.apache.commons, if you do not have access to source code, or if you do not want implement toString for change existing code.
For Example:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("User : "
+ reflectionToStringBuilder.toString(user ,
ToStringStyle.MULTI_LINE_STYLE))
}
"LOGGER.isDebugEnabled() is very important as toString Operation, or reflectionToStringBuilder, will be executed before calling log.debug, so you do not want such expensive operations.
ReflectionToStringBuilderJavaDoc: http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/builder/ReflectionToStringBuilder.html
No, keep overriding toString() which is much more useful. The default toString() is practically useless except that it at least shows what the class instance is.
That hash code is a randomly assigned value. It is only useful if you want to check you had the same object in a previous log, or a different one (i.e. very rarely)

object identityhashcode in java

I've been working in my project (I'm also using EMF Compare). I need to keep an unique ID for each object that I'm using, that's why I decided to use the IdentityHashCode, as far as I understand, this value is the same through the compilation.
I have given the object as a parameter in the method of another class, but when I try to get the hashcode this is not the same that I can see when I print the value of the object.
Something like this:
System.out.println("The Object is: "+obj)
System.out.println("The hash ID is: +Integer.toHexString(System.identityHashCode(obj)));
But as a result I get this:
The Object is : ***xxxxxxxxxxxxxx***.EntityImpl#18e588c (name: Comment) has been removed.
The hash ID is: 1ec1758
As you can see the two values (18e588c and 1ec1758) are totally different, but I can't understand why. Until now the only thing that I have done (and it works) is to get the String of the object and then use the substring method to get 18e588c (for this example)
I'd appreciate any answer.
I need to keep an unique ID for each object that I'm using, that's why I decided to use the IdentityHashCode, as far as I understand, this value is the same through the compilation.
No. It's got nothing to do with compilation, and it's not guaranteed to be unique.
It's not clear what you're trying to do, but you simply shouldn't regard hash codes as unique - they're not guaranteed to be.
The Object.hashCode documentation specifies:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.
That's not the same thing as guaranteeing it though.
You're also being confused by the result of calling toString() - I suspect your class actually overrides hashCode(), and Object.toString() calls the potentially-overridden hashCode() method rather than using the identity hash code:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
If you call obj.hashCode() you'll see the same value that's shown by toString.

Categories