Java核心技术系列之华东师范大学Java核心技术第六章不可变对象和字符串

Java核心技术系列之华东师范大学Java核心技术第六章不可变对象和字符串

可变对象与不可变对象

定义

在这里插入图片描述
不可变对象的更改实际上是重新开辟新的数值空间,然后将指针指向新开辟的数值空间。举个例子,
在这里插入图片描述

如何创建不可变对象

在这里插入图片描述

不可变对象优缺点

优点缺点
只读,线程安全制造垃圾,浪费空间(对不可变对象进行修改时,会新开辟空间,旧对象则被搁置,直到垃圾回收)
并发读,提高性能
可以重复使用

字符串

在这里插入图片描述

Java常量池
保存在编译期间就已经确定的数据
是一块特殊的内存
相同的**常量字符串(new出来的不算)**只存储一份,节省内存,共享访问
package chapter6.String;

public class StringPassingTest {
    public static void main(String[] args) {
        String a = "abc";
        changeValue(a);
        System.out.println(a); // "abc"

        a = "abc";
        String b = a;
        a = "def";
        System.out.println(b); // "abc", 这是因为a会被常量化,b是新建的对象指向a,a重新赋值指针由原来指向 "abc" 变成指向 "def",但是字符串b不会改变。
    }

    private static void changeValue(String b) {
        b = "def";
    }
}

在这里插入图片描述

字符串拼接的效率区别

比较Java字符串中的+、StringBuilder(线程不安全)、StringBuffer(线程安全)三者之间的效率问题,代码StringAppendTest.java如下:

package chapter6.String;

import java.util.Calendar;

public class StringAppendTest {
    public static void main(String[] args) {
        int n = 50000;
        Calendar t1 = Calendar.getInstance();
        String a = new String();
        for (int i=0; i<n; i++) {
            a = a + i + ",";
        }
        System.out.println(Calendar.getInstance().getTimeInMillis() - t1.getTimeInMillis()); //3648

        // 线程安全
        Calendar t2 = Calendar.getInstance();
        StringBuffer b = new StringBuffer("");
        for (int i=0;i<n;i++) {
            b.append(i);
            b.append(",");
        }
        System.out.println(Calendar.getInstance().getTimeInMillis() - t2.getTimeInMillis()); // 5

        // 线程不安全
        Calendar t3 = Calendar.getInstance();
        StringBuilder c = new StringBuilder("");
        for (int i=0;i<n;i++) {
            c.append(i);
            c.append(",");
        }
        System.out.println(Calendar.getInstance().getTimeInMillis() - t3.getTimeInMillis()); // 2
    }
}

因此,如果涉及到大量字符串拼接操作,建议使用 StringBuffer 或者 StringBuilder。

传参的区别

  • 当函数参数是基本类别变量时,是传值的。拷贝value给到形参,外围的参数不变。
  • 当函数参数是对象时,传入的是指针。
package chapter6.String;

public class ArgumentPassing {
    public static void main(String[] args) {
        int a = 5;
        String b = "abc";
        StringBuffer c = new StringBuffer("abc");
        changeValue(a);  // 实参=5,形参=5
        changeValue(b);
        changeValue(c);
        System.out.println(a); // 5
        System.out.println(b); // "def"
        System.out.println(c); // "abcdef"
    }

    private static void changeValue(StringBuffer s1) {
        s1.append("def");
    }

    private static void changeValue(String s1) {
        s1 = "def";
    }

    private static void changeValue(int a) {
        a = 10; // 实参=5,形参=10
    }
}

总结

在这里插入图片描述
但是StringBuffer线程安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值