在Java中,是添加两个字符的结果是int还是char?

时间:2011-12-31 14:34:54

标签: java char int primitive addition

添加'a' + 'b'时,它会生成195.输出数据类型为char还是int

9 个答案:

答案 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)

charbyte(和short)上的二进制算术运算推广到int - JLS 5.6.2。

答案 2 :(得分:6)

您可能希望了解有关char

的以下表达方式
char c='A';
int i=c+1;

System.out.println("i = "+i);

这在Java中完全有效,并返回66c+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);

虽然cchar的一种类型,但它可以在各自的构造函数中没有错误地提供,并且所有上述语句都被视为有效语句。它们分别产生以下输出。

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

Unicode To Decimal Converter

示例

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.2JLS 15.28

后者详细说明了常量表达式的要求。可能不是您想的那样。 (例如,仅将y声明为final并没有帮助。)