String "+"的问题

Java String拼接与null值
本文探讨了Java中String拼接操作时遇到的空指针问题,并详细解释了String类+运算背后的机制,包括如何处理null字符串。

今天项目查bug时,发现一个空指针问题,查了半天,最终定位到是有String +运算造成的.于是就写了一个测试:

public static void main(String [] arg0){
        String a = null;
        String b = "null";
        String c = "===";
        String  ac = a+c;
        String  bc = b+c;
        System.out.println("a+c: " + ac);
        System.out.println("b+c: " + bc);
        System.out.println("a+c == b+c " + ac.equals(bc));
    }

运行结果:

a+c: null===
b+c: null===
a+c == b+c true

原因: Java只是不支持自定义运算符重载,这个String类的+就是运算符重载,也是Java中仅有的一个运算符重载,它是通过编译器实现的,在语法解析阶段就已经确定了.

如:a+c是通过 new StringBuilder().append(a).append(c)实现的.
@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

/**
     * Appends the specified string to this character sequence.
     * <p>
     * The characters of the {@code String} argument are appended, in
     * order, increasing the length of this sequence by the length of the
     * argument. If {@code str} is {@code null}, then the four
     * characters {@code "null"} are appended.
     * <p>
     * Let <i>n</i> be the length of this character sequence just prior to
     * execution of the {@code append} method. Then the character at
     * index <i>k</i> in the new character sequence is equal to the character
     * at index <i>k</i> in the old character sequence, if <i>k</i> is less
     * than <i>n</i>; otherwise, it is equal to the character at index
     * <i>k-n</i> in the argument {@code str}.
     *
     * @param   str   a string.
     * @return  a reference to this object.
     */
public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

通过注释 If {@code str} is {@code null}, then the four characters {@code "null"} are appended 我们可以发现当String字符为空(null)时,append()方法会添加 字符串”null”.

### 实现方式 在循环内部进行 `String` 与常量拼接时,若直接使用 `+` 运算符,编译器会自动调用 `StringBuilder` 类进行字符串拼接以优化性能。例如: ```java public class Test { public static void main(String[] args) { String baseStr = "abc"; for (int i = 0; i < 10; i++) { String str = baseStr + i; System.out.println(str); } } } ``` 上述代码中,`baseStr + i` 这条语句编译器会自动调用 `StringBuilder` 类进行字符串拼接[^2]。 ### 性能问题 直接使用 `+` 运算符进行拼接在循环内部存在性能问题。因为 `String` 是不可变的,每次拼接都会创建新的 `String` 对象。在循环中使用 `+` 拼接,会产生大量临时对象,造成内存的浪费,影响性能。例如: ```java public class BadExample { public static void main(String[] args) { String result = ""; for (int i = 0; i < 10000; i++) { result = result + i; } } } ``` 在这个例子中,每次循环都会创建新的 `String` 对象,性能较低。 ### 优化建议 为了提高性能,对于字符串变量的拼接,应使用 `StringBuilder` 或 `StringBuffer`。`StringBuilder` 是非线程安全的,在单线程环境下性能更高;`StringBuffer` 是线程安全的,适用于多线程环境。例如使用 `StringBuilder` 优化上述代码: ```java public class GoodExample { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append(i); } String result = sb.toString(); } } ``` 这样可以避免创建大量临时对象,提高性能[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值