2

I have the following code for a class:

public class sqrt
{
    public sqrt()
    {
        char    start   = 'H';
        int     second  = 3110;
        char    third   = 'w';
        byte    fourth  = 0;
        char    fifth   = 'r';
        int     sixth   = 1;
        char    seventh = 'd';
        float   eighth  = 2.0f;
        boolean ninth  = true;

        String output = new String(start + second + " " + third + fourth +
        fifth + sixth + seventh + " " + eighth + " " + ninth);
        System.out.println(output);
    }  
}

The required output is:

H3110 w0r1d 2.0 true

However, this outputs the following:

3182 w0r1d 2.0 true

I can only assume this is because it sees the numerical (ASCII) value of char 'H' and adding it to int 3110.

My question is:

Shouldn't new String() convert each item within to a string and concatenate them?

If I change the output to:

String output = start + second + " " + third + fourth +
                fifth + sixth + seventh + " " + eighth +
                " " + ninth;

It does the same thing, and adds the value of char and int together before concatenating the rest.

I know I can overcome this by adding a "" + before start, and I suppose that explains why it is seeing the ASCII value of char 'H' (because it looks at the next value, sees it's an int, and goes from there?), but I'm confused as to why the new String() isn't working as intended.

PS, I want to write better questions, and I know I am still a bit of a beginner here, so any advice in that regard would be appreciated as well. PMs are more than welcome, if anyone is willing to take the time to help.

PPS, If I figure out why this is, I will post the answer myself, but I am really trying to learn this, and I'm just very confused.

ZLHysong
  • 189
  • 2
  • 3
  • 17
  • 2
    In general, you should never use `new String()` in Java. For String concatenation, use `+` or a `StringBuilder`. – Mick Mnemonic Jan 28 '18 at 22:07
  • It does the same without the `new String();` I'll edit the question to show that. I apologize. – ZLHysong Jan 28 '18 at 22:08
  • 2
    `new String(String)` just gives you a unique string with the given content, it shouldn't change anything to do with your question – jrtapsell Jan 28 '18 at 22:09
  • I think the answer you are looking for is here https://stackoverflow.com/questions/8688668/in-java-is-the-result-of-the-addition-of-two-chars-an-int-or-a-char – ASutherland Jan 28 '18 at 22:10
  • @ZLHysong, as you speculated, basically the problem is with the semantics of the `+` operator: between `char` and `int` operands it means _addition_ not _string concatenation_. If you replace all `+`s with `StringBuilder.append(...)`, there is no ambiguity and it works as it should. – Mick Mnemonic Jan 28 '18 at 22:16
  • Yes, you diagnosed it correctly, except the character code is from UTF-16, not ASCII. ASCII has only very rare or specialized uses. UTF-16 is one of several character encodings for the [Unicode](http://www.unicode.org/charts/nameslist/index.html) character set. – Tom Blodget Jan 28 '18 at 23:30

4 Answers4

5

I can only assume this is because it sees the numerical (ASCII) value of char 'H' and adding it to int 3110.

That's perfectly correct.

Shouldn't new String() convert each item within to a string and concatenate them?

The String constructor has no control over this, because the expression start + second + " " + ... is evaluated before.


The concise approach here is to use a StringBuilder. It has methods to accept all primitive types and arbitrary objects.

String output = new StringBuilder().append(start).append(second).append(' ')
    .append(third).append(fourth).append(fifth).append(sixth).appends(seventh)
    .append(' ').append(eighth).append(' ').append(ninth).toString();

or

StringBuilder builder = new StringBuilder();
builder.append(first);
builder.append(second);
builder.append(' ');
builder.append(third);
builder.append(fourth);
builder.append(firth);
builder.append(sixth);
builder.append(seventh);
builder.append(' ');
builder.append(eighth);
builder.append(ninth);
String output = builder.toString();
Izruo
  • 2,246
  • 1
  • 11
  • 23
  • Thank you. This makes the most sense to me, while all the answers were helpful. I've marked it as the solution to my question. – ZLHysong Jan 28 '18 at 23:03
2

Shouldn't new String() convert each item within to a string and concatenate them?

new String() has nothing to do with it. First we evaluate the expression. Then we pass the value of the expression to the String constructor.

So first of all we're adding a char to an int; this is integer addition. Then the result of that (3112) is converted to string so it can be concatenated to the string " ". Thereafter at least one operand is a String therefore concatenation applies.

dave
  • 21
  • 1
1

I'm confused as to why the new String() isn't working as intended.

It's working as intended, which is to initialize a new String object representing the data passed to it.

Shouldn't new String() convert each item within to a string and concatenate them?

Currently, you're using this overload of the String constructor which states:

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.

Essentially, as the string you passed to the String constructor is 3182 w0r1d 2.0 true the new string object is a copy of that. Nothing else is performed.

Community
  • 1
  • 1
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

you can use the code below since characters cannot be changed to string inherently so:

String output = new String(String.valueOf(start) + second + " " + third + fourth +
  fifth + sixth + seventh + " " + eighth + " " + ninth);
parsa
  • 987
  • 2
  • 10
  • 23