1 String的定义(Java8中)

// final的类,不能被继承
// 继承了序列化接口,comparable接口,
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]; // char数组(双字节),存储String的内容。
// char数组是final的,所以String不能改 /** Cache the hash code for the string */
private int hash; // Default to 0

// JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,
// JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。
// 如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常,即是InvalidCastException。
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
    // 计算hashcode的算法,可以用来做hashMAP的key, hahscode算法一定要快,如下的算法中乘以31,可以用位移实现,
// 用位移实现的算法计算速度要比其他的快
public int hashCode() {
       int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

String 对象的创建方式

  A、通过字符串常量的方式

            String str= "pingtouge", JVM 会在字符串常量池中先检查是否存在该对象,如果存在,返回该对象的引用地址,如果不存在,则在字符串常量池中创建该字符串对象并且返回引用。使用这种方式创建的好处是:避免了相同值的字符串重复创建,节约了内存。

  BString()构造函数的方式:

             String str = new String("pingtouge"):使用这种方式创建字符串对象过程就比较复杂,分成两个阶段,首先在编译时,字符串pingtouge会被加入到常量结构中,类加载时候就会在常量池中创建该字符串。然后就是在调用new()时,JVM 将会调用String的构造函数,同时引用常量池中的pingtouge字符串,在堆内存中创建一个String对象并且返回堆中的引用地址。

String 对象的不可变性

String类不能被继承。这是String不可变的第一点

char value[]数组被private 和final修饰,这是String不可变的第二点

4 Java 公司为什么要将String设置成不可变的,主要从以下三方面考虑:

  A、保证 String 对象的安全性。假设 String 对象是可变的,那么 String 对象将可能被恶意修改。

  B、保证 hash 属性值不会频繁变更,确保了唯一性,使得类似 HashMap 容器才能实现相应的 key-value 缓存功能。

  C、可以实现字符串常量池。

String 对象的优化

   不涉及多线程,用StringBuilder 进行拼接,提升系统性能;如果涉及到线程安全的话,我们使用 StringBuffer 来进行字符

巧妙的使用 intern() 方法

   intern 函数用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。否则,在常量池中加入该对象,然后 返回引用(也就是说使用intern() 的时候,并不是在堆上创建对象,而是直接使用常量池中的引用)

  注意: String.intern()方法虽然好,但是我们要结合场景使用,不能乱用,因为常量池的实现是类似于一个HashTable的实现方式,HashTable 存储的数据越大,遍历的时间复杂度就会增加。如果数据过大,会增加整个字符串常量池的负担。

  

最新文章

  1. 关于 htonl 和 ntohl 的实现
  2. Unity协程(Coroutine)原理深入剖析
  3. Windows Phone获得IsolatedStorage中指定目录下的所有文件
  4. .Net使用JsonSchema验证Json
  5. JSP4(内置对象)
  6. Leetcode_144_Binary Tree Preorder Traversal
  7. Codeforces Round #483 (Div. 2) C. Finite or not?
  8. 如何在ASP.NET Core中自定义Azure Storage File Provider
  9. 原生js显示消失
  10. 使用 NPOI 导出 Excel 文件
  11. SQLServer2016 AlwaysOn AG基于工作组的搭建笔记
  12. 搭建openstf平台的那些事
  13. centos下通过pid查看进程的绝对路径的方法
  14. Handler相关
  15. Linux 小知识翻译 - 「Linux」和病毒
  16. linux如何安装多个jdk?
  17. fixed不能罩住下面的内容
  18. 新浪微博基于MySQL的分布式数据库实践
  19. java链表知识点总结
  20. 在Docker容器中运行Spring Boot的jar包 jar外的配置文件无法生效

热门文章

  1. 【后缀表达式求解】No.3.栈-evaluate-reverse-polish-notation题解(Java版)
  2. jmeter脚本中请求参数获取的几种方式
  3. javascript Object and new object() object --构造函数
  4. HDU-2196-Computer(树上DP)
  5. App版本更新接口的设计
  6. 数据库服务器和web服务器磁盘占用查询
  7. 学到了林海峰,武沛齐讲的Day49 django
  8. RESTful API Design: 13 Best Practices to Make Your Users Happy
  9. 2019.12.06 java基础代码
  10. zabbix server内存突然飙升