2

A very simple question. Does it have anything to do with performance? Something else?

System.out.println('c');
System.out.println("c");

Which, why?

System.out.println("Letter: " + "c");
System.out.println("Letter: " + 'c');

Which, why?

Pétur Ingi Egilsson
  • 4,368
  • 5
  • 44
  • 72

1 Answers1

8

They are different things. "c" is a String object of length 1; 'c' is a char primitive value (one of the integer types in Java).

Part of why they seem interchangeable is because of Java's rules for string concatenation; the language defines aString + aChar to be the string that results from appending to aString the character represented by the UTF-16 value aChar. In your particular example, the expression "Letter: " + 'c' is treated as a compile-time constant String expression and evaluated by the compiler, not at run time. You can see this by compiling the code and looking at the resulting bytecode.

The Java Language Specification spells out what's going on. First, one reads in JLS §15.18.1 ("String Concatenation Operator +"):

If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings.

Then in §5.1.11 we find (among other rules):

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

  • ...
  • If T is char, then use new Character(x).
  • ...

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

So in theory, the char constant 'c' is autoboxed to a Character object. However, in practice the compiler and the core classes take substantial liberties and generate much more efficient (but functionally equivalent) code.

Community
  • 1
  • 1
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 1
    Appending a character to string is done with StringBuilder and would not turn `'c'` into an object. – Teemu Ilmonen Mar 22 '16 at 07:17
  • @TeemuIlmonen - Actually, autoboxing is exactly what's going on **in theory**. See my expanded answer. In practice, however, neither autoboxing nor `StringBuilder` is used; the compiler simply treats the whole expression as a compile-time string constant. – Ted Hopp Mar 22 '16 at 07:51
  • Yes, when dealing with constants there wouldn't be need for StringBuilder. I guess the reference does not specifically state what path needs to be used when stating "as if by", it just states what the result must be. Splitting hairs: autoboxing would be `Character.valueOf(x)`, not `new Character(x)`? – Teemu Ilmonen Mar 22 '16 at 08:18
  • @TeemuIlmonen - Yes, I think autoboxing would be done with `Character.valueOf(x)`, but internally that just gives the class a chance to return a cached `Character` object previously constructed with `new Character(x)`; otherwise it still ends up with a new object construction. – Ted Hopp Mar 22 '16 at 15:12