【问题标题】:char + int gives unexpected resultchar + int 给出了意想不到的结果
【发布时间】:2021-04-22 13:05:02
【问题描述】:

我需要打印 'H3110 w0r1d 2.0 true' 作为输出。 下面是编写并输出为“3182 w0r1d 2.0 true”的代码。

public class HelloWorld {
    public static void main (String[] args){

        char c1= 'H';
        int num1 = 3110;
        char c2='w';
        byte b=0;
        char c3='r';
        int y=1;
        char c4='d';

        float f = 2.0f;
        boolean bool= true;
        String s = c1+num1 + " " + c2+b+c3+y+c4 + " " + f + " " + bool;
        System.out.println(s);
    }
}

查询:如果我连接H3110,则打印为3182。为什么会这样?

【问题讨论】:

  • 因为char在添加之前基本上被提升为int。如果你改用字符串 (string c1 = "H";) 就可以了。
  • 在像char + int这样的情况下,char首先被转换为int(它对应的Unicode值(对于初学者,在这种情况下是ASCII表中的索引))然后它是常规的int + int 加法。

标签: java type-conversion string-concatenation


【解决方案1】:

+ 运算符不使用字符串连接,除非至少有一个操作数是String 类型。忽略+ 运算符的其余部分,您基本上是在寻找“如果我将charint 添加在一起会发生什么” - 答案是“char 被提升为int,并且是普通整数添加被执行”。 'H' 的提升值为 72(因为这是 'H' 的 UTF-16 数值),因此结果为 3182。

在您的情况下,最简单的解决方法是将c1 的类型更改为String 而不是char

String c1 = "H";

这将使用字符串连接而不是整数加法。

【讨论】:

  • 好吧,准确地说,'H' 即使没有升级为int 也是72,因为根据Java,char 是一个16 位无符号整数语言规范。
  • 很好的解释,但是使用 StringBuilder 更安全。
  • @IQbrod 更安全 可能是错误的术语来解释为什么应该首选StringBuilder。性能可能更准确。但是请注意,在这种特殊情况下它并不适用,因为 Java 已经优化了单语句连接,即 a + b + c + d(通过在早期版本中使用 StringBuilder 本身,甚至在之后使用更好的机制)。
【解决方案2】:

您应该使用在 Java 5 中引入的 StringBuilder,它具有 .append() 和 char/int/long 等方法... 此类是 Java 中正确的字符串连接器,允许您通过其字符串表示连接任何原语(char/int/long ...)。

System.out.println(4+3+"s"); // will print "7s"
System.out.println(StringBuilder.append(4).append(3).append("s").toString()); // will print "43s"

正如@Zabuzard 所提到的,Java 编译器会将字符串总和 (+) 替换为 StringBuilder,但 char+int 确实返回 int(并且 int 不是 String)。 获取关于char + int返回int的详细解释。 我建议你@JonSkeet 回答:)

public class Main {
    public static void main(String[] args) {
        char c1= 'H';
        int num1 = 3110;
        char c2='w';
        byte b=0;
        char c3='r';
        int y=1;
        char c4='d';

        float f = 2.0f;
        boolean bool= true;
        String s = new StringBuilder()
                .append(c1)
                .append(num1)
                .append(c2)
                .append(b)
                .append(c3)
                .append(y)
                .append(c4)
                .append(f)
                .append(bool)
                .toString();
        System.out.println(s);
    }
}

【讨论】:

  • 虽然这个答案提供了一个有价值的解决方案,但如果它能够解释 OP 问题以及解决问题的原因也会很好。
  • @Zabuzard Jon 做得很好,我不会复制粘贴他的答案
  • 公平。但是请注意,在这种特殊情况下,StringBuilder 与普通串联 a + b + c + d 相比没有任何优势。由于 JLS 要求任何 Java 实现都必须优化此类连接。 StringBuilder 仅在连接发生在多个语句(通常在循环中)时才具有性能优势。
  • OP 期望 + 作为字符串连接器,但在 Java 中,正确的字符串连接器是 StringBuilder.append(),这可以防止 char+int 混淆返回 int
  • 这是公平的,这就是为什么我建议添加更详细的解释来突出这一方面。
【解决方案3】:

这个问题的另一个解决方案可能是使用静态方法

String.valueOf(c1)

更好的方法是使用前面提到的 StringBuilder,但使用 String.valueOf 是另一种解决方案,对代码的影响比使用 StringBuilder 的效果要小。

【讨论】:

  • 谢谢大家的详细解释
猜你喜欢
  • 2019-05-19
  • 2017-01-05
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 2016-02-13
  • 2017-11-05
  • 1970-01-01
相关资源
最近更新 更多