首页 > 其他 > 详细

关于String

时间:2020-03-03 14:23:45      阅读:60      评论:0      收藏:0      [点我收藏+]

1、String类的修饰符

这是一个final的类,不可继承,创建的对象不可变

public final class String implements java.io.Serializable, Comparable<String>, CharSequence{}

为什么String要设计成不可变的类?

有以下几个方面可以思考:

1、为了实现字符串常量池,提高效率

2、安全,设计为final的,保证在多线程的时候是安全的,可以被多个线程共享

3、String设计的时候缓存了hash值,不需要重新计算,如果是可变的,每次都需要重新计算

2、主要成员变量

private final char value[]; //使用字符数组存放字符串
private int hash; // Default to 0  缓存哈希值

3、equals()方法

重写了Object的equals()方法,判断两个字符串的每一个字符是否相等
public boolean equals(Object anObject) {
    if (this == anObject) { // 如果两个引用指向的是同一个String对象
        return true;
    }
    if (anObject instanceof String) { // 如果第2个引用指向的对象是String实例
        String anotherString = (String)anObject; // 强制类型转换
        int n = value.length; // 获取第1个引用指向的String对象的字符串长度
        if (n == anotherString.value.length) { // 如果两个字符串长度相等
            // 定义字符数组指针
            char[] v1 = value;
            char[] v2 = anotherString.value;
 
            // 字符依次比较
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

4、hashCode()方法

重写了hashCode()方法

public int hashCode() {
    // 获取字符串缓存散列码
    int h = hash;
    if (h == 0 && value.length > 0) { // 如果字符串缓存散列码为0并且字符串数组长度大于0
        // 定义字符数组指针
        char val[] = value;
 
        // 遍历每个字符
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i]; // 31 * h会被JVM优化成(h << 5) - h
        }
        hash = h; // 修改字符串缓存散列码
    }
    return h;
}

5、split()方法

split()方法的坑比较多,试一下执行
public static void main(String[] args) {
    String s = "1"; 
    String[] s1 = s.split("-");
    System.out.println(s1.length);-----------------结果是1
}

这里建议避开如下坑:

(1)不要使用如下字符作为分隔符:.$|()[{^?*+\\,这些是"Dangling meta character";

(2)对于空字符串的,也不要使用split,这样分割后的数组长度是1

(3)注意转义字符

(4)注意分隔符在最前和最后的情况

推荐使用的分隔符:单个字符如     "-"  ","   ";"   ":"

6、native方法 intern()

调用了intern()方法的字符串对象,将会进入常量池

/**
     * Returns a canonical representation for the string object.
     * A pool of strings, initially empty, is maintained privately by the class {@code String}.    
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the method, then the string from the pool is returned. 
   * Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {s} and {t},
     * {s.intern() == t.intern()} is {true}
     * if and only if {s.equals(t)} is {true}.
     * <p>
     * All literal strings and string-valued constant expressions are interned. --------所有字面意义的字符串值和具有字符串值的常量表达式
   * String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
public native String intern();

7、关于字符串常量池

(1)双引号字符串:String s1 = "aa";  只在常量池上创建"aa"对象

(2)new String():  String s2 = new String("aa");  在堆上创建对象"aa",并在常量池上创建常量"aa"

(3)new String()相加:String s3 = new String("a") + new String("a");

  在堆上创建两个"a",一个"aa"。在常量池中创建了"a"

(4)String s4 = new String("a") + new String("a");   s4.intern();

  在堆上创建两个"a",一个"aa"。在常量池中创建了"a",并将该对象aa的引用保存到常量池上

 

关于String

原文:https://www.cnblogs.com/yb38156/p/12401816.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!