Java中的char类型对于算术运算是有符号还是无符号的?

4

Java中的char是一种16位数据类型,但在进行算术运算时它是有符号还是无符号的呢?

你能将其作为无符号16位整数用于算术运算吗?

例如,下面的表达式正确吗?

char c1;
char c2;

int i = c1 << 16 | c2;

还是必须先将c2的符号扩展位去掉?

(我确信答案已经在其他地方了,但显然搜索不到。)


字符是无符号的,但在位移之前会被提升为整数。 - Michael
https://dev59.com/5mEi5IYBdhLWcg3wpdjJ#21089624 - r3dst0rm
@Michael 我认为这个推广不涉及扩展最高位(因为没有符号位)。 - rghome
1
考虑到第二个答案在那个问题中本质上是错误的(这一点在评论中指出),我认为需要澄清这个问题(因此提出这个问题)。 - rghome
2个回答

8

char是无符号的。来自JLS§4.2.1

对于char,范围从'\u0000'到'\uffff',即从0到65535

但请注意,当您对它们使用任何各种数学运算(包括位运算和移位运算)时,它们会根据另一个操作数的类型扩展为另一种类型,并且该其他类型可能是有符号的:

  1. 扩大基本类型转换(§5.1.2)的应用是为了根据以下规则将一个或两个操作数进行转换:

    • 如果任何一个操作数是double类型,则另一个操作数被转换为double类型。

    • 否则,如果任何一个操作数是float类型,则另一个操作数被转换为float类型。

    • 否则,如果任何一个操作数是long类型,则另一个操作数被转换为long类型。

    • 否则,两个操作数都被转换为int类型。

例如,char + charint类型,因此:

public class Example {
    public static void main(String[] args) {
        char a = 1;
        char b = 2;

        char c = a + b;          // error: incompatible types: possible lossy conversion from int to char
        System.out.println(c);
    }
}

关于位扩展,如果我们按照上面的链接进行原始类型扩展:

将char类型零扩展为整数类型T的扩展转换将表示char值的表示零扩展以填充更宽的格式。

所以char 0xFFFF变成了int 0x0000FFFF,而不是0xFFFFFFFF。

1
谢谢:我感觉文档中指定数字范围的方式(如unicode转义)并没有让人清楚地了解字符在算术上是如何处理的。关键问题是扩展发生的方式。第15位是否被传播? - rghome
@rghome - 已更新答案结尾。不是符号扩展,而是0扩展。 - T.J. Crowder

1

来自规格

对于char类型,范围是从'\u0000''\uffff',即从0到65535。

由于它是16位的,这意味着它们是无符号的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接