java String类总结


String类实例对象的不可变性:

String的两种声明方式:
- 方式1:我们经常使用的字符串声明方式声明其对象:

  String s1 = "abc";
  String s2 = "abc";
  System.out.println(s1 == s2);//true

- 方式2:通过new对象的方式:

  String s1= new String("abc");
  String s2= new String("abc");
  System.out.println(s1 == s2);//false

(1)这两种声明方式在内存中是不同的,首先String类是一个final类第一种方式相当于:

    final String s1 = "abc"

可见相当于定义了一个字符串常量,在内存中拥有一个特殊的空间用来存放该常量,该常量的值是不可以被改变的(String的不可变性1);当创建该常量的时候jvm对判断内存中是否存在该常量,如果没有则创建,有则只创建一个新的引用指向该常量。
(2)通过第二种方式创建,与其他类相同,new一个新的对象则在堆内存中开辟一个空间,方式2 new了两个对象,虽然对象内容一样但是内存地址不同,而==操作符比较的就是两个对象的首内存地址,所以结果为false;


String类生成对象可以被修改,但是修改后将返回一个新的对象。

用上述两种方法创建的字符串,都是可以使用concat方法来修改对象内容,字符串被修改后将返回一个新的字符串。
- 方式1相当于又生成一个字符串常量,
- 方式2相当于有生成个字符串对象;
所以如果用==比较的话,两种方式新生成的字符串与之前的字符串均不相同;

String对“+”的重载

我们知道,Java是不支持重载运算符,String的“+”是java中唯一的一个重载运算符,那么java使如何实现这个加号的呢?我们先看一段代码:

public static void main(String[] args) {
String string=”hollis”;
String string2 = string + “chuang”;
}
然后我们将这段代码反编译:

public static void main(String args[]){
String string = “hollis”;
String string2 = (new StringBuilder(String.valueOf(string))).append(“chuang”).toString();
}
看了反编译之后的代码我们发现,其实String对“+”的支持其实就是使用了StringBuilder以及他的append、toString两个方法。
这里可以看到先new了一个StringBuilder对象,这时候就在堆内存中创建了一个对象,而String2指向的是这个对象的内存地址。所以和String指向的地址不同。


String字符串的格式化输出:

  • 方法1:可以使用system.out.printf语句格式化输出String字符串;

    System.out.printf("The value of the float variable is " +
              "%f, while the value of the integer " +
              "variable is %d, and the string " +
              "is %s", float类型变量, int类型变量, string类型变量);
    
  • 方法2:也可以采用String类的format方法,格式化生成字符串对象;

    String fs;//先格式化生成fs对象
      fs = String.format("The value of the float variable is " +
               "%f, while the value of the integer " +
               "variable is %d, and the string " +
               "is %s", float类型变量, int类型变量, string类型变量);
                System.out.println(fs);//后打印输出该字符串
    

String的比较方法:

  • 方法1 “s1 == s2” 比较两者所指向的对象内存地址是否相同;
  • 方法2 “s1.equal(s2)”覆写了Object类中的equal()方法;

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {//判断比较对象是否是String对象类型
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {//如果两个string对象的长度相同进行下面的比较;
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {//比较所有字符是否相同,v[i] 等于该字符的Unicode表中对应的数值;
                        if (v1[i] != v2[i])
                            return false;
                    i++;
            }
            return true;
        }
    }
    return false;
    }
    
  • 方法3: compareto()方法:

    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;//String类的本质是字符数组char[]
        char v2[] = anotherString.value;
    
        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
    

    return

    • the value 0 if the argument string is equal to this string;
    • a value less than 0 if this string is lexicographically less than the string argument; and a
    • value greater than 0 if this string is lexicographically greater than the string argument.
      也就是如果两个字符串相同的返回0,若两个字符串不相同的话返回第一个不相同字符的unicode编码值的差值。

参考资料:

java String对象的经典问题 http://sarin.iteye.com/blog/603684

你可能感兴趣的:(JAVA,基础进阶)