Java之关于String字符串笔试面试重点

一.关于字符串的常量池1.关于字符串产生的三种方式String s1="abc";

String s2=new String("abc");

char[] value={'a','b','c'};

String s3=new String(value);

2.关于字符串的常量池当字符串采用直接赋值法的时候,JVM会维护一个字符串的常量池.

当字符串常量第一次产生的时候,就会产生字符常量,放入到常量池中

当使用直接复制法再次产生相同的对象时,若常量池中存在该值的对象直接复用常量池中的对象,并不会产生新的对象

3.直接赋值法和new的方式产生对象的区别首先需要明确==比较的引用对象的地址是否相同,而不是值!!!

    String s1 = "abc";

    String s2 = new String("abc");

    char[] value = {'a', 'b', 'c'};

    String s3 = new String(value);

    String s4 = "abc";
    System.out.println(s1 == s2);//false
    System.out.println(s1 == s4);//true
    System.out.println(s2 == s3);//false
    System.out.println(s3 == s4);//fasle

关于这样四对字符串==的比较,因为s1和s4都采用的是直接赋值法,所以他们对象的产生在常量池中,由于他们的值都是相同的,所以他们指向同一个地址的值.

而new对象的产生是在堆上,所以他们都是指向不同地址的对象,虽然他们的值都是一样的

二.关于intern方法这是一个手动置入常量池的方法:调用此方法,会将当前字符串对象尝试置入常量池

主要分为两种情况:

1.若常量池中已经包含了当前对象的内容,不会将当前对象置入常量池,返回值是常量池中原有的对象地址⒉若常量池中没有包含当前字符串对象的内容,就将当前对象置入常量池之中,返回值是当前对象的地址

1.情况一(已经包含)String s1 = "abc";

    String s2=new String("abc");

    System.out.println(s1==s2);//false

    s2=s2.intern();

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

第一个s1==s2输出的是false,前边已经讲解过了,因为new对象是在堆上产生的,s1是在常量池中产生,==比较的地址,显然他们的地址不一样.

第二个s1==s2,因为值为"abc"已经存在与常量池中了,不会将s2对象置入到常量池中,但是结果的返回值为s1的地址,此时令s2=s2.intern(),s2的地址便与s1的地址相同

2.情况二(已经包含)String s1 = "abc";

    String s2=new String("abc");

    System.out.println(s1==s2);//false

    s2.intern();

    System.out.println(s1==s2);//false

第一个s1==s2同上

第二个s1==s2,因为值为"abc"已经存在与常量池中了,不会将s2对象置入到常量池中,所以s2指向的还是s2原本的地址,s1与s2的地址不相同,所以返回的false

3.情况三(未包含)char[] ch = {'a', 'b', 'c'};

    String s2 = new String(ch);

    s2.intern();

    String s1 = "abc";

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

new出来s2的时候,常量池中并没有"abc"这个字符串,这个时候将s2压入到常量池中,然后s1直接赋值法直接就是和s2压入到常量池的地址一样了,具体看下图

4.情况四String s2 = new String("abc");//"abc"是字符串常量,此时存在于常量池中了

    s2.intern();//此时常量池中已经存在"abc",因为上边new对象的时候"abc"在常量池

    String s1 = "abc";

    System.out.println(s1 == s2);//false

因为刚开始new对象的时候是拿常量池中的"abc"new出来,所以此时常量池中已经有了"abc",这个时候s2的地址还是处在堆中,s1直接赋值"abc"在常量池中,所以s1和s2的地址不一样

三.关于字符串的不可变性1.了解字符串的不可变性String对象一旦产生,字符串对象中保存的值不可改变

    String s1="hello";

    s1+=",world";
    s1+="!!";

    System.out.println(s1);

很多人可能会疑问,这样s1的值不是改变了吗?

这样一段代码,改变的是s1的引用,它的指向一直在改变,不断指向新的字符串常量

不断在常量池中产生了新的字符串对象,str这个引用一直在变字符串常量池中一旦字符串对象产生,内容不变的.这就是字符串对象的不可变性

2.String对象不可变性的原因

String对象的底层是用一个字符串数组进行保存的.

有些人可能以为String对象不可变是因为char数组是final修饰的,实则这是一个很大的误解,因为final修饰的引用对象,只是它的地址值不会发生改变,它的实际内容还是会改变的,下面这段代码便可以很好的证明

    final char[] ch={'a','b','c'};

    System.out.println(Arrays.toString(ch));//[a, b, c]

    ch[0]='g';

    System.out.println(Arrays.toString(ch));//[g, b, c]

实际上是因为字符串数组前边的private进行修饰,因为String类中没有具体的get和set方法,所以我们在外边的时候,无法直接对char数组进行改变

所以我们常用的subString,replace等操作字符串的方法,并没有对原来的字符串进行了改变,只是产生了新的字符串对象

    String s="abcdefg";
    String substring = s.substring(0, 5);
    System.out.println(s);//abcdefg

3.相关的考题public static void main(String args[]){String str = new String("good");char[ ] ch = { 'a' , 'b' , 'c' };change(str,ch);System.out.println(str);System.out.println(ch);}public static void change(String str,char ch[ ]){str = "abc";ch[0] = 'g';}对于这样一段代码的输出是什么?

我们学习过了字符串的不可变性,进入到change方法之后,字符数组直接在堆进行改变,而对字符串的改变,直接产生了新的字符串,str指向了新的地址,而主方法里的str指向的还是原来的地址,所以最后输出

str="good"ch="gbc"

各位三连支持下

全部评论

相关推荐

2024-12-29 19:48
河北科技大学 Java
没事就爱看简历:问题不在于简历:1、大学主修课程学那么多应用语言,作为计算机专业是很难理解的。 2、技能部分,每一个技能点的后半句话,说明对熟练,熟悉的标准有明显误会。 3、项目应该是校企合作的练习吧,这个项目你负责什么,取得了哪些成果都没有提及,只是列举了你认为有技术含量的点,而这些都有成熟的实现。
点赞 评论 收藏
分享
评论
1
6
分享

创作者周榜

更多
牛客网
牛客企业服务