Cappuccino~~~
BlogJava
首页
新文章
新随笔
聚合
管理
posts - 3, comments - 7, trackbacks - 0
一题有关String笔试题的分析
题目:String s = new String("xyz"); 这么一题简单的java笔试题,对于java新手来说可能会做错,看只要是PAPER,看一遍,听人家讲一遍就知道了。
问:执行这一语句,一共创建了几个String对象?
答:2个,1个在String池中,一个在堆内存中。
但其实这题目具有很大的灵活度,如果不真正理解String的运作机制,换个样子就有可能把PAPER难住了。
String s1 = "xyz"; String s2 = "x"+"yz"; String s3 = "x"+new String("yz"); String s4=new String("xyz");
如果说s1==s2,那s1为什么!=s3呢?为什么s1!=s4呢?
String类是java中一个比较特殊的类,与其相关的还有java中仅有的两个内置重载操作符:"+"和"+="。
String类对象是不可变的,而StringBuffer & String Builder类对象是可变的;String类重写了equals方法,而StringBuffer & String Builder类却没有重写。
拿操作符"+"来说,其两边的操作元类型无非就5种情况(注意操作符的左结合性):
1、两个操作元都是基本类型(原始类型):效果是重载前的算术运算
2、两个操作元都是非String类型的引用类型:编译无法通过,不支持
3、两个操作元都是String类型:重载操作
4、一个是String类型,一个是基本类型:重载操作
5、一个是String类型,一个是引用类型:重载操作
其实对于3、4两种情况,由于String类型的特殊性,编译器会在编译时做一些特殊处理,所以情况会变得稍微复杂一点。
1
public
class
StringTest
2
{
3
public
static
void
main(String[] args)
4
{
5
//
1.操作符两边都是基本类型(原始类型),则"+"操作符代表算术运算
6
//
2.操作符两边都是非String类型的引用类型,重载操作不支持,编译错误
7
//
3.操作符两边都是String类型
8
String s1
=
new
String(
"
hello
"
);
9
String s2
=
new
String(
"
world
"
);
10
String s3
=
s1
+
s2;
//
重载操作是通过StringBuilder实现的
11
12
//
4.操作符一边是基本类型(原始类型)
13
int
i
=
2008
;
14
String s4
=
new
String(
"
beijing
"
);
15
String s5
=
s4
+
i;
//
重载操作是通过StringBuilder实现的,
16
//
对于基本类型也并不是转化成String字符串再进行连接
17
18
//
5.操作符一边是引用类型
19
Integer in
=
new
Integer(
2008
);
20
String s6
=
s4
+
in;
//
重载操作是通过StringBuilder实现的,
21
//
对于引用类型in,通过in.toString()方法返回字符串,再进行连接
22
23
//
6.操作符都是String类型,且都是编译时可计算的
24
String s7
=
"
hello
"
+
"
world
"
;
//
编译后就确定了s7取值,并不需要等到运行时
25
System.out.println(s3
==
s7);
//
false, s3指向StringBuilder返回的,指向堆内存的新String对象,s7则指向String池
26
27
//
7.操作符一边是基本类型(原始类型)
28
String s8
=
"
beijing
"
+
2008
;
//
编译后就确定了s8取值,并不需要等到运行时
29
System.out.println(s5
==
s8);
//
false, s5指向StringBuilder返回的,指向堆内存的新String对象,s8则指向String池
30
31
String s9
=
"
beijing
"
+
i;
//
编译时无法计算出取值,s9的结果是指向堆内存
32
System.out.println(s8
==
s9);
//
false, s9指向的是堆内存,而s8指向String池
33
s7
+=
"
blogjava
"
;
//
编译时无法计算出取值,s7的结果是指向堆内存
34
System.out.println(s7
==
"
helloworld blogjava
"
.intern());
//
false, s7指向的是堆内存
35
}
36
}
37
查看反编译后的源代码或许更能理解String的运作机制:
Compiled from
"
StringTest.java
"
public
class
StringTest
extends
java.lang.Object
{
public
StringTest();
Code:
0
: aload_0
1
: invokespecial #
1
;
//
Method java/lang/Object."<init>":()V
4
:
return
public
static
void
main(java.lang.String[]);
Code:
0
:
new
#
2
;
//
class java/lang/String
3
: dup
4
: ldc #
3
;
//
String hello
6
: invokespecial #
4
;
//
Method java/lang/String."<init>":(Ljava/lang/String;)V
9
: astore_1
10
:
new
#
2
;
//
class java/lang/String
13
: dup
14
: ldc #
5
;
//
String world
16
: invokespecial #
4
;
//
Method java/lang/String."<init>":(Ljava/lang/String;)V
19
: astore_2
20
:
new
#
6
;
//
class java/lang/StringBuilder
23
: dup
24
: invokespecial #
7
;
//
Method java/lang/StringBuilder."<init>":()V
27
: aload_1
28
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
31
: aload_2
32
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
35
: invokevirtual #
9
;
//
Method java/lang/StringBuilder.toString:()Ljava/lang/String;
38
: astore_3
39
: sipush
2008
42
: istore
4
44
:
new
#
2
;
//
class java/lang/String
47
: dup
48
: ldc #
10
;
//
String beijing
50
: invokespecial #
4
;
//
Method java/lang/String."<init>":(Ljava/lang/String;)V
53
: astore
5
55
:
new
#
6
;
//
class java/lang/StringBuilder
58
: dup
59
: invokespecial #
7
;
//
Method java/lang/StringBuilder."<init>":()V
62
: aload
5
64
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
67
: iload
4
69
: invokevirtual #
11
;
//
Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
72
: invokevirtual #
9
;
//
Method java/lang/StringBuilder.toString:()Ljava/lang/String;
75
: astore
6
77
:
new
#
12
;
//
class java/lang/Integer
80
: dup
81
: sipush
2008
84
: invokespecial #
13
;
//
Method java/lang/Integer."<init>":(I)V
87
: astore
7
89
:
new
#
6
;
//
class java/lang/StringBuilder
92
: dup
93
: invokespecial #
7
;
//
Method java/lang/StringBuilder."<init>":()V
96
: aload
5
98
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
101
: aload
7
103
: invokevirtual #
14
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
106
: invokevirtual #
9
;
//
Method java/lang/StringBuilder.toString:()Ljava/lang/String;
109
: astore
8
111
: ldc #
15
;
//
String helloworld
113
: astore
9
115
: getstatic #
16
;
//
Field java/lang/System.out:Ljava/io/PrintStream;
118
: aload_3
119
: aload
9
121
: if_acmpne
128
124
: iconst_1
125
:
goto
129
128
: iconst_0
129
: invokevirtual #
17
;
//
Method java/io/PrintStream.println:(Z)V
132
: ldc #
18
;
//
String beijing2008
134
: astore
10
136
: getstatic #
16
;
//
Field java/lang/System.out:Ljava/io/PrintStream;
139
: aload
6
141
: aload
10
143
: if_acmpne
150
146
: iconst_1
147
:
goto
151
150
: iconst_0
151
: invokevirtual #
17
;
//
Method java/io/PrintStream.println:(Z)V
154
:
new
#
6
;
//
class java/lang/StringBuilder
157
: dup
158
: invokespecial #
7
;
//
Method java/lang/StringBuilder."<init>":()V
161
: ldc #
10
;
//
String beijing
163
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
166
: iload
4
168
: invokevirtual #
11
;
//
Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
171
: invokevirtual #
9
;
//
Method java/lang/StringBuilder.toString:()Ljava/lang/String;
174
: astore
11
176
: getstatic #
16
;
//
Field java/lang/System.out:Ljava/io/PrintStream;
179
: aload
10
181
: aload
11
183
: if_acmpne
190
186
: iconst_1
187
:
goto
191
190
: iconst_0
191
: invokevirtual #
17
;
//
Method java/io/PrintStream.println:(Z)V
194
:
new
#
6
;
//
class java/lang/StringBuilder
197
: dup
198
: invokespecial #
7
;
//
Method java/lang/StringBuilder."<init>":()V
201
: aload
9
203
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
206
: ldc #
19
;
//
String blogjava
208
: invokevirtual #
8
;
//
Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
211
: invokevirtual #
9
;
//
Method java/lang/StringBuilder.toString:()Ljava/lang/String;
214
: astore
9
216
: getstatic #
16
;
//
Field java/lang/System.out:Ljava/io/PrintStream;
219
: aload
9
221
: ldc #
20
;
//
String helloworld blogjava
223
: invokevirtual #
21
;
//
Method java/lang/String.intern:()Ljava/lang/String;
226
: if_acmpne
233
229
: iconst_1
230
:
goto
234
233
: iconst_0
234
: invokevirtual #
17
;
//
Method java/io/PrintStream.println:(Z)V
237
:
return
}
posted on 2008-01-09 00:08
菜园小鸟
阅读(1942)
评论(6)
编辑
收藏
FeedBack:
#
re: 一题有关String笔试题的分析
2008-01-09 07:46 |
vagrant
其实这也和另一个知识相关:= 和 equals区别.equals是判断两个对象的值是否相等,而=则判断值和地址是否相等.
回复
更多评论
#
re: 一题有关String笔试题的分析
2008-01-09 08:24 |
Matthew Chen
第一题不是说一种吗,好像看哪里说过常量池是编译期结束就创建好的,运行时不会创建。
回复
更多评论
#
re: 一题有关String笔试题的分析
2008-01-09 09:29 |
隔叶黄莺
对于这种问题我基本是不愿多看细看的,讨论多了都无益,如果照很多人的想法可以无限伸展,就比如一个有许多个对象属性的类
Class1{
Object obj1;
Object obj1;
Object obj1;
Object obj1;
Object obj1;
.........
}
new Class1() 谁能说创建了几个对象,那如果属性嵌属性,很深很深层次的,又会创建几个对象,有多大意义呢
可能对于 new String("xyz") 就是存在一个常量池的问题,有时要考虑编译优化的问题,就这么简单,何必搞得这么复杂。
回复
更多评论
#
re: 一题有关String笔试题的分析[未登录]
2008-01-09 10:34 |
abc
这些原理是属于编程基础吧?
回复
更多评论
#
re: 一题有关String笔试题的分析
2008-01-09 13:14 |
你是楼猪
讨论这没多大意义,很讨厌死抠这些的hr
回复
更多评论
#
re: 一题有关String笔试题的分析
2008-01-09 20:10 |
sitinspring
留个记号。
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
<
2008年1月
>
日
一
二
三
四
五
六
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔档案
2008年2月 (1)
2008年1月 (2)
搜索
最新评论
1. re: 代理模式与动态代理模式
简单易懂
--陶然楠轩
2. re: 一题有关String笔试题的分析
留个记号。
--sitinspring
3. re: 一题有关String笔试题的分析
讨论这没多大意义,很讨厌死抠这些的hr
--你是楼猪
4. re: 一题有关String笔试题的分析[未登录]
这些原理是属于编程基础吧?
--abc
5. re: 一题有关String笔试题的分析
评论内容较长,点击标题查看
--隔叶黄莺
阅读排行榜
1. 代理模式与动态代理模式(8003)
2. 一题有关String笔试题的分析(1942)
3. TestString(219)
评论排行榜
1. 一题有关String笔试题的分析(6)
2. 代理模式与动态代理模式(1)
3. TestString(0)