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

       

  • 相关阅读:
    android用户界面之WebView教程实例汇总
    android用户界面之TabHost教程实例汇总
    手把手教你写android项目@第一期项目——身份证查询创新(项目总结)
    android用户界面之GridView教程实例汇总
    android学习从模仿开始 —— 模仿UI 导航帖
    Android 实现书籍翻页效果
    android用户界面之Widget教程实例汇总
    如何安装webdriver chrome浏览器支持
    Seleniumwebdriver系列教程(15)————使用已存在的profile启动firefox
    ruby设计模式之【观察者】模式1————简单的观察者模式
  • 原文地址:https://www.cnblogs.com/liufei1983/p/11785229.html
Copyright © 2011-2022 走看看