在添加'a' + 'b'
时,它会产生195。输出的数据类型是int
还是char
?
将Java中的char、short或byte相加的结果是一个int:
- 如果任何一个操作数是引用类型,则执行自动拆箱转换(§5.1.8)。然后:
- 如果任一操作数是double类型,则将另一个操作数转换为double类型。
- 否则,如果任一操作数是float类型,则将另一个操作数转换为float类型。
- 否则,如果任一操作数是long类型,则将另一个操作数转换为long类型。
- 否则,两个操作数都将转换为int类型。
二进制操作的结果将被转换为左侧变量的类型...并将转换的结果存储到该变量中。
例如:
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
一种通常的方式是将结果转换为Object,然后询问它属于哪个类别,以确定结果的类型:
System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer
iadd
(用于int)、ladd
(用于long)、fadd
(用于float)、dadd
(用于double),就是这样。为了模拟使用较小类型的x += y
,编译器将使用iadd
,然后使用像i2c
(“int转char”)这样的指令将int的上半字节清零。如果本地CPU具有用于1字节或2字节数据的专用指令,则由Java虚拟机在运行时进行优化。"ab"
:
'a' + "" + 'b'
"" + 'a' + 'b'
(这个可以工作是因为"" + 'a'
先被评估;如果""
在最后,您将得到"195"
)new String(new char[] { 'a', 'b' })
new StringBuilder().append('a').append('b').toString()
String.format("%c%c", 'a', 'b')
char
和byte
(还有short
)的二进制算术运算会自动提升为int
类型 -- 参见JLS 5.6.2。
您可能希望了解以下关于char
的表达式。
char c='A';
int i=c+1;
System.out.println("i = "+i);
66
,即字符(Unicode)c+1
的相应值。String temp="";
temp+=c;
System.out.println("temp = "+temp);
这个在Java中是合法的,字符串类型变量temp
自动接受char类型的c
并在控制台上产生temp=A
。
以下所有语句在Java中也是有效的!
Integer intType=new Integer(c);
System.out.println("intType = "+intType);
Double doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);
Float floatType=new Float(c);
System.out.println("floatType = "+floatType);
BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);
Long longType=new Long(c);
System.out.println("longType = "+longType);
char 的一种类型,但在相应的构造函数中可以无误地提供它,并且上述所有语句都被视为有效语句。 它们分别产生以下输出。
intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65
char
是一种原始数字整数类型,因此受到这些类型的所有规则的限制,包括转换和提升。您需要阅读相关知识,而JLS是其中最好的资源之一:Conversions and Promotions。特别地,请阅读有关“5.1.2扩展原始转换”的简短介绍。
Java编译器可以将其解释为任何一个。
通过编写程序并查找编译器错误来检查它:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
char result2 = 'a' + 'b'
z + y
不是常量表达式。请查看我的答案,其中包含更详细的解释...以及JLS链接。 - Stephen Cchar
作为数字值是完全符合其目的的,这也是JLS为此类用法付出大量言辞的原因。 - Lew Bloch虽然您已经有了正确的答案(在JLS中引用),但这里有一些代码来验证当添加两个char
时,您会得到一个int
。
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());
}
}
输出结果是
java.lang.Integer
int
和Integer
并不是同一种东西。更有说服力的验证是尝试将a + b
分配给一个int
变量或一个char
变量。后者会产生编译错误,大致意思是“你不能将int
分配给char
”。 - Stephen C尽管 Boann的答案是正确的,但在赋值上下文中出现常数表达式的情况会产生复杂性。
考虑以下示例:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
发生了什么?它们不是意思相同吗?为什么在第一个例子中将int
赋值给char
是合法的?
当常量表达式出现在赋值上下文中时,Java编译器计算表达式的值并查看它是否在您要分配的类型范围内。如果是,则应用隐式的缩小原始转换。
在第一个例子中,'a' + 'b'
是一个常量表达式,它的值将适合于一个 char
,所以编译器允许将 int
表达式结果的隐式缩小为 char
。y
是一个变量,因此 y + 'b'
不是一个常量表达式。即使Blind Freddy也能看出值将适合,编译器也不允许任何隐式缩小,并且您会得到一个编译错误,指出无法将 int
赋值给 char
。
在这种情况下,有一些其他注意事项关于何时允许隐式的缩小原始转换;请参阅JLS 5.2和JLS 15.28获取完整详情。
后者详细解释了常量表达式的要求。 它可能不是您想象中的那样。(例如,仅将y
声明为final
是没有帮助的。)
char
被表示为 Unicode
值,其中 Unicode 值由 \u
后跟 十六进制
值表示。
由于任何应用于 char
值并提升为 int
的算术运算,因此 'a' + 'b'
的结果计算如下:
1.) 使用 Unicode 表
将相应的 char
应用于 Unicode
值
2.) 应用 十六进制转十进制 并在 Decimal
值上执行操作。
char Unicode Decimal
a 0061 97
b 0062 98 +
195
例子
0061
0062
97 + 98 = 195
例子2
char Unicode Decimal
Ջ 054b 1355
À 00c0 192
--------
1547 +
1163 -
7 /
260160 *
11 %
char
,那么'a' + 'b'
的值将不是195
而是'Ã'
。 - Joren