2道关于String字符串类型的面试题

package wjd.stringtest;

public class Test04 {

    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "java";
        show(s1,s2);
        System.out.println(s1+"...."+s2);//hello....java
        System.out.println("********************");
        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("java");
        show_2(sb1,sb2);
        System.out.println(sb1+"....."+sb2);//hellojava.....java
    }

    private static void show_2(StringBuffer sb1, StringBuffer sb2) {
        sb1.append(sb2);
        sb1 = sb2;
    }

    private static void show(String s1, String s2) {
        s2.replace('a', 'o');
        s1 = s2;
    }

}

(1) show方法中,String是怎么处理的?

    1.1,  main方法进栈,这个时候在字符串常量池中就会出现2个地址,这个假设s1地址的0x11,s2地址是0x22,在main方法中的s1和s2就分别指向了这2个地址

    1.2,  show方法进栈,show方法上的参数s1和s2也指向了上面对应的那2个地址(注意,方法参数上的s1,s2和main方法中的s1,s2是两个不同的东西,只是它们的变量名字相同而已),在show中,使用replace方法中,发生了替换的动作,这个时候,在字符串常量池中,会多出来一个属于jovo字符串的地址,这个假设是0x33,然后再将s2的地址赋值给s1,这里关键点出来了,由于是在show方法中进行的操作,当操作完毕之后,show方法中最后2个参数的地址都会是s2的地址,但是当show方法执行完毕之后,弹栈之后,在字符串常量池中,s1和s2的地址上的内容至始至终都没有发生变化,这个时候输出的就是hello和java.

(2)show_2方法中,StringBuffer是怎么处理的?

由于StringBuffer在底层是维护的一个可变的数组,所以在append的时候,会把s2中的内容追加到s1后面去,当new的时候,在堆内存中,会出现2个属于sb1和sb2的地址,然后在append的时候,s1的地址上的内容会变成hellojava,这里在sb1地址上的内容就发生了变化

再看后面的赋值,和String一样,方法内的赋值,方法没返回值,赋值的时候,不会导致堆内存中地址上面的内容的变化,所以你再怎么赋值,在最后方法弹栈的时候,对main方法中,程序的运行结果是没有变化的,所以最后输出的结果,是  hellojava   和  java.

----------------------------------------------------------------------------------------------------------------------------------------------

package wjd.stringtest;

public class Test05 {
    public static void main(String[] args) {
        String s1 = "ab";
        String s2 = "cd";
        String s3 = "ab" + "cd";
        String s4 = "abcd";
        /*
         * 字符串连接的时候
         * (1)如果是2个或者几个字符串常量进行+连接的时候,这时会产生一个新的字符串,这个新字符串产生的字符串常量池中
         * (2)如果是2个或者几个字符串的引用变量进行+连接的时候,这个时候JVM会在底层产生StringBuffer字符串缓冲区对象,
         *    String s5 = s1+s2,这时候s1会被append中字符串缓冲区中,接着s2再被append字符串缓冲区中
         *    最后s5指向的不是s1+s2的结果,而是指向了StringBuffer容器
         * 需要注意的是,在String和StringBuffer中,toString()这个方法都已经被复写了.
         */
        String s5 = s1 + s2;
        System.out.println(s3 == s4);//true
        System.out.println(s5 == s3);//false
        System.out.println(s5 == s4);//false
    }

}
posted @ 2014-09-07 16:21  木有杂念  阅读(724)  评论(0编辑  收藏  举报