一提到java的String首先想到的应该就是它的不可变性,其原因是因为String类的内部是使用一个private final char value[]的字符数组来存储数据,本身没有相应的set方法,同时String类又是final的,所以该内部数组就与外界隔绝了,唯一的方法就是通过反射破除private的限制,虽然value[]也是final的,我们不可以修改其内部的数据,但是可以修改其引用的指向从而改变String的值。

至于为什么要把String设计成不可变的,首先,究其原因还是因为字符串是我们编程过程中最经常使用的对象,所以有必要在其使用内存时做一些优化,其中一个优化就是字符串常量池,在这个池中不存在两个相同值的字符串。对于字符串,其对象的引用都是存储在栈中的,对于对象本身,如果是编译期就确定其值的话(比如直接使用双引号创建)就会存储在常量池中,如果是运行期才能确定其值的话(比如使用new创建)就会存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中可以有多份。

对于语句String str = new String("abc")执行时,会先去常量池中查找是否存在字符串“abc”对象,如果没有则先在常量池中创建“abc”对象,再将该对象拷贝到堆中。如果已经存在的话则将其直接拷贝到堆中。如果我们想直接获取一个存储在常量池的字符串对象,可以使用intern()方法,例如String s1 = new String("abc");s2 = s1.intern();注意,此时s1.equals(s2)是true,但是s1==s2是false,因为s1是指向堆中的“abc”对象,s2是指向常量池中的“abc”对象。

虽然常量池的使用节省了内存,但是多个引用同时指向常量池中的一个字符串对象时,如果其中一个引用更改了字符串的值,其他几个便会受到影响,而字符串的不可变性则完全避免了这种问题的出现。

其次,因为String对象的内部值不可改变,所以其自身的hashCode值也不会改变,所以每一个字符串的hashCode都会被提前计算好缓存在自身对象中,所以我们经常使用String作为HashMap的键,这样在查询时便节省了计算hashCode的步骤,同时因为String的不可变性,也不会出现因为某个键改变后与其他键冲突的情况。

最后,因为String对象是不可变的所以它肯定是线程安全的,至于字符串拼接返回新对象的问题,本文就不在此赘述。

浅谈java的String字符串的更多相关文章

  1. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  2. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  3. 【转】浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  4. 浅谈Java的反射机制和作用

    浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...

  5. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  6. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  7. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

  8. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  9. 【转】浅谈Java中的hashcode方法(这个demo可以多看看)

    浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...

随机推荐

  1. Objective-C中的Hello World

    Objective-C在C语言的基础之上,加入了自己的一些独特的特性,而且在Objective-C中兼容C语言原有的用法.在Objective-C中,实现Hello World和C语言有一定的区别,如 ...

  2. iPhone的刷机 iPhone进UDF

    首先是进入udf出现问题.. 要点是 黑屏后按电源键到屏幕亮了+HOME键再一直按 按到黑屏 4秒左右后 放开HOME键 再按大概7秒就是udf界面了 不是界面~全黑的.你可以电源键是开不了机的. 然 ...

  3. iOS 之 内存检查instrument

    经常听见iOS开发instrument是一个内存检查工具,但是,没想到,它是集成在xcode里面的,而且打开一看,感觉功能非常强大. 打开方式是 product -> profile 头一次运行 ...

  4. ios自定义UIButton内部空间Rect

  5. webpack之代码分离

    https://robertknight.github.io/posts/webpack-dll-plugins/ webpack一般会把一个文件里import/require的文件都会打包在一起,最 ...

  6. iOS 之 alcatraz (插件管理器)

    1. 安装 1.1. 打开命令行 curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/deploy/Scripts/ins ...

  7. 建立、配置和使用Activity——启动其他Activity并返回结果

    Activity还提供了一个startActivityForResult(Intent intent,int requestCode)方法来启动其他Activity.该方法用于启动指定Activity ...

  8. Promise基础

    前言: ES2015将Promise引入语言规范,包括fetch等在内的API也构建在Promise之上.作为让js摆脱“回调地狱”的重要一环和众多框架中的重要基础设施之一,学习如何自己实现一个Pro ...

  9. HTML 表单和输入

    HTML 表单 表单是一个包含表单元素的区域. 表单元素是允许用户在表单中输入内容,比如:文本域(textarea).下拉列表.单选框(radio-buttons).复选框(checkboxes)等等 ...

  10. HTTP协议系列(3)---包括WebSocket简单介绍

    一.HTTPS     HTTP是超文本传输协议,那HTTPS是什么尼?要明白HTTPS是什么先要明白HTTP的缺点,想一下我们在使用HTTP的时候会有那些缺点尼? 1.通信使用的明文(不加密),内容 ...