How Does the .Tostring() Method Work

How does the toString method work?

The purpose to toString is clearly documented in the API:

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.

Object#toString() will produce:

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 override toString in your class call to default Object#toString() will be replaced by yourclass#toString().In your current code If you try to print Item instance the output will be of format:

name +": $" + price+":" + qty;

How does the .ToString() method work?

Sometimes when I call the ToString method it returns the fully qualified name of the runtime type of the object that received the call.

Correct.

But for some types, such as System.Int32, ToString returns the value of the receiver converted to a string.

Correct.

Does the System.Int32 struct override the ToString method?

Yes.

Do other types whose ToString methods return the fully-qualified type name not override ToString?

That is probably the case, yes. Of course, they could override the method and have the overriding method do exactly the same thing as the base class method, but that would be a bit pointless.

So in those cases, calling ToString just calls the System.Object implementation of ToString, which returns fully qualified name?

Correct.

You seem to have a solid grasp of how this works. My only correction would be to note that System.Int32 is a struct, not a class.

How does Object.toString() work for different underlying types?

Your last paragraph where you explain your reasoning is slightly incorrect.

so why in the example of before i don't see the reference but directly
the number? by logic, the rules of the polymorphism says that: if u
have a "child" object in a "father" variable, this object, inside,
remanis the same but he is used like an istance of object, so he can
just uses the class object and so just the method of object, so is
really strange that i don't see the reference but directly the number.

The beginning is correct, but the part I bolded is an incorrect conclusion you drew from it.

You are correct that with polymorphism, the object truly remains whatever type it is, but the reference type (the type of the variable) defines what you can do with it. However, the reference type does not describe what the object does

That is the intent behind polymorphism. It is an abstraction to define what can be done separately from how it works. For example, if you have this example:

public class Vehicle {
public int getWheelCount() {
return 1;
}
}

public class Car extends Parent {
public int getWheelCount() {
return 4;
}

public void blowHorn() {
System.out.println("Honk honk!");
}
}

public class Bicycle extends Parent {
public int getWheelCount() {
return 2;
}
}

Car car = new Car();
car.getWheelCount(); // 4
car.blowHorn(); //"Honk honk!"

Vehicle v = new Car();
v.getWheelCount() // 4
v.blowHorn(); // COMPILE ERROR HERE! Unknown method

Bicycle b = new Bicycle();
b.getWheelCount(); // 2

Vehicle v = new Bicycle();
v.getWheelCount(); // 2

What you can conclude from this is that when over-riding a method in a sub-class, the child version is always called. A car is always a car whether you are referring to it as a vehicle or as a car. But by referring to it as a vehicle, you are limited to invoking methods which are defined on all vehicles.

To tie it to the example, all Vehicle objects have a wheel size, therefore getWheelCount() is always callable whether it's Vehicle.getWheelCount() or Car.getWheelCount(). However, Car.getWheelCount() is what executes because Car over-rides it.

If the reference type is Vehicle, you cannot call blowHorn() because that method is only available on Car.

Going back to your example, an Integer is an Integer.

Object i = new Integer(5);
i.toString(); // 5

This prints 5 because i is an integer. The Integer class over-rides toString. The reference type (the type you are referring to the object as) only determines which methods you can call, but not which parent/child class's version of the method is called.

How does toString() work in javascript?

toString is a special function (in object's prototype), which is called when a stringified mode of the object is required.

In your cases, the addition operator calls the toString method of the object. From the specs:


  1. If Type(lprim) is String or Type(rprim) is String, then

    a. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim).

However, this native method can be overridden, which you've done* in the first snippet. Addition operator just calls the custom method, which produces the result you've got.

In the latter snippet toString just returns a default value for objects.

You can see this happening in many situations, for example alert({}) calls internal toString method from object's prototype, since alert requires a string as an argument.

(* More accurate: you haven't re-written the native property, rather you've created an own property to the object with the same name, which is used instead of searching the native property from the prototype chain.

What does assigning to {}.toString mean?

Is it because toString is a built-in function

Not exactly, it is because both Object and window in javascript both have a toString method.


The {} in {}.toString represents a new object in javascript. Object has a toString method and that is what you're creating a reference to.

If you omit the {} it is equivalent of window.toString and as luck would have it the window object itself has a toString method. So everything continues to work.

When you do {}.getAge you're telling the interpreter to get the getAge method from Object, which does not exist, setting tellAge equal to undefined, which leads to the error cannot read property "call" of undefined

How to use the toString method in Java?

From the Object.toString docs:

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())

Example:

String[] mystr ={"a","b","c"};
System.out.println("mystr.toString: " + mystr.toString());

output:- mystr.toString: [Ljava.lang.String;@13aaa14a

How does Integer.toString() works internally?

The no arg call of integer.toString() simply calls the static method Integer.toString(int i) (using the integer variables own primitive value), which is implemented as below;

  public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(0, size, buf);
}

First it checks whether it's value is == the lowest possible integer, and returns that if it is equal. If not, then it checks what size the String needs to be using the stringSize() method of Integer to use as the size of an array of characters.

stringSize() implementation below;

  static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}

Once it has a char[] of the correct size, it then populates that array using the getChars() method, implemented below;

  static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;

if (i < 0) {
sign = '-';
i = -i;
}

// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}

// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}

Explaining each individual step would take far too long for for a stackoverflow answer. The most pertinent section however (as pointed out in the comments) is the getChars() method which, complicated bit shifting aside, is essentially process of elimination for finding each character. I am afraid I can't go into any greater detail than that without going beyond my own understanding.

when to use toString() method

In most languages, toString or the equivalent method just guarantees that an object can be represented textually.

This is especially useful for logging, debugging, or any other circumstance where you need to be able to render any and every object you encounter as a string.

Objects often implement custom toString behavior so that the method actually tells you something about the object instance. For example, a Person class might override it to return "Last name, First name" while a Date class will show the date formatted according to some default setting (such as the current user interface culture).



Related Topics



Leave a reply



Submit