char is 16 bit unsigned data type in Java, which is used to store characters and String value is an immutable array of char. In Java we cannot cast a primitive char element to String.

tl;dr

  • Use String.valueOf(char)

6 Ways to do it

Below I have given five 6 methods to convert a char to String. Also I have included common mistakes that gives compile time errors.

CharToString.javaview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.deepumohan.tech.chartostring;
public class CharToString {
public static void main(String[] args) {
char x = 'x';
// Although this method seems very simple, this is less efficient because the concatenation
// expands to new StringBuilder().append(x).append("").toString();
String concatBlankString = 'x' + "";
// use String.valueOf(char) static method
String stringValueOf = String.valueOf(x);
// use String.valueOf(char[]) static method
String stringValueOfCharArray = String.valueOf(new char[]{x});
// use Character.toString(char) static method
String characterToString = Character.toString(x);
// create new Character object from the given char and
// then use object's toString() method
String characterObjectToString = new Character(x).toString();
// create new char[] array from the char and pass it to
// String constructor
String fromCharArray = new String(new char[]{x});
System.out.println(concatBlankString + ":" + stringValueOf + ":" + stringValueOfCharArray);
System.out.println(characterToString + ":" + characterObjectToString + ":" + fromCharArray);
/*
// Compile time error
// No suitable constructor found
public static String noConstructor(char x) {
return new String(x);
}
// Compile time error
// Inconvertible types
public static String inconvertibleTypes(char x) {
return (String) x;
}
*/
}
}

EDIT: September 07 2015

Closer look on what is happening in Java 8

Source codes are extracted from grepcode Open JDK 8

The toString methods in java.lang.Character class calls the String.valueOf(char) method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package java.lang.Character;
...
public String toString() {
char buf[] = {value};
return String.valueOf(buf);
}
...
public static String toString(char c) {
return String.valueOf(c);
}

And here is what String.valueOf(char[]) and String.valueOf(char) methods looks like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package java.lang.String;
...
/**
* Returns the string representation of the {@code char} array
* argument. The contents of the character array are copied; subsequent
* modification of the character array does not affect the returned
* string.
*
* @param data the character array.
* @return a {@code String} that contains the characters of the
* character array.
*/
public static String valueOf(char data[]) {
return new String(data);
}
...
/**
* Returns the string representation of the {@code char}
* argument.
*
* @param c a {@code char}.
* @return a string of length {@code 1} containing
* as its single character the argument {@code c}.
*/
public static String valueOf(char c) {
char data[] = {c};
return new String(data, true); // package private
}

Here are the constructors that is called in the above methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package java.lang.String;
...
/**
* Allocates a new {@code String} so that it represents the sequence of
* characters currently contained in the character array argument. The
* contents of the character array are copied; subsequent modification of
* the character array does not affect the newly created string.
*
* @param value
* The initial value of the string
*/
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
...
/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}

To summarise when you use String.valueOf or Charactor.toString methods, the constructor public String(char value[]) is being invoked.
You may as well call it directly and reduce one hop.

Most Efficient Method

String.valueOf(char value) invokes the following package private constructor.

1
2
3
4
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}

String.valueOf(char) seems to be most efficient method for converting char to String.

Side note

Remember String objects are immutable and they can be shared.

For example:

1
String str = "abc";

is equivalent to:

1
2
char data[] = {'a', 'b', 'c'};
String str = new String(data);
I wonder why Java doesn’t include String constructor that accept a single char as argument.

Java does’nt include String constructor that accepts a single char, because there already is a constructor that accepts a char[].

Also see