String类是java Coder使用得最多的一个工具类吧,常见的考点有:
1)常量字符串是定义在常量区,值相同的所有常量字符串其实是引用的同一个常量,包括能在编译时能计算出来的常量字符串。
示例1:
1 2 3 4 5 6 7 |
public class TestString { public static void main(String[] args) { String s1 = "javacoder.cn"; String s2 = "javacoder" + ".cn"; System.out.println(s1 == s2); } } |
答案:true
可以看到s1 s2引用的是同一个对象, 虽然s2是通过 "javacoder" 和 ".cn"计算出来的, 由于这两个字符串是常量的,所以s2的值能在编译时确定。
示例2:
1 2 3 4 5 6 7 |
public class TestString { public static void main(String[] args) { String s1 = "javacoder.cn"; String s2 = "javacoder" + new String(".cn"); System.out.println(s1 == s2); } } |
答案:false
2)字符串作为参数传递:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class TestString { public static void main(String[] args) { String s1 = null; fn(s1); System.out.println(s1); } public static void fn(String p) { if(p == null) { p = "javacoder.cn"; } System.out.println(p); } } |
答案:
fnjavacoder.cn
main:null
java中所有的对象作为参数时都是以引用的形式传递,当调用fn 时,p也指向了s1指向的对象,一个空的对象,在fn中p指向了一个新的对象“javacoder.cn”,而s1的指向没有改变,讲到这里,我相信大家对输出的结果就一目了然了,
概念性的问题:
3)为什么String 类的定义是final 的?
可以参考http://stackoverflow.com/questions/2068804/why-is-string-final-in-java
建议去stackoverflow.com逛逛,这个网站收录了很多编程的问题。你值得访问
4)String s1 = ne w String("javacoder.cn");构造了几个字符串?
两个,一个匿名的常量字符串“javacoder.cn”, 另一个是通过new 操作符产生的
5)String 和StringBuffer的区别
String 是不可改变的,调用String对象的任何方法都将产生新的对象, StringBuffer 的内容是可以改变的,一般用来动态的构建字符串,节省产生新对象的时间。
示例3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class TestString { private static final String welcome = "welcom"; private static final String to = " to"; private static final String javacoder = " javacoder"; private static final String cn = ".cn"; public static void main(String[] args) { String s1 = welcome; s1 += to; s1 += javacoder; s1 += cn; System.out.println(s1); StringBuffer sb = new StringBuffer(); sb.append(welcome); sb.append(to); sb.append(javacoder); sb.append(cn); System.out.println(sb.toString()); } } |
使用javap -v TestString.class 反编译的结果为
0: ldc #8// load "welcome"
2: astore_1
3: new #29// StringBuilder
6: dup
7: aload_1
8: invokestatic #31// String String.valueOf:(Object)
11: invokespecial #37// void StringBuilder."":(String)
14: ldc #10// load "to"
16: invokevirtual #40// StringBuilder StringBuilder.append(String)
19: invokevirtual #44// String StringBuilder.toString()
22: astore_1
23: new #29 // StringBuilder
26: dup
27: aload_1
28: invokestatic #31// String String.valueOf:(Object)
31: invokespecial #37// void StringBuilder."":(String)
34: ldc #13// load "javacoder"
36: invokevirtual #40// StringBuilder StringBuilder.append:(String)
39: invokevirtual #44// String StringBuilder.toString()
42: astore_1
43: new #29// StringBuilder
46: dup
47: aload_1
48: invokestatic #31// String String.valueOf(Object)
51: invokespecial #37// void StringBuilder.""(String)
54: ldc #16// load ".cn"
56: invokevirtual #40// StringBuilder StringBuilder.append(String)
59: invokevirtual #44// String StringBuilder.toString();
62: astore_1
63: getstatic #48// Field System.out;
66: aload_1
67: invokevirtual #54// void PrintStream.println(String)
70: new #59// StringBuffer
73: dup
74: invokespecial #61// void StringBuffer.""()
77: astore_2
78: aload_2
79: ldc #// load "welcome"
81: invokevirtual #62// StringBuffer StringBuffer.append(String)
84: pop
85: aload_2
86: ldc #10// load "to"
88: invokevirtual #62// StringBuffer StringBuffer.append(String)
91: pop
92: aload_2
93: ldc #13// load "javacoder"
95: invokevirtual #62// StringBuffer StringBuffer.append(String)
98: pop
99: aload_2
100: ldc #16// load ".cn"
102: invokevirtual #62// StringBuffer StringBuffer.append(String)
105: pop
106: getstatic #48// Field System.out
109: aload_2
110: invokevirtual #65// String StringBuffer.toString()
113: invokevirtual #54// void PrintStream.println(String)
116: return
0-67是"+"对应的字节码,可以看到额外产生了3个StringBuffer对象和三个String对象(通过StringBuffer.toString产生),而直接使用StringBuffer,那么直会唯一的产生一个额外的String对象(通过StringBuffer.toString())。
Posted in: 面试加油站
Comments are closed.