在添加'a' + 'b'
时产生195。是输出数据类型char
还是int
??
在添加'a' + 'b'
时产生195。是输出数据类型char
还是int
??
Answers:
添加Java字符,短裤或字节的结果是一个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
如果您对性能感兴趣,请注意,Java字节码甚至没有专用于较小数据类型的算术指令。例如,要进行添加,有指令iadd
(用于整数),ladd
(用于多头),fadd
(用于浮点数),dadd
(用于双精度数),仅此而已。为了模拟x += y
较小的类型,编译器将使用iadd
诸如i2c
int char的指令,然后将int的高字节清零。如果本机CPU具有用于1字节或2字节数据的专用指令,则取决于Java虚拟机在运行时对其进行优化。
如果要将字符串连接为字符串而不是将它们解释为数字类型,则有很多方法可以做到这一点。最简单的方法是在表达式中添加一个空String,因为添加char和String会生成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')
您可能希望学习有关的以下表达式char
。
char c='A';
int i=c+1;
System.out.println("i = "+i);
这在Java中是完全有效的,并且返回66
字符(Unicode)的对应值c+1
。
String temp="";
temp+=c;
System.out.println("temp = "+temp);
这在Java中太有效了,并且String类型变量会temp
自动接受c
char类型并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就是其中的最佳来源之一:转化和促销。特别是,请阅读“ 5.1.2扩展基元转换”的简短内容。
Java编译器可以将其解释为任一。
通过编写程序并查找编译器错误来进行检查:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
如果是字符,则第一行将给我一个错误,而第二行则不会。如果它是一个int,则相反。
我编译了它,我得到了.....没有错误。因此Java都接受。
但是,当我打印它们时,我得到:
整数:195
字符:
发生的事情是当您执行以下操作:
char result2 = 'a' + 'b'
执行隐式转换(从int到char的“原始缩小转换” )。
尽管您已经有了正确的答案(在JLS中已引用),但是这里有一些代码可以验证int
添加两个char
s时是否得到一个。
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
变量。后者给出了一个编译错误,实际上是“您不能将an分配int
给char
”。
char
表示为Unicode
值,其中Unicode值\u
后跟Hexadecimal
值。
由于对char
值提升为的任何算术运算int
,因此的结果'a' + 'b'
计算为
1.)应用Unicode
上的相应值char
使用Unicode Table
2.)将 十六进制转换为十进制,然后对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 %
尽管Boann的答案是正确的,但当常量表达式出现在赋值上下文中时,有一种复杂情况适用于常量表达式。
请考虑以下示例:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
到底是怎么回事?他们是说同一件事不是吗?为什么在第一个示例中将分配int
给a合法char
?
当常量表达式出现在赋值上下文中时,Java编译器将计算该表达式的值,并查看它是否在您要分配的类型的范围内。如果是,则应用隐式缩小原语转换。
在第一个示例中,'a' + 'b'
是一个常量表达式,其值将适合于char
,因此编译器允许将int
表达式结果隐式缩小为char
。
在第二个示例中,y
是变量,因此y + 'b'
不是常量表达式。因此,即使Blind Freddy可以看到该值合适,编译器也不允许任何隐式变窄,并且您会收到编译错误,指出int
无法将an分配给char
。
关于在这种情况下何时允许隐式变窄原语转换,还有其他一些警告。有关完整的详细信息,请参见JLS 5.2和JLS 15.28。
后者详细解释了对常量表达式的要求。可能不是您想的那样。(例如,仅声明y
为asfinal
并没有帮助。)
char
那么的值'a' + 'b'
不会是195
,但'Ã'