• JAVA核心技术I---JAVA基础知识(不可变对象和字符串)


    一:不可变对象

    不可变对象(Immutable Object)
    –一旦创建,这个对象(状态/值)不能被更改了–其内在的成员变量的值就不能修改了。
    –典型的不可变对象
    • 八个基本型别的包装类的对象String,BigInteger和BigDecimal等的对象
    可变对象(Mutable Object)
    –普通对象

    (一)普通对象:可修改值

            //普通对象
            genobj go = new genobj();
            genobj go2 = go;    //两个指针指向一个对象
            
            System.out.println(go.getnumber());
            System.out.println(go2.getnumber());
            go2.setnumber(16);
            
            System.out.println(go.getnumber());
            System.out.println(go2.getnumber());
            if(go==go2) {
                System.out.println("obj1==obj2");
            }
    12
    12
    16
    16
    obj1==obj2

    (二)不可变对象,不允许修改值

            //8个基本包装类
            Integer I1=12;
            Integer I2=I1;
            
            System.out.println(I1);
            System.out.println(I2);
            
            if(I1==I2) {
                System.out.println("I1==I2");
            }
            
            I2 = 13;    //修改值
            System.out.println(I1);
            System.out.println(I2);
            if(I1==I2) {
                System.out.println("I1==I2");
            }else {
                System.out.println("I1!=I2");
            }
            //发现原来的内存地址的值I1并没有修改,还是12,只是修改了对象指针I2的指向,指向13的内存
    12
    12
    I1==I2
    12
    13
    I1!=I2

    (三)在函数参数中体现不可变对象

            String a = new String("abc");
            String b = a;
            System.out.println(b);
            a = "def";
            System.out.println(b);
    abc
    abc
    View Code

    函数修改

        public static void main(String[] args) {
            String a = new String("abc");
            System.out.println(a);
            change(a);
            System.out.println(a);
        }
        
        public static void change(String b) {
            b = "def";
        }
    abc
    abc
    View Code

    不可变对象,也是传指针(引用)
    由于不可变,临时变量指向新内存,外部实参的指针不改动

    (四)如何创建一个不可变对象

    –immutable对象是不可改变,有改变,请clone/new一个对象进行修改
    –所有的属性都是final和private的
    –不提供setter方法
    –类是final的,或者所有的方法都是final
    –类中包含mutable对象,那么返回拷贝需要深度clone

    (五)不可变对象优缺点

    不可变对象(Immutable Object)
    优点
    –只读,线程安全
    –并发读,提高性能
    –可以重复使用
    缺点
    –制造垃圾,浪费

    二:字符串

    字符串是Java使用最多的类,是一种典型的不可变对象
    String定义有2种
    –String a = “abc”; //常量赋值,栈分配内存
    –String b = new String(“abc”); //new对象,堆分配内存
    字符串内容比较:equals方法
    是否指向同一个对象:指针比较==
    Java 常量池(Constant Pool)
    –保存在编译期间就已经确定的数据
    –是一块特殊的内存
    –相同的常量字符串只存储一份,节省内存,共享(栈中,不是堆中)

    (一)字符串加法

    String a=“abc”;
    a = a+“def”; //由于String不可修改,效率差。

    使用StringBuffer/StringBuilder类的append方法进行修改(原地修改,扩张StringBuffer/StringBuilder 的对象都是可变对象
    StringBuffer(同步,线程安全,修改快速),
    StringBuilder(不同步,线程不安全,修改更快)
            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());
            
            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());
            
            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());
    20017
    50
    35
    字符串append操作速度:StringBuilder>StringBuffer>String

    (二)字符串函数传递

        public static void changeValue(int a)
        {
            a = 10;
        }
        public static void changeValue(String s1)
        {
            s1 = "def";
        }
        public static void changeValue(StringBuffer s1)
        {
            s1.append("def");
        }
        public static void main(String[] args) {
            int a = 5;        //基本类型
            String b = "abc"; //不可变对象
            StringBuffer c = new StringBuffer("abc"); //可变对象
            changeValue(a);  //基本类型,传值
            changeValue(b);  //不可变对象,传引用,但是不允许修改
            changeValue(c);  //可变对象,传引用,可以修改值
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
        }

    三:StringBuffer和StringBuilder比较

    StringBuffer(字符串加减,同步,性能好)
    StringBuilder(字符串加减,不同步,性能更好)
    StringBuffer/StringBuilder: 方法一样,区别在同步
    –append/insert/delete/replace/substring –length 字符串实际大小,capacity字符串占用空间大小  空间大小为实际大小加一,再两倍
    –trimToSize(): 去除空隙,将字符串存储压缩到实际大小
    –如有大量append,事先预估大小,再调用相应构造函数
  • 相关阅读:
    Java openrasp学习记录(一)
    Java ASM3学习(3)
    Java ASM3学习(2)
    Java Instrumentation插桩技术学习
    Java ASM3学习(1)
    从JDK源码学习HashSet和HashTable
    从JDK源码学习HashMap
    从JDK源码学习ArrayList
    Java XXE漏洞典型场景分析
    CVE-2020-7961 Liferay Portal 复现分析
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10196488.html
Copyright © 2020-2023  润新知