Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is primitive type int actually converted to a String?

Firstly, my question is about how the primitive type int is able to be converted into a String without being an Object, so not having a toString() method to get the String value.

I'm well aware of how you're able to seemingly 'convert' a variable of the primitive type int to a String in Java. The most simple way I use is:

int x = 5;
String y = "" + x;

This works very well, however my question is the following:

Due to the primitive type int not being an Object, therefore not having any methods such as the toString() method which to my knowledge is required in order to get a String value of a variable... How is the value of the variable recognised without this fundamental method?

like image 499
Nathangrad Avatar asked Feb 25 '16 16:02

Nathangrad


2 Answers

This is called string conversion. The JLS, Section 5.1.11, states:

Any type may be converted to type String by string conversion.

A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression (§15.9):

(other types)

  • If T is byte, short, or int, then use new Integer(x).

This reference value is then converted to type String by string conversion.

Now only reference values need to be considered:

  • If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).

  • Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.

So, the int is converted to an Integer, not by boxing conversion, but by new Integer(x), then toString() is called on it.

It's technically not a boxing conversion; string conversion has been in the language since the beginning of Java, where boxing conversions were added in Java 1.5.

like image 176
rgettman Avatar answered Oct 11 '22 07:10

rgettman


In general, an int value is converted to String by calling one of these two methods:

  • StringBuilder.append(int i)
  • String.valueOf(int i)

For other primitive values, the corresponding overload of either of these methods are used.

StringBuilder.append()

The expression "" + x is implemented by the compiler as:

new StringBuilder().append("").append(x).toString()

With x being declared as int, that means that the overload of append() that takes an int parameter will be called.

The source (Java 1.8.0_65) for append(int) is:

@Override
public StringBuilder append(int i) {
    super.append(i);
    return this;
}

The super call leads to:

public AbstractStringBuilder append(int i) {
    if (i == Integer.MIN_VALUE) {
        append("-2147483648");
        return this;
    }
    int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
                                 : Integer.stringSize(i);
    int spaceNeeded = count + appendedLength;
    ensureCapacityInternal(spaceNeeded);
    Integer.getChars(i, spaceNeeded, value);
    count = spaceNeeded;
    return this;
}

String.valueOf()

When converting a value to a String without using string concatenation, it is generally done by calling String.valueOf(). For an int value that means valueOf(int):

public static String valueOf(int i) {
    return Integer.toString(i);
}

The Integer.toString() call is:

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(buf, true);
}

Integer.getChars()

As you can see, both do it by actually calling the package-private method Integer.getChars(int i, int index, char[] buf).

Neither of them actually creates an instance of Integer, even though the JLS implies it would.

like image 35
Andreas Avatar answered Oct 11 '22 07:10

Andreas