String、StringBuffer、equals、== 、堆、栈、常量池

Java内存分配--堆、栈、常量池

Java内存分配主要包括以下几个区域:

1. 寄存器:我们在程序中无法控制

2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

3. 堆:存放用new产生的数据

4. 静态域:存放在对象中用static定义的静态成员

5. 常量池:存放常量

6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间

 字符串常量池--引入

public class test2 {
    public static void main(String[] args){
        String name1="不敢说话";
        String name2="不敢说话";
        System.out.println(name1==name2);
    }
}

String对象是不可变的,字符串一旦创建,内容就不能该变。

Java中为了效率考虑,以" "包括的字符串只要内容相同,无论在程序代码中出现过几次JVM都只会建立一个实例,放在字符串池中维护。

字符串拼接--原理

public class test2 {
    public static void main(String[] args){
        String str="不敢说话";
        str+="喜欢吃草莓。";
        System.out.println(str);
        String str2="不敢说话";
        str2=str2.concat("不喜欢吃苹果。");
        System.out.println(str2);
    }
}

事实上+=和concat是等价的。我们先来看一下concat的原理代码

忽略中间的过程,总之,返回的是一个新创建的对象,所以每次写+=或者调用concat方法都会创建一个新的对象。

所以,这种写法与“字符串一旦创建,内容就不能该变。”这句话并不矛盾。

注意:调用concat的方法时写str=str.concat("喜欢吃草莓"),不能写成str.concat("喜欢吃草莓")。如果用第二种写法,只时在JVM中创建了一个新的对象而已,str这个引用变量中存的地址还是“不敢说话”的地址,输出的时候不会是拼接的结果。

String与StringBuffer

StringBuffer引入

public class StringBufferDemo {//StringBuffer是+=的大概1000倍!!!

    public static void main(String[] args){

        final int N=100000;
        //使用String进行字符串拼接
        long starTime=System.currentTimeMillis();
        String str="*";
        for(int i=0;i<N;i++){
            str+="*";
        }
        long endTime=System.currentTimeMillis();
        System.out.println("+=的用时:"+(endTime-starTime)+"毫秒");

        //使用StringBuffer进行字符串拼接
        starTime=System.currentTimeMillis();
        StringBuffer str0=new StringBuffer("*");
        for(int i=0;i<N;i++){
            str0.append("*");
        }
        endTime=System.currentTimeMillis();
        System.out.println("StringBuffer的append用时:"+(endTime-starTime)+"毫秒");
        //还有StringBuilder
    }
}

为什么要使用StringBuffer?

我们看见,用String去实现字符串拼接,消耗的时间竟然是StringBuffer的很多倍。怎么会这样呢?

以下这段话摘自于https://blog.csdn.net/fengshizty/article/details/41482793

String中的equals和StringBuffer中的equals

public class equalsDemo {
    public static void main(String[] args){

        String value="helloworld";
        value+="Good";
        String value2="helloworldGood";
        //System.out.println(value==value2);
        System.out.println(value.equals(value2));

        StringBuffer strBuffer3=new StringBuffer("你好成都!");
        StringBuffer strBuffer4=new StringBuffer("你好成都!");
        System.out.println(strBuffer3.equals(strBuffer4));
        //System.out.println(strBuffer3.toString().equals(stringBuffer4.toString()));//全用toStirng()转成字符串比较的就是值而已

    }
}

 

看到这里也许就疑惑了,诶?怎么同时equals,要比较的字符串也一样啊,怎么输出第一个就是true第二个就是false呢?

String类中的equals方法是对父类Object类中的equals方法的覆盖,比较的是字符串的内容是否相同。

而StringBuffer类中的equals方法没有覆盖Object的方法,比较的是两个字符串的地址。

这就不难理解为什么第一个输出true第二个输出false了。

关于  "=="

public class test2 {
    public static void main(String[] args){
        int a=1;
        double b=1;
        System.out.println(a==b);

        String str1="不敢说话";
        String str2="不敢说话";
        System.out.println(str1==str2);

        String str3=new String("不敢说话");
        String str4=new String("不敢说话");
        System.out.println(str3==str4);
    }
}

当==比较的是两个基本数据类型的变量是,比较的是二者的值。

而==比较的是两个引用类型的引用变量是,比较的是二者的地址。

猜你喜欢

转载自blog.csdn.net/miamia8989/article/details/84782203