2.8、String类

2.8、String类(重点

2.8.1、String的两种实例化方式

String本身是一个类,在String类中定义了如下的构造方法:

public String(String original)

可以接受一个String类的对象,并重新实例化String对象,除了此方法之外String还可以采用直接赋值的方式进行对象的实例化。

public class Demo00 {
    public static void main(String args[]) {
        String str1 = "hellow";     //通过直接赋值的方式完成
        String str2 = new String("11111");     //通过构造方法完成
        System.out.println(str1+str2);      //进行字符串的连接操作
    }
};

此时,证明两个String类型对象都实例化。

2.8.2、String的比较方式

现在假设有如下的一道程序,观察String类的比较问题:

public class Demo00 {
    public static void main(String args[]) {
        String str1 = "hellow";     //通过直接赋值的方式完成
        String str2 = new String("11111");     //通过构造方法完成
        String str3 = str2;
        System.out.println("str1 == str2  " + (str1==str2));      //false
        System.out.println("str1 == str3  " + (str1==str3));      //false
        System.out.println("str2 == str3  " + (str2==str3));      //true
    }
};

从内存关系中来分析一下结果:

得出一个结果,实际上对于“==”比较的是两个对象的地址是否相等,具体的来讲实际上比较的是地址的值,因为地址是以数值的形式存在的。

但是现在真正要比较的不是地址的值,而是两个字符串的内容,所以现在就需要使用String类中的equals()方法完成比较,此方法定义如下:

  • public boolean equals(String str)

范例:使用equals()修改程序

public class Demo00 {
    public static void main(String args[]) {
        String str1 = "hellow";     //通过直接赋值的方式完成
        String str2 = new String("hellow");     //通过构造方法完成
        String str3 = str2;
        System.out.println("str1 equals str2  " +  str1.equals(str2));      //true
        System.out.println("str1 equals str3  " +  str1.equals(str3));      //true
        System.out.println("str2 equals str3  " +  str2.equals(str3));      //true
    }
};

2.8.3、一个字符串实际上就是Sring的匿名对象

一个字符串是使用“ “ “括起来的,那么一个字符串的常量实际上本身就属于Sting的一个匿名对象。

public class Demo00 {
    public static void main(String args[]) {
        String str1 = "hellow";     //通过直接赋值的方式完成
        System.out.println("str1 equals str2  " +  ("hellow".equals(str1)));
    }
};

2.8.4、String的两种实例化方式的区别

所有的操作以内存图形表示出来。

String str1 = "hellow";

现在在堆内存空间中,之开辟了一个空间,不会产生多余的内容。

如果现在使用new关键字的方式呢?

String str2 = new String("hellow");

可以发现,程序开辟了两个空间,与直接赋值相比,肯定使用直接赋值的方式方便,所以在开发中绝对不能使用new调用String类的String(String org)的构造方法。

而且,如果使用直接赋值的方式也可以减少堆内存的开销。

public class Demo00 {
    public static void main(String args[]) {
        String str1 = "hellow";     //通过直接赋值的方式完成
        String str2 = new String("11111");     //通过构造方法完成
        String str3 = str2;
        System.out.println("str1 == str2  " + (str1==str2));     
        System.out.println("str1 == str3  " + (str1==str3));     
        System.out.println("str2 == str3  " + (str2==str3));     
    }
};

实际上,以上的三个对象表示的都是同一个空间的引用,因为对于String来讲使用直接赋值的方式会在字符串池中保存内容。如果之后再声明字符串的时候发现内容一样了,则不会重新开辟空间,而是从内存池中取出数据继续使用。

2.8.5、字符串的内容一旦声明之后则无法修改

public class Demo00 {
    public static void main(String args[]) {
        String str = "hello";
        str += " world";
        System.out.println(str);
    }
};

虽然最终的输出结果改变了,但是字符串的内容并没有改变

实际上来讲,字符串变量的改变实际上是改变的内存空间的地址指向,而本身的字符串内容没有任何的变化,所以,在开发中一下的操作代码绝对要避免:

public class Demo00 {
    public static void main(String args[]) {
        String str = "hello";
        for (int i = 0; i < 100; i++) {
            str += i;
        }
        System.out.println(str);
    }
};

以上的操作要不断的断开已有的链接,指向新连接100次,整体代码的性能极低,所以遇到此类代码绝对不要使用。


转载请注明来源