添加'a' + 'b'
时,它会生成195.输出数据类型为char
还是int
?
答案 0 :(得分:115)
添加Java字符,短路或字节的结果是 int :
Java Language Specification on Binary Numeric Promotion:
- 如果任何操作数是引用类型,则取消装箱转换 (§5.1.8)执行。然后:
- 如果任一操作数的类型为double,则为 其他被转换为双倍。
- 否则,如果任一操作数是类型 浮动,另一个转换为浮动。
- 否则,如果是任一操作数 类型为long,另一个转换为long。
- 否则两者兼而有之 操作数转换为int。
But note what it says about compound assignment operators (like +=):
二进制运算的结果转换为左手变量的类型......并且转换结果存储在变量中。
例如:
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
如果您对性能感兴趣,请注意Java bytecode甚至没有关于较小数据类型的算术的专用指令。例如,对于添加,有指示iadd
(对于整数),ladd
(对于长整数),fadd
(对于浮点数),dadd
(对于双精度),以及而已。要使用较小的类型模拟x += y
,编译器将使用iadd
,然后使用类似i2c
(“int to char”)的指令将int的高位字节归零。如果本机CPU具有1字节或2字节数据的专用指令,则可以由Java虚拟机在运行时进行优化。
如果要将字符连接为String而不是将它们解释为数字类型,则有很多方法可以做到这一点。最简单的方法是在表达式中添加一个空字符串,因为添加一个char和一个String会产生一个String。所有这些表达式都会产生字符串"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')
答案 1 :(得分:19)
char
和byte
(和short
)上的二进制算术运算推广到int
- JLS 5.6.2。
答案 2 :(得分:6)
您可能希望了解有关char
。
char c='A';
int i=c+1;
System.out.println("i = "+i);
这在Java中完全有效,并返回66
,c+1
的字符(Unicode)的相应值。
String temp="";
temp+=c;
System.out.println("temp = "+temp);
这在Java中太有效了,String类型变量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);
虽然c
是char
的一种类型,但它可以在各自的构造函数中没有错误地提供,并且所有上述语句都被视为有效语句。它们分别产生以下输出。
intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65
char
是一种原始的数字整数类型,因此受这些野兽的所有规则约束,包括转换和促销。您需要阅读此内容,JLS是最佳来源之一:Conversions and Promotions。特别是,请阅读“5.1.2加宽原始转换”的短位。
答案 3 :(得分:3)
Java编译器可以将其解释为一个。
通过编写程序并查找编译器错误来检查它:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
如果它是一个字符,那么第一行会给我一个错误而第二行不会。 如果它是一个int,则会发生相反的情况。
我编译了它,我得到了.....没有错误。 所以Java同时接受。
然而,当我打印它们时,我得到了:
int:195
char:Ã
当你这样做时会发生什么:
char result2 = 'a' + 'b'
执行隐式转换(从 int 到 char 的“原始缩小转换”)。
答案 4 :(得分:2)
根据binary promotion rules,如果两个操作数都不是double,float或long,则两者都被提升为int。但是,我强烈建议不要将char类型视为数字,这种方法会失败。
答案 5 :(得分:1)
虽然您已经有了正确答案(在JLS中引用),但这里有一些代码可以验证您在添加两个int
时获得char
。
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中
答案 6 :(得分:1)
char
表示为Unicode
值,其中Unicode值由\u
后跟Hexadecimal
值表示。
由于对char
值的任何算术运算都提升为int
,因此'a' + 'b'
的结果计算为
1。)使用Unicode Table
Unicode
上应用char
值
2.。)应用Hexadecimal to Decimal转换,然后对Decimal
值执行操作。
char Unicode Decimal
a 0061 97
b 0062 98 +
195
示例
0061
(0 * 16 3 )+(0 * 16 2 )+(6 * 16 1 )+ (1 * 16 0 )
(0 * 4096)+(0 * 256)+(6 * 16)+(1 * 1)
0 + 0 + 96 + 1 = 97
0062
(0 * 16 3 )+(0 * 16 2 )+(6 * 16 1 )+ (2 * 16 0 )
(0 * 4096)+(0 * 256)+(6 * 16)+(2 * 1)
0 + 0 + 96 + 2 = 98
因此97 + 98 = 195
示例2
char Unicode Decimal
Ջ 054b 1355
À 00c0 192
--------
1547 +
1163 -
7 /
260160 *
11 %
答案 7 :(得分:0)
但这有点奇怪。以下编译:
char x;
x = 'a' + 'b';
但这不是:
char x;
x = 'a';
x = x + 'b';
通过以下测试,似乎两个表达式('a'+'b'和x +'b')都会产生整数:
Object obj = 'a'+'b';
System.out.println(obj.getClass().getName());
char x = 'a';
Object obj2 = x+'b';
System.out.println(obj2.getClass().getName());
那么为什么第二种情况不能编译?顺便说一句,您可以通过将整个表达式转换为char:
来修复它x = (char)(x+'b');
这似乎与Java的语义不一致 - 任何char表达式都应该可以在任何上下文中与另一个表达式互换。有没有人知道如何理解这个?
答案 8 :(得分:0)
虽然Boann's answer是正确的,但是当常量表达式出现在赋值上下文中时,就会出现复杂情况。
请考虑以下示例:
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
。
在这种情况下,是否允许隐式 narrowing原始转换还有其他一些警告;有关详细信息,请参见JLS 5.2和JLS 15.28。
后者详细说明了常量表达式的要求。可能不是您想的那样。 (例如,仅将y
声明为final
并没有帮助。)