Java中单引号和双引号的区别是什么?

5

我有

  1. System.out.println(2+" "+3);

  2. System.out.println(2+' '+3);

第一个输出 2 3,而第二个输出 37,有人能解释一下为什么会输出 37 吗?


使用单引号表示字符,双引号表示字符串。当你添加一个字符时,它是一个数字;当你添加一个字符串时,它会追加到原有的字符串后面。 - Peter Lawrey
char和int是对一个值的不同视角。 - Thorbjørn Ravn Andersen
7个回答

4

引用Java语言规范中加法运算符的说明:

如果加法运算符的任一操作数的类型为String,则执行字符串连接操作。

否则,加法运算符的每个操作数的类型必须是可转换(§5.1.8)为原始数字类型的类型

对于数字类型

对操作数执行二进制数字提升(§5.6.2)

二进制数字提升

[...] 否则,将两个操作数都转换为int类型。

因此,2 + " " + 3是字符串拼接,而String + 3也是字符串拼接,所以2 + " " + 3等于"2" + " " + "3",意思是"2 3"2 + ' ' + 32 + ' ',空格字面量是char,所以它被转换为int(32),2 + 32 + 337
如果这些字面量是变量,那么实际上就像这样,其中变量的赋值仅用于说明中间结果的类型:
// String concatenation
String s = new StringBuilder().append(2).append(" ").append(3).toString();
System.out.println(s);

// Numeric addition
int n = 2 + (int)' ' + 3;
System.out.println(n);

append()println()都是重载的方法,所以它们不是完全相同的方法。

由于它们是字面量而不是变量,编译器会在编译时进行操作,您真正得到的是这个结果(尝试反汇编.class文件以查看):

System.out.println("2 3");
System.out.println(37);

3

' '=32在ASCII中代表空格。

a:) System.out.println(2+" "+3); // string concatenation

b:) System.out.println(2+' '+3);  // 2+ 32(32 ascii valur for space)+3 so 37

1
第一个将所有内容转换为字符串。第二个将其转换为整数。空格的十进制代码为32。如果要将2和3转换为字符串,请使用引号。

0
那是因为您正在打印2+ ' ' +3的整数值,它会将' '翻译为char而不是string,这只是将b)部分转换为其ASCII值,结果为2 + Space的ASCII值 + 3,最终结果将是37,因为空格的ASCII值为32。

0
第一个例子是执行字符串连接,所以答案非常直观。第二个例子不同,因为' '不是一个字符串,而是一个字符。该字符被转换为整数代码,这就是为什么你得到那个数字的原因。

0

在这里的串联几乎是 Java 如此宽容的一种情况。在其他上下文中,使用 char ' ' 和 String " " 表现不同:它们是强类型的。


0

除非 System.out.println 的输出参数明确为 java.lang.String,否则 Java 会自动将其作为输出参数给定的任何数据类型和对象转换为 java.lang.String

在您的第一个示例中,System.out.println(2+" "+3);,Java 扫描输出参数并找到一个 int(2),双引号 " ",表示双引号内的字符数组应解释为 String,以及另一个 int(3)。Java 将字符串 " " 的存在视为提示,表明参数中的其他所有内容也应视为字符串处理。因此,实际发生的是该行 System.out.println(2+" "+3); 被视为您编写了

System.out.println(Integer.toString(2)+" "+Integer.toString(3));

在你的第二个例子中,System.out.println(2+' '+3); 发生了同样的过程,但是与其找双引号不同,Java 找到了由单引号包围的 ' ' -- 一个被单引号包围的空格,这告诉 Java 它正在处理原始数据类型 char -- 这就是为什么 Java 将其视为加法操作的原因: 所有 Java 原始数据类型都是数字 -- 因此 Java 接受了这个提示,并将输出参数解释为一个 int(2),加法运算符(+),一个 char(一个空格字符) -- 它与无符号 short 相同,加法运算符(+),和另一个 int(3)。空格字符的数值为32,所以在幕后转换中,您的语句被视为您编写了
System.out.println(Integer.toString(2+32+3));

当然,背后进行的解析比我在这里描述的要复杂得多。为什么不试试:
    System.out.println("The answer is "+(3+" "+2));
    System.out.println("The answer is "+(3+2));
    System.out.println("The answer is "+(3+' '+2));

或者甚至更好

System.out.println('a' + 'b' + 'c');

@Andreas,那么请告诉我们,JVM如何处理布尔值? - user5292387
布尔值存储为true或false的值。它在物理上存储为一个位,就像其他所有东西都存储为一个或多个位一样。 - Andreas
“它在物理上存储为一个位,就像其他所有东西都存储为一个或多个位一样。”这是一个比你想象中更不聪明的回避问题的方式。一个位是1或0,对吗?再说一遍,1和0是什么? - user5292387
这是一个准确而直接的答案。位不是数字,尽管它总是表示为0或1。字符串“Hello”存储为5 * 16 = 80位,但绝不被视为数字。当然,许多其他语言允许将布尔值分配/转换为数字,其中false为0,true为1。Java不是这些语言之一。 - Andreas
对我来说这并不重要。我只是想指出你的陈述不完全正确而已,希望能有所帮助。通常情况下,回答者会在他们的回答中添加额外的“除了布尔类型”的内容,然后问题就解决了。那时我可能会删除评论。你仍然可以这样做,我会删除除第一条评论以外的所有评论。你是否采用这个建议或让你的回答保持不变完全由你决定。 - Andreas
显示剩余5条评论

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