- 浏览: 350972 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
bsc2xp:
作者的文章不错,但是程序好像有错误:1、StreamFilte ...
Java6.0新特性之StAX--全面解析Java XML分析技术 -
bystander_:
写的真好啊, 牛
JAVA面试题解惑系列合集恢复下载 -
qdp150273:
想下载,怎么下载不了
《JAVA面试题解惑系列合集》PDF电子书下载 -
qdp150273:
不错啊,受益匪浅
《JAVA面试题解惑系列合集》PDF电子书下载 -
miroki:
感谢分享!
JAVA面试题解惑系列合集恢复下载
removed.
请到博文下载PDF文件:http://zangweiren.iteye.com/blog/241218
请到博文下载PDF文件:http://zangweiren.iteye.com/blog/241218
评论
100 楼
xunke515
2013-09-09
JAVA面试题解惑系列(二)——到底创建了几个String对象?
我们来看这段代码:
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
运行结果:
1. b没被加入字符串池中,新建了对象
----------------------------------
我这里运行给出的是 "b被加入了字符串池中,没有新建对象" . 楼主做过测试用例么,可否指点下迷津.
我们来看这段代码:
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
运行结果:
1. b没被加入字符串池中,新建了对象
----------------------------------
我这里运行给出的是 "b被加入了字符串池中,没有新建对象" . 楼主做过测试用例么,可否指点下迷津.
99 楼
woaiyingyu123
2010-05-21
LZ写得很详细。以后多写点哦。楼主。谢谢!
98 楼
wzju64676266
2010-03-04
public class StringStaticTest {
// 常量A
public static final String A;
// 常量B
public static final String B;
static {
A = "ab";
B = "cd";
}
public static void main(String[] args) {
// 将两个常量用+连接对s进行初始化
String s = A + B;
String t = "abcd";
if (s == t) {
System.out.println("s等于t,它们是同一个对象");
} else {
System.out.println("s不等于t,它们不是同一个对象");
}
}
}
它的运行结果是这样:
s不等于t,它们不是同一个对象
只是做了一点改动,结果就和刚刚的例子恰好相反。我们再来分析一下。A和B虽然被定义为常量(只能被赋值一次),但是它们都没有马上被赋值。在运算出s的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此A和B在被赋值之前,性质类似于一个变量。那么s就不能在编译期被确定,而只能在运行时被创建了。
由于字符串池中对象的共享能够带来效率的提高,因此我们提倡大家用引号包含文本的方式来创建String对象,实际上这也是我们在编程中常采用的。
我不知道你解释的是哪个版本的jdk,在jdk1.5下你的解释是有问题的
public static final String A;
// 常量B
public static final String B;
static {
A = "ab";
B = "cd";
}
这么定义的话jdk会把代码优化成
public static final String A= "ab";
// 常量B
public static final String B= "cd";
省去了
static {
A = "ab";
B = "cd";
}
这个环节。。。。
而下面的
String s = A + B;
会变成String s = (new StringBuilder(String.valueOf(A))).append(B).toString();
最终编译器会把你的代码编译成
String s = (new StringBuilder(String.valueOf(A))).append(B).toString();
String t = "abcd";
if (s == t) {
System.out.println("s等于t,它们是同一个对象");
} else {
System.out.println("s不等于t,它们不是同一个对象");
}
试问这怎么会相等呢,您写得相当不错,有很多知识是从您这里学过来的,^_^
// 常量A
public static final String A;
// 常量B
public static final String B;
static {
A = "ab";
B = "cd";
}
public static void main(String[] args) {
// 将两个常量用+连接对s进行初始化
String s = A + B;
String t = "abcd";
if (s == t) {
System.out.println("s等于t,它们是同一个对象");
} else {
System.out.println("s不等于t,它们不是同一个对象");
}
}
}
它的运行结果是这样:
s不等于t,它们不是同一个对象
只是做了一点改动,结果就和刚刚的例子恰好相反。我们再来分析一下。A和B虽然被定义为常量(只能被赋值一次),但是它们都没有马上被赋值。在运算出s的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此A和B在被赋值之前,性质类似于一个变量。那么s就不能在编译期被确定,而只能在运行时被创建了。
由于字符串池中对象的共享能够带来效率的提高,因此我们提倡大家用引号包含文本的方式来创建String对象,实际上这也是我们在编程中常采用的。
我不知道你解释的是哪个版本的jdk,在jdk1.5下你的解释是有问题的
public static final String A;
// 常量B
public static final String B;
static {
A = "ab";
B = "cd";
}
这么定义的话jdk会把代码优化成
public static final String A= "ab";
// 常量B
public static final String B= "cd";
省去了
static {
A = "ab";
B = "cd";
}
这个环节。。。。
而下面的
String s = A + B;
会变成String s = (new StringBuilder(String.valueOf(A))).append(B).toString();
最终编译器会把你的代码编译成
String s = (new StringBuilder(String.valueOf(A))).append(B).toString();
String t = "abcd";
if (s == t) {
System.out.println("s等于t,它们是同一个对象");
} else {
System.out.println("s不等于t,它们不是同一个对象");
}
试问这怎么会相等呢,您写得相当不错,有很多知识是从您这里学过来的,^_^
97 楼
netscript
2009-05-07
不知道博主还能不能看到我的回复,我想对你说你是个挺负责任的博主,帮很多人回复并解释了问题,所以我看完你的帖子后也有个自己的理解,想请你指教一下我理解的对不对,String str1 = new String("abcd");这行代码创建了2个对象,一个是str1指向的那个对象,一个是"abcd",它们都放在了堆里,并且把"abcd"这个对象的引用又放到了栈(字符串池)里,当再执行一次String str2 = new String("abcd");这行代码,那么这次就只创建了一个对象也就是str2指向的那个对象,因为"abcd"已经在栈里了,当执行String str3 = "abcd";这行代码时并没有创建对象,只是从栈(字符串池)中取出了已经存在的"abcd"对象的引用给了str3,先说这些,不确定对不对,我是初学者,在找工作,多请博主和大家指教了,谢谢。
96 楼
Ronald9
2008-12-13
1)看JDK帮助文档
2)看JDK源码(在JDK中包含有,可以通过阅读源码借鉴别人的思路,并了解JDK的实现)
3)看SCJP相关文档
4)百度或google
2)看JDK源码(在JDK中包含有,可以通过阅读源码借鉴别人的思路,并了解JDK的实现)
3)看SCJP相关文档
4)百度或google
95 楼
Ronald9
2008-12-13
1)
String str1 = "hello";
这句话执行时,先会在 字符串常量池 中看有没有字符串"hello",如果有,则将引用变量str1指向字符串"hello";如果没有,则创建"hello"然后将str1指向它;
内存分布情况:
引用变量str1在栈
"hello"在字符串常量池
System.out.println(str1.equals("hello"));
输出结果:true
因为他们都指向的是字符串常量池中的字符串"hello"
2)String str2 = new String("hello");
这句话执行时,先会在 字符串常量池 中看有没有字符串"hello",如果有,则将复制一份并在堆中创建一个对象,引用变量str2指向堆中的字符串对象,其值为:字符串"hello";如果没有,则先在字符串常量池中创建"hello"然后执行上面的步骤.
内存分布情况:
引用变量str1在栈
"hello"在字符串常量池
new String("hello")在堆中
System.out.println(str1==str2);
输出结果:false
str1指向的是字符串常量池中的"hello"
str2指向的是堆中的字符串对象"hello"
3)String str3 = new String("hello");
str3 = str3.intern();
System.out.println(str1==str3);
输出结果:true
str3 = str3.intern();
str3将引用字符串常量池中的"hello"
具体解释请参看JDK帮助文档相关内容.
String str1 = "hello";
这句话执行时,先会在 字符串常量池 中看有没有字符串"hello",如果有,则将引用变量str1指向字符串"hello";如果没有,则创建"hello"然后将str1指向它;
内存分布情况:
引用变量str1在栈
"hello"在字符串常量池
System.out.println(str1.equals("hello"));
输出结果:true
因为他们都指向的是字符串常量池中的字符串"hello"
2)String str2 = new String("hello");
这句话执行时,先会在 字符串常量池 中看有没有字符串"hello",如果有,则将复制一份并在堆中创建一个对象,引用变量str2指向堆中的字符串对象,其值为:字符串"hello";如果没有,则先在字符串常量池中创建"hello"然后执行上面的步骤.
内存分布情况:
引用变量str1在栈
"hello"在字符串常量池
new String("hello")在堆中
System.out.println(str1==str2);
输出结果:false
str1指向的是字符串常量池中的"hello"
str2指向的是堆中的字符串对象"hello"
3)String str3 = new String("hello");
str3 = str3.intern();
System.out.println(str1==str3);
输出结果:true
str3 = str3.intern();
str3将引用字符串常量池中的"hello"
具体解释请参看JDK帮助文档相关内容.
94 楼
jxausea
2008-12-09
楼主:我想知道String str=new String("abc"); 这行代码在内存中具体的操作。
你能帮我画一下在内存中的过程吗?(把堆和栈中的数据也表示出来)
谢谢LZ
你能帮我画一下在内存中的过程吗?(把堆和栈中的数据也表示出来)
谢谢LZ
93 楼
ZangXT
2008-10-07
java 虚拟机规范里面有对常量池的介绍.
92 楼
lkjust08
2008-09-18
请问楼主,对象的引用保存干什么地方? 字符串池中又是保有存的什么东东?
91 楼
magical4061
2008-09-01
回复 simple is power :
其实,咱们可以有另外一种更加简单的理解方法(这种方法只是便于大家理解,并非就是正确的),就是说
String s = "abc";
这个语句,是直接在字符串池中创建了一个对象,而 s 就是指向 字符串池中 这个对象的引用。
String s1 = new String("abc");
这个语句,在上一个语句的基础上(即字符串池中已经存在了一个abc对象),然后new 操作符 在堆中又创建了一个对象 ,这个对象的引用就是 s1.
而 s1.intern() 方法 ,就是在字符串池中查找 abc 对象,如果存在,就返回 字符串池中abc的引用(这里就是s)。
这样理解起来,是不是更容易一点呢。
其实,咱们可以有另外一种更加简单的理解方法(这种方法只是便于大家理解,并非就是正确的),就是说
String s = "abc";
这个语句,是直接在字符串池中创建了一个对象,而 s 就是指向 字符串池中 这个对象的引用。
String s1 = new String("abc");
这个语句,在上一个语句的基础上(即字符串池中已经存在了一个abc对象),然后new 操作符 在堆中又创建了一个对象 ,这个对象的引用就是 s1.
而 s1.intern() 方法 ,就是在字符串池中查找 abc 对象,如果存在,就返回 字符串池中abc的引用(这里就是s)。
这样理解起来,是不是更容易一点呢。
90 楼
simple is power
2008-09-01
如magical4061所说,如果下面的论述成立:
"String s = “abc”;
这里只是在堆中创建了一个对象,字符串池中并没有任何对象,只是存放了一个对于 “abc”对象的引用。 "
那么
String s = new String("abc");
单独这样一条语句也只是在堆中创建了一个对象,字符串池中并没有创建任何对象。
可不可以这样理解呢
"String s = “abc”;
这里只是在堆中创建了一个对象,字符串池中并没有任何对象,只是存放了一个对于 “abc”对象的引用。 "
那么
String s = new String("abc");
单独这样一条语句也只是在堆中创建了一个对象,字符串池中并没有创建任何对象。
可不可以这样理解呢
89 楼
magical4061
2008-09-01
让我试着来回复一下 simple is power 吧,看看我解释的对不对。
这点你是理解错误了,这里只是在堆中创建了一个对象,字符串池中并没有任何对象,只是存放了一个对于 “abc”对象的引用。
new操作符才另外在堆中创建了一个新的对象,这个新对象的引用就是str.
你所说的这2段代码,str1 都是 "string" 这个对象的引用,而str2 是 new操作符新创建的对象的引用。 而 “==”是比较两个对象的引用的,自然不会输出 "1 true" 。而equals 是比较两个String对象的字面值的,他们都是 "string" ,所以会输出 "2 true"来。
引用
String a="abc";
一句创建了两个对象,一个在堆中,一个在字符串池中
一句创建了两个对象,一个在堆中,一个在字符串池中
这点你是理解错误了,这里只是在堆中创建了一个对象,字符串池中并没有任何对象,只是存放了一个对于 “abc”对象的引用。
引用
而如果接下来在有 String str=new String("abc");
这样的语句则只在堆中创建一个对象。
这样的语句则只在堆中创建一个对象。
new操作符才另外在堆中创建了一个新的对象,这个新对象的引用就是str.
引用
(一)
String str1 = "string";
String str2 = new String("string");
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
(二)
String str2 = new String("string");
String str1 = "string";
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
为什么上面两种方式的输出结果一样,都是输出第二个语句呢?
String str1 = "string";
String str2 = new String("string");
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
(二)
String str2 = new String("string");
String str1 = "string";
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
为什么上面两种方式的输出结果一样,都是输出第二个语句呢?
你所说的这2段代码,str1 都是 "string" 这个对象的引用,而str2 是 new操作符新创建的对象的引用。 而 “==”是比较两个对象的引用的,自然不会输出 "1 true" 。而equals 是比较两个String对象的字面值的,他们都是 "string" ,所以会输出 "2 true"来。
88 楼
simple is power
2008-08-31
您的文章写的很好,学习了。
文章开篇即点题,指出
String str=new String("abc");
一句创建了两个对象,然后接下来思路一直非常清晰,虽然通篇未提第二个对象在哪里。
直到最后结尾时,反倒让我迷惑了。
最后一段让我觉得是
String a="abc";
一句创建了两个对象,一个在堆中,一个在字符串池中,而如果接下来在有
String str=new String("abc");
这样的语句则只在堆中创建一个对象。
请问到底是谁创建2个对象。
还有,如果String str=new String("abc");它创建两个对象,那么引用指向的是哪一个?如果String a="abc";创建两个对象,引用指向的是哪一个?
(一)
String str1 = "string";
String str2 = new String("string");
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
(二)
String str2 = new String("string");
String str1 = "string";
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
为什么上面两种方式的输出结果一样,都是输出第二个语句呢?
请解答。
文章开篇即点题,指出
String str=new String("abc");
一句创建了两个对象,然后接下来思路一直非常清晰,虽然通篇未提第二个对象在哪里。
直到最后结尾时,反倒让我迷惑了。
最后一段让我觉得是
String a="abc";
一句创建了两个对象,一个在堆中,一个在字符串池中,而如果接下来在有
String str=new String("abc");
这样的语句则只在堆中创建一个对象。
请问到底是谁创建2个对象。
还有,如果String str=new String("abc");它创建两个对象,那么引用指向的是哪一个?如果String a="abc";创建两个对象,引用指向的是哪一个?
(一)
String str1 = "string";
String str2 = new String("string");
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
(二)
String str2 = new String("string");
String str1 = "string";
if(str1==str2)
System.out.println("1 true");
if (str1.equals(str2))
System.out.println("2 true");
为什么上面两种方式的输出结果一样,都是输出第二个语句呢?
请解答。
87 楼
yu_xian81
2008-08-25
看起头在转.看来只有在头最清醒的时候看,呵呵
86 楼
H_eaven
2008-08-05
String s1 = "ab";
String s2 = "cd";
String str = "abcd";
(s1 + s2) 是不等于 str 的. (JDK1.5以上...JDK1.5以前的没试过)
不等的原因:
例子:
public class StringTest
{
public static void main(String[] args) {
String s = "";
for (int i = 0; i < 10; i++ )
{
s += "abc";
}
System.out.println(s);
}
}
//----------------------------------
javap之后的代码:
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: ldc #2; //String
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: bipush 10
8: if_icmpge 37
11: new #3; //class java/lang/StringBuilder
14: dup
15: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
22: ldc #6; //String abc
24: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
27: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
30: astore_1
31: iinc 2, 1
34: goto 5
37: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
40: aload_1
41: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
44: return
}
注意:里面有第十一行11: new #3; //class java/lang/StringBuilder
虽然代码里全部都是用"+"号连接字符串,
但编译器还是比较聪明的,它会生成一个StringBuilder对象来进行字符串的连接工作.
经过StringBuilder这一道手,转化后的String对象就是一个新对象了.
("ab" + "cd") 与原生的 "abcd" 就不是同一个对象了.
String s2 = "cd";
String str = "abcd";
(s1 + s2) 是不等于 str 的. (JDK1.5以上...JDK1.5以前的没试过)
不等的原因:
例子:
public class StringTest
{
public static void main(String[] args) {
String s = "";
for (int i = 0; i < 10; i++ )
{
s += "abc";
}
System.out.println(s);
}
}
//----------------------------------
javap之后的代码:
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: ldc #2; //String
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: bipush 10
8: if_icmpge 37
11: new #3; //class java/lang/StringBuilder
14: dup
15: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
22: ldc #6; //String abc
24: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
27: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
30: astore_1
31: iinc 2, 1
34: goto 5
37: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
40: aload_1
41: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
44: return
}
注意:里面有第十一行11: new #3; //class java/lang/StringBuilder
虽然代码里全部都是用"+"号连接字符串,
但编译器还是比较聪明的,它会生成一个StringBuilder对象来进行字符串的连接工作.
经过StringBuilder这一道手,转化后的String对象就是一个新对象了.
("ab" + "cd") 与原生的 "abcd" 就不是同一个对象了.
85 楼
臧圩人
2008-08-03
回复jiakechong:
你好,后续的文章会有介绍集合类的部分的,请保持关注
你好,后续的文章会有介绍集合类的部分的,请保持关注
84 楼
jiakechong
2008-08-03
楼主可以介绍1篇
java.util.这个包这个经常用,如map(hashmap,hashtable)
list(arraylist.vector..) ,set等等
java.util.这个包这个经常用,如map(hashmap,hashtable)
list(arraylist.vector..) ,set等等
83 楼
jiakechong
2008-08-03
引用 lggege 2008-07-03
1.
JVM 中, 线程持有Stack, Stack随线程创建而创建.
Heap 则是JVM启动时就启动, 共享, 由垃圾回收机制清理.
2.
Stack 和 Heap都是在Ram中划分.
3.
基本型 int, char...等在创建前会查看Stack中是否已经有, 有则则向, 没有则新建.
4.
String 可以想象为与char[]等同, String a= "abc", 首先在Heap中创一个对象, 再到Stack中找char[]是否存在, 有则 指向该地址, 无则在Stack中创建.
5.
String a = new("abc"); new()出来的都会有自己的独立存放, 不会像前面一样的指向, 而是指向新创建的.
6.
== 基本型比值, 对象比引用.
1.
JVM 中, 线程持有Stack, Stack随线程创建而创建.
Heap 则是JVM启动时就启动, 共享, 由垃圾回收机制清理.
2.
Stack 和 Heap都是在Ram中划分.
3.
基本型 int, char...等在创建前会查看Stack中是否已经有, 有则则向, 没有则新建.
4.
String 可以想象为与char[]等同, String a= "abc", 首先在Heap中创一个对象, 再到Stack中找char[]是否存在, 有则 指向该地址, 无则在Stack中创建.
5.
String a = new("abc"); new()出来的都会有自己的独立存放, 不会像前面一样的指向, 而是指向新创建的.
6.
== 基本型比值, 对象比引用.
82 楼
臧圩人
2008-08-02
回复naff:
关于字符串池请参考这个回复:
不过遗憾的是,关于字符串池,我还没有找到专门的深入介绍其内部结构与实现的资料。
关于字符串池请参考这个回复:
臧圩人 写道
回复nbawukun:
对象总是被保存在堆中,而引用总是被保存在栈中。
实际上是字符串池搅乱了我们的思路。我觉得可以把它看作一个数组,字符串被保存池中,实际上只是在字符串池中保存了这个字符串的引用,实际的字符串对象仍像其它对象一样被保存在堆中了。只不过通过new创建的字符串对象在被保存在堆中的同时,并没有在字符串池中保存它的引用,因此字符串池并不知道它的存在,也就无法将它共享使用。
对象总是被保存在堆中,而引用总是被保存在栈中。
实际上是字符串池搅乱了我们的思路。我觉得可以把它看作一个数组,字符串被保存池中,实际上只是在字符串池中保存了这个字符串的引用,实际的字符串对象仍像其它对象一样被保存在堆中了。只不过通过new创建的字符串对象在被保存在堆中的同时,并没有在字符串池中保存它的引用,因此字符串池并不知道它的存在,也就无法将它共享使用。
不过遗憾的是,关于字符串池,我还没有找到专门的深入介绍其内部结构与实现的资料。
81 楼
naff
2008-07-31
接下来我们再来看看intern()方法,它的定义如下:
Java代码
public native String intern();
public native String intern();
这是一个本地方法。在调用这个方法时,JAVA虚拟机首先检查字符串池中是否已经存在与该对象值相等对象存在,如果有则返回字符串池中对象的引用;如果没有,则先在字符串池中创建一个相同值的String对象,然后再将它的引用返回。
我们来看这段代码:
Java代码
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
运行结果:
b没被加入字符串池中,新建了对象
=====================
以上是您文章内的一段。
能否请您详细的解说下代码的分析.
小弟新学,请赐教.
想问下字符串池它的方式和属性之类的.
谢谢.
Java代码
public native String intern();
public native String intern();
这是一个本地方法。在调用这个方法时,JAVA虚拟机首先检查字符串池中是否已经存在与该对象值相等对象存在,如果有则返回字符串池中对象的引用;如果没有,则先在字符串池中创建一个相同值的String对象,然后再将它的引用返回。
我们来看这段代码:
Java代码
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
public class StringInternTest {
public static void main(String[] args) {
// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为"abcd"的对象
String a = new String(new char[] { 'a', 'b', 'c', 'd' });
String b = a.intern();
if (b == a) {
System.out.println("b被加入了字符串池中,没有新建对象");
} else {
System.out.println("b没被加入字符串池中,新建了对象");
}
}
}
运行结果:
b没被加入字符串池中,新建了对象
=====================
以上是您文章内的一段。
能否请您详细的解说下代码的分析.
小弟新学,请赐教.
想问下字符串池它的方式和属性之类的.
谢谢.
发表评论
-
JAVA面试题解惑系列(十一)——这些运算符你是否还记得?
2008-08-25 00:45 14055removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(十)——话说多线程
2008-08-08 18:55 17190removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(九)——继承、多态、重载和重写
2008-07-31 00:35 21121removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(八)——聊聊基本类型(内置类型)
2008-07-25 10:24 15874removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(七)——日期和时间的处理
2008-07-22 16:31 15542removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(六)——字符串(String)杂谈
2008-07-18 09:35 17724removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(五)——传了值还是传了引用?
2008-07-13 17:24 17842removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(四)——final、finally和finalize的区别
2008-07-08 09:25 18738removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(三)——变量(属性)的覆盖
2008-07-03 22:33 15695removed. 请到博文下载PDF文件:http://za ... -
JAVA面试题解惑系列(--)——参透Servlet
2008-07-01 22:12 0------ -
JAVA面试题解惑系列(--)——几对孪生兄弟的是是非非
2008-06-28 23:12 0HashMap和Hashtable StringBuffer和 ... -
JAVA面试题解惑系列(--)——垃圾收集器(GC)如何运转?
2008-06-28 16:15 0----- -
JAVA面试题解惑系列(--)——位运算符“>>”、“>>>”、“<<”和“<<<”
2008-06-26 13:54 0----- -
JAVA面试题解惑系列(十二)——你真的了解数组吗?
2008-06-26 13:52 0作者:臧圩人(zangweiren) 网址:http://za ... -
JAVA面试题解惑系列(一)——类的初始化顺序
2008-06-26 10:13 26876removed. 请到博文下载PDF文件:http://za ...
相关推荐
JAVA 面试题解惑系列之 String 对象创建机制 本文将深入探讨 JAVA 中 String 对象的创建机制,解答常见的面试题目,并探索 String 对象池的概念和机制。 一、String 对象的创建方式 在 JAVA 中,String 对象可以...
.3 1.2 JAVA面试题解惑系列(二)——到底创建了几个String对象? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1.3 JAVA面试题解惑系列(三)——变量(属性)的覆盖 . . . . . . . . . . . . ....
**1.2 JAVA面试题解惑系列(二)——到底创建了几个String对象?** - **知识点**:探讨Java中String对象的创建机制,特别是常量池的概念和String对象的内存分配策略。了解字符串字面量与`new String()`的区别,以及...
这个压缩包可能包含了两本书籍,一本是"JAVA面试题解惑系列.pdf",另一本是"臧圩人--JAVA面试题解惑系列合集.pdf"。这些资源旨在帮助求职者准备Java开发相关的面试,提升他们对Java技术的理解和应用能力。 在Java...
2、到底创建了几个String对象;3、变量(属性)的覆盖;4、final,finally,finalize;5.传了值还是传了引用;6.String杂谈;7.日期与时间的处理;8.基本类型总结;9.继承,多态,重载,重写;10.多线程;11.运算符...
首先,我们来看“JAVA面试题解惑系列(二)——到底创建了几个String对象?”这个问题。在Java中,String是不可变的,这意味着一旦创建,其内容就不能改变。因此,每当对String进行操作,如拼接或赋值,实际上可能...
《经典JAVA面试题解惑系列合集(臧圩人)》这本书很可能就是针对这些问题进行深入解析的一本指南。 首先,Java的基础知识是面试中的必考部分。这包括但不限于Java语法、数据类型、控制结构(如if语句、for循环、...
【JAVA面试题解惑系列】是一系列专门针对Java开发者面试准备的文章集合,涵盖了多个核心Java概念和面试常问问题。作者臧圩人在JavaEye社区分享了这个系列,旨在帮助求职者理解和解答面试中可能出现的疑问。 1. **类...
在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...
Java中的字符串(String)是编程面试中的热门话题,其特性与操作是面试官常常用来考察候选人基础知识的手段。本文将深入探讨String对象的一些关键知识点。 首先,我们要了解`String`类的`length()`方法。这个方法返回...
JAVA面试题解惑系列(一)——类的初始化顺序 JAVA 是一门面向对象的编程语言,类的初始化顺序是 JAVA 程序员和 JAVA 工程师面试中一个非常重要的知识点。本文将详细讲解类的初始化顺序,并提供了相关的测试代码,...
《JAVA面试题解惑系列——类的初始化顺序》 在Java编程中,理解类的初始化顺序是面试中常见的考察点,因为它直接关系到程序的执行逻辑。本文将深入探讨类的初始化过程,以及在继承场景下如何理解这个过程。 首先,...
Java面试题是每个Java开发者在求职过程中必须面对的挑战,涵盖范围广泛,从基础概念到高级特性和设计模式。这份终极列表包含115个Java面试题和答案,旨在帮助求职者全面准备,以期在面试中表现出色。以下是部分核心...
本文通过对Java面试题中的两个典型问题——类的初始化顺序和String对象的创建——进行了深入分析。这些知识点不仅是Java编程的基础,也是深入理解Java语言特性的关键。掌握这些内容不仅能够帮助开发者在面试中表现...