Java 有关String面试题

在Java 编程中,String是最常使用的Java类之一,
作为一个Java新手程序员,对String进行更深入的了解很有必要。在面试中关于string的问题也经常问到,下面总结一下面试中常会问到的几个有关string的问题。
1、什么是String,它是什么数据类型?
String是定义在 java.lang 包下的一个类。它不是基本数据类型。
String是不可变的,JVM使用字符串池来存储所有的字符串对象。
(基本数据类型包括 byte、int、char、long、float、double、boolean 和 short。)

2、什么是字符串池?
顾名思义,字符串常量池就是用来存储字符串的。它存在于Java 堆内存。
下图解释了字符串池在java堆空间如何存在以及当我们使用不同方式创建字符串时的情况。
在这里插入图片描述
一些java题中,可能会问一段代码中有几个字符串被创建,例如:
String str = new String(“Cat”);
上面一行代码将会创建1或2个字符串。如果在字符串常量池中已经有一个字符串“Cat”,那么就只会创建一个“Cat”字符串。如果字符串常量池中没有“Cat”,那么首先会在字符串池中创建,然后才在堆内存中创建,这种情况就会创建2个对象了。

3、下面的代码将创建几个字符串对象。
String s1 = new String(“Hello”);
String s2 = new String(“Hello”);

答案是3个对象
第一,行1 字符串池中的“hello”对象。
第二,行1,在堆内存中带有值“hello”的新字符串。
第三,行2,在堆内存中带有“hello”的新字符串。这里“hello”字符串池中的字符串被重用。

4、String s = “Hello”;s = s + " world!"; 这两行代码执行后,原始的 String对象中的内容到底变了没有?
没有。
因为 String 被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指向一个 String 对象,内容是 “Hello”,然后我们对 s 进行了+操作,这时,s 不指向原来那个对象了,而指向了另一个 String 对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。

5、浅谈一下String, StringBuffer,StringBuilder的区别?
String是不可变类,每当我们对String进行操作的时候,总是会创建新的字符串。操作String很耗资源,所以Java提供了两个工具类来操作String - StringBuffer和StringBuilder。

StringBuffer和StringBuilder是可变类,StringBuffer是线程安全的,StringBuilder则不是线程安全的。所以在多线程对同一个字符串操作的时候,我们应该选择用StringBuffer。由于不需要处理多线程的情况,StringBuilder的效率比StringBuffer高。

6、String 有没 有没有 有 length() 这个方法?数组有没有 length() 这个方法?
String 有 length()这个方法。
数组没有 length()这个方法,有 length 的属性。

7、下面的代码输入什么
String s1 = “abc”;
StringBuffer s2 = new StringBuffer(s1);
System.out.println(s1.equals(s2));

输入false
因为s2不是String类型,String的equals方法进行了类型判断。
8、
String s1 = “abc”;
String s2 = new String(“abc”);
s2.intern();
System.out.println(s1 ==s2);
输出false
当intern()方法被调用,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。
intern()方法将返回从字符串池中的字符串对象的引用,但因为我们没有分配到S2,S2没有变化。

String s2 = new String(“abc”);
s2.intern();
String s1 = “abc”;
System.out.println(s1 ==s2);
输出true。
当执行s2.intern();时,因为常量池中没有“abc”这个字符串,所以会在常量池中生成一个对堆中的“abc”的引用,而在进行String s1 = “abc”;字面量赋值的时候,常量池中已经存在一个引用,所以直接返回了该引用,因此s1和s2都指向堆中的同一个字符串,返回true。
9、String s=“abcdefg”; s.substring(0,3);System.out.println(s);

abcdefg,因为String类是final类,值不可改变,final类不可被继承。
10、判断定义为String类型的s1和s2是否相等 String s1 = “abc”; String s2 = “abc”; System.out.println(s1 == s2);

true
在内存中有一个常量池, 当我们创建常量时;系统先看常量池中有没有这个常量,如果有,则不创建直接引用这个常量 所以,s1和s2引用的是一个常量 ,记录的是一个地址值
== 判断引用数据类型的地址是否相等 System.out.println(s1.equals(s2));true public boolean equals(Object anObject) 将此字符串与指定的对象比较。当且仅当该参数不为 null, 并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。

11、判断定义为String类型的s1和s2是否相等
String s1 = new String(“abc”);
String s2 = “abc”;
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));

false true
String s1 = new String(“abc”);记录的是堆内存对象的地址
String s2 = “abc”;记录的是常量池内对象的地址
== 判断引用数据类型的地址是否相等
equals() 判断引用数据类型的值是否相等

12、判断定义为String类型的s1和s2是否相等
String s1 = ‘a’+‘b’+‘c’;
String s2 = “abc”;
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));

true true
java有常量优化机制,在编译时就变成了“abc”
有符号引用时不会被优化。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值