java - String类如何重写+运算符?

标签 java string object

为什么在 Java 中,当 String 是一个类时,您可以使用 + 运算符添加字符串?在String.java代码中我没有找到这个运算符的任何实现。这个概念违反了面向对象吗?

最佳答案

让我们看一下 Java 中的以下简单表达式

int x=15;
String temp="x = "+x;

编译器在内部将 "x = "+x; 转换为 StringBuilder 并使用 .append(int) 将整数“添加”到字符串中。

<强> 5.1.11. String Conversion

Any type may be converted to type String by string conversion.

A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression (§15.9):

  • If T is boolean, then use new Boolean(x).
  • If T is char, then use new Character(x).
  • If T is byte, short, or int, then use new Integer(x).
  • If T is long, then use new Long(x).
  • If T is float, then use new Float(x).
  • If T is double, then use new Double(x).

This reference value is then converted to type String by string conversion.

Now only reference values need to be considered:

  • If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).
  • Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.

The toString method is defined by the primordial class Object (§4.3.2). Many classes override it, notably Boolean, Character, Integer, Long, Float, Double, and String.

See §5.4 for details of the string conversion context.

<强> 15.18.1.

Optimization of String Concatenation : An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.

优化版本实际上不会首先执行完全包装的字符串转换。

这是编译器使用的优化版本的一个很好的说明,尽管没有转换原语,您可以在其中看到编译器在后台将内容更改为 StringBuilder:

http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/

<小时/>

这段java代码:

public static void main(String[] args) {
    String cip = "cip";
    String ciop = "ciop";
    String plus = cip + ciop;
    String build = new StringBuilder(cip).append(ciop).toString();
}

生成这个 - 查看两种串联样式如何产生完全相同的字节码:

 L0
    LINENUMBER 23 L0
    LDC "cip"
    ASTORE 1
   L1
    LINENUMBER 24 L1
    LDC "ciop"
    ASTORE 2

   // cip + ciop

   L2
    LINENUMBER 25 L2

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 3

    // new StringBuilder(cip).append(ciop).toString()

   L3
    LINENUMBER 26 L3

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 4
   L4
    LINENUMBER 27 L4
    RETURN

查看上面的示例以及如何生成基于给定示例中的源代码的字节码,您将能够注意到编译器已在内部转换了以下语句

cip+ciop; 

进入

new StringBuilder(cip).append(ciop).toString();

换句话说,字符串连接中的运算符+实际上是更详细的StringBuilder习惯用法的简写。

关于java - String类如何重写+运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57185523/

相关文章:

java - CRUDRepository 中的 Update 或 saveorUpdate

java - 给定 2 个字符串,仅删除一位数字以使 1 个字符串按字典顺序更小

javascript - 如何使用 MooTools 将表单数据转换为对象

Java并发实践 "Listing 7.1. Using a volatile field to hold cancellation state."。同步可见性?

java - StreamCorruptedException : invalid type code: AC

php - MySQL 的 LOWER() 和 PHP 的 mb_strtolower() 返回相同的结果?

fgets 回车

java - 每次创建对象时都会有新的引用变量?

java - 使用 equals 方法比较两个对象,Java

Java 对象模型和类型识别方法