【问题标题】:Why does + work with Strings in Java?为什么 + 与 Java 中的字符串一起使用?
【发布时间】:2011-07-24 18:34:51
【问题描述】:

Java 不能进行运算符重载,但 + 可以用于 StringInteger 以及其他一些类。这怎么可能?

更新:
为什么会这样?

Integer i = 4;
Integer p = 5;

System.out.println(i*p); // prints 20

【问题讨论】:

    标签: java string operator-overloading string-concatenation


    【解决方案1】:

    由于autoboxing,它适用于像 Integer 这样的原始包装器。

    它适用于字符串,因为那是 special case for concatenating strings:

    Java 语言为字符串连接运算符 ( + ) 以及将其他对象转换为字符串提供了特殊支持。字符串连接是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,由 Object 定义并由 Java 中的所有类继承。有关字符串连接和转换的更多信息,请参阅 Gosling、Joy 和 Steele,Java 语言规范。

    【讨论】:

      【解决方案2】:

      + 是一个内置操作。这是一个例外,而不是规则。

      【讨论】:

      • 谢谢。但是为什么它可以与其他类(如 Integer)一起使用,请查看更新后的问题
      • 编译器在将源代码消化成 Java IL 时会简单地解析运算符。有对数字有效的加、减、乘等 IL 级指令。 另外,+ 被硬编码以处理字符串;编译器会将 "a" + "b" 翻译成 IL 级指令以连接 "a" 和 "b"。
      【解决方案3】:

      Java 不允许 custom 运算符重载,但编译器开发人员仍然可以告诉编译器 String1 + String2 == String1String2,并用正确的连接方法调用替换 + 运算符.

      【讨论】:

        【解决方案4】:

        + 不是运算符重载的示例。 + 作为连接运算符算术加法运算符内置于语言中。

        这意味着用Java编写程序的人不能重载运算符,但就Java语言的语法而言,+被定义为连接和加法运算符。

        编辑

        由于autoboxing,它适用于其他类,例如IntegerDouble

        如果您查看执行字符串连接的 Java 程序的字节码,您会看到它创建了 StringBuilder 并使用了 append() 方法。 Java 编译器看到+ 运算符并意识到操作数是字符串而不是原始类型(如int)。

        如果您查看执行整数加法的程序的字节码,您会发现它使用iadd 指令来执行整数加法。这是因为编译器意识到+ 操作的操作数是整数。

        就执行Integer i = 4 之类的操作而言,字节码将显示您实际上正在执行Integer i = Integer.valueOf(4)。这称为自动装箱。稍后,当您执行i + p 之类的操作时,其中ip 的类型均为Integer,生成的字节码将显示您正在执行i.intValue() + p.intValue(),这两种方法的返回类型都是int(实际的字节码指令又是iadd)。

        这就是为什么 + 可以在 Integer 工作,即使它们不是实际的原始类型。

        【讨论】:

        • 谢谢!是否有所有支持自动装箱的类的列表?
        • 我相信 intfloatdoublebooleanshortbyte 存在自动装箱。
        【解决方案5】:

        Java 语言为字符串连接运算符 ( + ) 以及将其他对象转换为字符串提供了特殊支持。

        String s = "string 1" + "string 2";
        

        实际执行的是

        (new StringBuilder()).append("string 1").append("string 2").toString()
        

        【讨论】:

          【解决方案6】:

          正如@yan 所说,这是例外,而不是规则。字符串在 Java 中具有特殊的地位。 Java 语言规范中有一个完整的小节专门介绍 + 作为字符串连接运算符的作用:§15.18.1

          关于您的更新,这是另一种特殊情况。 Java 有时,根据具体情况,足够聪明,可以在需要Strings 时将不是Strings 的东西转换为Strings。这些特殊情况之一就是您描述的情况,其中原语出现在需要String 的地方。原语首先转换为它们的引用类型——IntegerDouble 等。 — 然后通过toString() 方法进入Strings。

          另一种特殊情况是当String 和一个非String 与字符串连接运算符+ 组合时,如JLS §5.4 — String Conversion 中所述。

          为了完整起见:+ 在其更常见的“将数字相加”角色中描述了 §15.18 的另一部分,§15.18.2 — Additive Operators (+ and -) for Numeric Types

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-03
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 2023-03-13
            • 2012-08-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多