According to the binary promotion rules, if neither of the operands is double, float or long, both are promoted to int. However, I strongly advice against treating char type as numeric, that kind of defeats its purpose.
The result of the binary operation is converted to the type of the left-hand variable ... and the result of the conversion is stored into the variable.
For example:
char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK
One way you can find out the type of the result, in general, is to cast it to an Object and ask it what class it is:
System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer
If you're interested in performance, note that the Java bytecode doesn't even have dedicated instructions for arithmetic with the smaller data types. For example, for adding, there are instructions iadd (for ints), ladd (for longs), fadd (for floats), dadd (for doubles), and that's it. To simulate x += y with the smaller types, the compiler will use iadd and then zero the upper bytes of the int using an instruction like i2c ("int to char"). If the native CPU has dedicated instructions for 1-byte or 2-byte data, it's up to the Java virtual machine to optimize for that at run time.
If you want to concatenate characters as a String rather than interpreting them as a numeric type, there are lots of ways to do that. The easiest is adding an empty String to the expression, because adding a char and a String results in a String. All of these expressions result in the String "ab":
'a' + "" + 'b'
"" + 'a' + 'b' (this works because "" + 'a' is evaluated first; if the "" were at the end instead you would get "195")
new String(new char[] { 'a', 'b' })
new StringBuilder().append('a').append('b').toString()
Although c is a type of char, it can be supplied with no error in the respective constructors and all of the above statements are treated as valid statements. They produce the following outputs respectively.
char is a primitive numeric integral type and as such is subject to all the rules of these beasts including conversions and promotions. You'll want to read up on this, and the JLS is one of the best sources for this: Conversions and Promotions. In particular, read the short bit on "5.1.2 Widening Primitive Conversion".
While you have the correct answer already (referenced in the JLS), here's a bit of code to verify that you get an int when adding two chars.
public class CharAdditionTest
{
public static void main(String args[])
{
char a = 'a';
char b = 'b';
Object obj = a + b;
System.out.println(obj.getClass().getName());
}
}
While Boann's answer is correct, there is a complication that applies to the case of constant expressions when they appear in assignment contexts.
Consider the following examples:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
What is going on? They mean the same thing don't they? And why is it legal to assign an int to a char in the first example?
When a constant expression appears in an assignment context, the Java compiler computes the value of the expression and sees if it is in the range of the type that you are assigning to. If it is, then an implicit narrowing primitive conversion is applied.
In the first example, 'a' + 'b' is a constant expression, and its
value will fit in a char, so the compiler allows the implicit narrowing of the int expression result to a char.
In the second example, y is a variable so y + 'b' is NOT a
constant expression. So even though Blind Freddy can see that the
value will fit, the compiler does NOT allow any implicit narrowing, and you get a compilation error saying that an int cannot be assigned to a char.
There are some other caveats on when an implicit narrowing primitive conversion is allowed in this context; see JLS 5.2 and JLS 15.28 for the full details.
The latter explains in detail the requirements for a constant expression. It may not be what you may think. (For example, just declaring y as final doesn't help.)