电子书下载地址: http://wiki.jikexueyuan.com/project/java-interview-bible/
1. 下面程序的运行结果是()
String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);
答案:false
解析:因为 str2 中的 llo 是新申请的内存块,而 == 判断的是对象的地址而非值,所以不一样。如果是String str2 = str1
,那么就是 true 了。
2. 下面代码的运行结果为?
import java.io.*;
import java.util.*;
public class foo{
public static void main (String[] args){
String s;
System.out.println("s=" + s);
}
}
A. 代码得到编译,并输出 “s=”
B. 代码得到编译,并输出 “s=null”
C. 由于 String s 没有初始化,代码不能编译通过
D. 代码得到编译,但捕获到 NullPointException异常
答案:C
解析:开始以为会输出 null 什么的,运行后才发现 Java 中所有定义的基本类型或对象都必须初始化才能输出值。
3. String 是最基本的数据类型吗?
答:不是。Java 中的基本数据类型只有 8 个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型(reference type)。
4. 数组有没有 length() 方法? String 有没有 length() 方法?
答:数组没有 length()方法,有 length 的属性。String 有 length()方法。JavaScript 中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。
5. 是否可以继承 String 类?
答:String 类是 final 类,不可以被继承。
补充:继承 String 本身就是一个错误的行为,对 String 类型最好的重用方式是关联(HAS-A)而不是继承(IS-A)。
6. String 和StringBuilder、StringBuffer 的区别?
答:Java 平台提供了两种类型的字符串:String 和StringBuffer / StringBuilder,它们可以储存和操作字符串。其中 String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer 和 StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 JDK 1.5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被 synchronized 修饰,因此它的效率也比 StringBuffer 略高。
有一个面试题问:有没有哪种情况用 + 做字符串连接比调用 StringBuffer / StringBuilder 对象的 append 方法性能更好?如果连接后得到的字符串在静态存储区中是早已存在的,那么用+做字符串连接是优于 StringBuffer / StringBuilder 的 append 方法的。
7. String s=new String(“xyz”);创建了几个字符串对象?
答:两个对象,一个是静态存储区的"xyz",一个是用new创建在堆上的对象。
8. 将字符 “12345” 转换成 long 型
解答: String s=”12345″;
long num=Long.valueOf(s).longValue();
9. 为了显示 myStr = 23 这样的结果,写出在控制台输入的命令
public class MyClass {
public static void main(String args[]) {
String s1 = args[0];
String s2 = args[1];
String myStr = args[2];
System.out.printin(“myStr =” + s2 + myStr);
}
}
答:java MyClass 1 2 3 4
10. String s = "Hello";s = s + " world!”;
这两行代码执行后,原始的 String 对象中的内容到底变了没有?
没有。因为 String 被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指向一个 String 对象,内容是 "Hello",然后我们对 s 进行了+操作,那么 s 所指向的那个对象是否发生了改变呢?答案是没有。这时, s 不指向原来那个对象了,而指向了另一个 String 对象,内容为 "Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用 String 来代表字符串的话会引起很大的内存开销。因为 String 对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个 String 对象来表示。这时,应该考虑使用 StringBuffer 类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都 new 一个 String。例如我们要在构造器中对一个名叫 s 的 String 引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value”);
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为 String 对象不可改变,所以对于内容相同的字符串,只要一个 String 对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的 String 类型属性 s 都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java 认为它们代表同一个 String 对象。而用关键字 new 调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把 String 类设计成不可变类,是它的用途决定的。其实不只 String,很多 Java 标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以 Java 标准类库还提供了一个可变版本,即 StringBuffer。
11. 如何把一段逗号分割的字符串转换成一个数组?
如果不查 jdk api,我很难写出来!我可以说说我的思路:
1 用正则表达式,代码大概为:String [] result = orgStr.split(“,”);
2 用 StingTokenizer ,代码为:
StringTokenizer tokener = StringTokenizer(orgStr,”,”);
String [] result =new String[tokener .countTokens()];
Int i=0;
while(tokener.hasNext(){result[i++]=toker.nextToken();}
12. 下面这条语句一共创建了多少个对象:String s=“a”+”b”+”c”+”d”;
答:对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一条语句打印的结果为 false ,第二条语句打印的结果为 true,这说明 Javac 编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个 String 对象。写如下两行代码,
String s ="a" + "b" + "c" + "d";
System.out.println(s== "abcd");
最终打印的结果应该为 true。
13. String 和 StringBuffer 的区别?
答:JAVA 平台提供了两个类:String 和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个 String 类提供了数值不可改变的字符串。而这个 StringBuffer 类提供的字符串进行修改。当你知道字符数据要改变 的时候你就可以使用 StringBuffer。典型地,你可以使用 StringBuffers 来动态构造字符数据。
14. String, StringBuffer StringBuilder的区别。
答:
String 的长度是不可变的;
StringBuffer的长度是可变的,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用 StringBuffer,如果最后需要 String,那么使用 StringBuffer 的 toString() 方法;线程安全;
StringBuilder 是从 JDK 5 开始,为StringBuffer该类补充了一个单个线程使用的等价类;通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。