java面试 (七)- 关于String

 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;
}

 2 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 存储的数据越大,遍历的时间复杂度就会增加。如果数据过大,会增加整个字符串常量池的负担。

   

原文地址:https://www.cnblogs.com/liufei1983/p/11785229.html