资讯专栏INFORMATION COLUMN

String那些事

gghyoo / 3352人阅读

摘要:的不可变性众所周知,是常量,不可变,这一点很重要。那中,包装类的一个特质就是值操作时体现对应的基本类型的特质。同样的,等这些包装类和在这种情况下的表现是相同的。那么无论你对传入参数做了什么操作,都不会影响原来的值。

1. String的不可变性

众所周知,String是常量,不可变,这一点很重要。
其底层的实现是char[]

    /** The value is used for character storage. */
    private final char value[];

而且,它是final的。

看两个构造函数:

    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    /**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

其内部的很多方法,也是会新生成一个char[]来构造一个新的String对象返回。
例如replace:

    /**
     * Returns a new string resulting from replacing all occurrences of
     * oldChar in this string with newChar.
     */
public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

doc中写的很明白,这个方法,会新生成一个String对象返回。

所以类似

str = str.replace("a","b");
str = str.substring(2);
str = str.toLowerCase();

都会生成新的对象。原来的对象还是存在的,只是没有引用指向它,等待被垃圾回收。

2.传递String类型参数

看一个例子:

public class StringTest {
    public static void main(String[] args) {
        StringTest stringTest = new StringTest();
        
        String string = "abc";
        stringTest.replace(string);
        System.out.println(string);

        Integer i = 1;
        stringTest.add(i);
        System.out.println(i);
    }

    public void replace(String string) {
        string = string.replace("a", "b");
        string = string.toUpperCase();
        System.out.println("inner:" + string);
    }

    public void add(Integer integer) {
        integer++;
        System.out.println("inner:" + integer);

    }
}

Stirng内部实现时,是用char[] 来存储字符串的,所以String相当于char[]的包装类。那java中,包装类的一个特质就是值操作时体现对应的基本类型的特质。同样的,Integer、Float等这些包装类和String在这种情况下的表现是相同的。

分析一下,主要是还是由于包装类内部实现方式导致的。
包装类内部存储结构是final的原生类型,或原生类型数组,是不可变的。之后所做的操作都会新生成一个对象来返回。那么无论你对传入参数做了什么操作,都不会影响原来的值。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65679.html

相关文章

  • href的那些

    摘要:看个问题此时的值是什么呢带着这样的疑问,开始今天的话题的那些事。问题分析为什么会有这个问题呢上周在项目中,会对页面标签绑定些事件,会用到内容。总结写在最后,对于的事情还不完整,欢迎补充补充。 看个问题test,此时href的值是什么呢?带着这样的疑问,开始今天的话题‘href的那些事’。 问题分析 为什么会有这个问题呢?上周在项目中,msui会对页面a标签绑定些事件,会用到href内容...

    rose 评论0 收藏0
  • 浅谈隐式类型转换与显示类型转换的那些

    摘要:隐式类型转换类型转类型先定义一个类型的变量只要类型跟类型还是类型用号,其他类型都会被转为字符串输出结果字符串类型转类型或者类型定义类型的变量与类型的变量前端从测试结果可以看出,类型在跟数字类型做乘除减运算时,得到的是数字类型的值,但是类型必 隐式类型转换 number类型转string类型 //先定义一个number类型的变量 //只要string类型跟boolean类型还是numbe...

    atinosun 评论0 收藏0
  • [登录那些] 邮件发送,限流,漏桶与令牌桶

    摘要:关于如何限速,有两个比较出名的算法,漏桶算法与令牌桶算法,这里对其简单介绍一下,最后再实践在我发邮件的中以下是发送邮件的,已限制为一分钟两次,你可以通过修改进行试验。 前段时间,我使用了 jwt 来实现邮箱验证码的校验与用户认证与登录,还特别写了一篇文章作为总结。 在那篇文章中,提到了一个点,如何限速。 在短信验证码和邮箱验证码,如果不限速,被恶意攻击造成大量的 QPS,不仅拖垮了服务...

    wpw 评论0 收藏0
  • 【面试】Java基础的那些-Thr

    摘要:为了提高程序运行的效率,在软件发布后,检查默认是被关闭的。注意不能保证原子性,不能代替,且其会阻止编译器对代码的优化。以下方法用来判断一个字符串中是否包含中文字符。 前言 面试中对于技术职位,一般分笔试与面谈,如果面试官的一些小问题你可以立马找到对应的知识点扩展开来,那么这就是你的优势,本系列将讲述一些java面试中的事,不会很详细,但是应该比较全面吧。 主要内容 assert有什么作...

    ShowerSun 评论0 收藏0
  • 微信小程序登录那些

    摘要:小程序的登录跟平时自己这种登录验证还不太一样,多了一个角色,那就是微信服务器。的有效期默认是小时,当用户一直在使用小程序的话会自动刷新,这个是由微信这边来维护的。 最近团队在开发一款小程序,都是新手,一边看文档,一边开发。在开发中会遇到各种问题,今天把小程序登录这块的流程整理下,做个记录。 小程序的登录跟平时自己APP这种登录验证还不太一样,多了一个角色,那就是微信服务器。 showI...

    kid143 评论0 收藏0

发表评论

0条评论

gghyoo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<