How does the String class override the + operator?

前端 未结 7 1994
刺人心
刺人心 2020-11-22 12:25

Why in Java you\'re able to add Strings with the + operator, when String is a class? In theString.java code I did not find any implementation for this operator

相关标签:
7条回答
  • 2020-11-22 12:31

    The + operator is usually replaced by a StringBuilder at compile time. Check this answer for more details on that matter.

    0 讨论(0)
  • 2020-11-22 12:36

    How String class overrides + operator?

    It doesn't. The compiler does it. Strictly speaking, the compiler overloads the + operator for String operands.

    0 讨论(0)
  • 2020-11-22 12:44

    The meaning of the + operator when applied to String is defined by the language, as everyone has written already. Since you don't seem to find this sufficiently convincing, consider this:

    Ints, floats and doubles all have different binary representations, and therefore adding two ints is a different operation, in terms of bit manipulation, than adding two floats: For ints you can add bit by bit, carrying a bit and checking for overflow; for floats you must deal with the mantissas and exponents separately.

    So, in principle, "addition" depends on the nature of the objects being "added". Java defines it for Strings as well as ints and floats (longs, doubles, ...)

    0 讨论(0)
  • 2020-11-22 12:49

    The Java language provides special support for the string concatenation operator (+) and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.

    0 讨论(0)
  • 2020-11-22 12:50

    It is Java compiler feature which checks the operands of + operator. And based on the operands it generates the byte code:

    • For String, it generates code to concat strings
    • For Numbers, it generates code to add numbers.

    This is what the Java spec says:

    The operators + and - are called the additive operators. AdditiveExpression: MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression

    The additive operators have the same precedence and are syntactically left associative (they group left-to-right). If the type of either operand of a + operator is String, then the operation is string concatenation.

    Otherwise, the type of each of the operands of the + operator must be a type that is convertible (§5.1.8)to a primitive numeric type, or a compile-time error occurs.

    In every case, the type of each of the operands of the binary - operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs.

    0 讨论(0)
  • 2020-11-22 12:51

    Let's look at the following simple expressions in Java

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

    The compiler converts "x = "+x; into a StringBuilder internally and uses .append(int) to "add" the integer to the string.

    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.

    The optimized version will not actually do a full wrapped String conversion first.

    This is a good illustration of an optimized version used by the compiler, albeit without the conversion of a primitive, where you can see the compiler changing things into a StringBuilder in the background:

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


    This java code:

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

    Generates this - see how the two concatenation styles lead to the very same bytecode:

     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
    

    Looking at the example above and how the byte code based on the source code in the given example is generated, you will be able to notice that the compiler has internally transformed the following statement

    cip+ciop; 
    

    into

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

    In other words, the operator + in string concatenation is effectively a shorthand for the more verbose StringBuilder idiom.

    0 讨论(0)
提交回复
热议问题