String对象问题

String对象问题
String对象问题

很常见,很经典的关于java 字符串的笔试面试试题,看了别人的讲解,然后用自 己理解的写出来,o( n _n )0哈哈。题目如下:

public static void main(String[] args)

{

Stri ng s = new Stri ng("abc");//执行到这一行时,创建了几个对象? String s1 = "abc";//执行到这一行时,创建了几个对象? Stri ng s2 = new Stri ng("abc");//执行到这一行时,创建了几个对象?

System.out .println(s == s1);/输出结果是什么?

System.out .println(s == s2);/输出结果是什么? System.out .println(s2 == s1);/输出结果是什么? 答案依次为: 2 个对象

没有对象

1个对象 false false false

试题详解:I.String s = new String("abc")执行此句时,首先在 String Pool (String 池)中查找有没有字符常量"abc",没有则在String Pool 中创建"abc"的对象,当执 行new String("abc")时则在java 的堆中创建一个"abc"对象,而s 则是该对象的引 用,因此共计创建 2个对象。

2.String s1 = "abc'执行此句时,首先还是在 String Pool 中查找有没有字符串常量 "abc",有则直接将s1作为String Pool 中"abc"的一个引用,因此此时没有创建任何 对象。

3.String s2 = new String("abc")执行此句时,依旧在 String Pool 中查找有没有字符串 常量"abc",有则不进行再次创建,由于这里用了 new 关键字(有new 就有对 象),所有便在java 堆中又创建了一个"abc"刈象(地址与第一句在堆中创建的地址 不同),而s2则是这个对象的引用,因此执行此句时只创建了 1个对象。

4.我们知道"=="是判断对象的,因此由于s 指向的是java 堆中的"abc"对象而s1指 向的则是String Pool 中的"abc"对象,所以输出false 。

5.6判断同上

1. 2. 3. 4. 5.

6. 7. 8. 9.

10.}

P ackage com; import org.j un it.Test; p ublic class TestStri ng { p ublic void test1()

Stri ng s = new Stri ng("abc");

Stri ng s1 = "abc";

Stri ng s2 = new Stri ng("abc");

System.out. pnntln(s == s1);

System.out. pnntln(s == s2);

System.out. pnntln(s1 == s2);

System.out. pnntln(s == s.i ntern());

System.out. pnntln(s1 == s.i ntern());

System.out. prin tl n( s1.i ntern() == s2.i ntern());

上述代码中:

String s = new String("abc");请问在内存中创建了几个对象?分别在什么地方?

创建了两个对象,分别在String Pool(常量池)和Heap(堆)里.

首先生成了一个对象,叫"abc",在String Pool里面,先在常量池里查找是否有"abc",发现没有就把"abc"放入String Pool里面.

接下来,执行new String("abc")构造方法,new出来的对象都放在Heap里面.

在Heap里又创建了一个"abc"的对象.这时内存里就有两个对象了,一个在String

P ool

里面,一个在Heap里面.

只有String类型有String Pool(常量池),String类是不可变的类.在创建对象,先在常量池里查找是否有"abc"的常量,如果没有则创建一个新的,如果有则不会再创建,使用原来已经存在的.

其中s只是一个对象的引用(存放对象的地址),而不是对象.

在执行完第二句String s1 = "abc";后内存里创建了几个对象?为什么?

在执行完string s1 = "abc";后内存里一个对象也没有创建.因为在它先在String Pool 里面检查是否有内容为"abc"的字符串对象存在,发现已经有一个了,就不会再创建.(因为在执行完第一句已经存在一个"abc" 了).

在执行完第三句String s2 = new String("abc");后内存中创建了几个对象?为什么?

在执行完第三名,内存创建了一个对象.因为此句中的"abc"先在String Pool里面查找是否有内容为"abc"的对象,发现已经在在就不会再创建新的了然后new String("abc") 会在堆里创建一个新的"abc"对象,只要new出来的,不管内容是否相同,都会在Heap 中创建一个对象.

所以此句执行后只在Heap中创建了一个对象.

s == s.intern()其中s.intern()会首先在String Pool里查找是否有内容为"abc"的对象, 发现存在,就会返回String Pool里面内容为"abc"的对象,地址也指向它.所以此句输出false.

s1 == s.intern()同样,s1指向的是String Pool里面内容为"abc"的对象,所心此句输出true.

s1.intern() == s2.intern()同样,s1.intern()和s2.intern()指向的都String Pool 里面内容为"abc"的对象,所以此句输出true.

***********************************************

s == "hel" + "lo"当加号两边都是常量值时,就会组成一个新的常量值在String Pool里面.

如果String Pool已经有相同内容的就不会再创建.输出true.

"hel" + s2当加号两边有一个不是常量值,会在堆里面创建一个新的"hello"对象.输出false

s1 + s2同上,输出false.

P ublic void test2()

{

Stri ng s = "hello";

Stri ng s1 = "hel";

Stri ng s2 = "lo";

System.out .println(s == "hel" + "lo");

System.out .pnntln(s == "hel" + s2);

System.out. prin tl n(s == s1 + s2);

}

java.Iang.String 的intem()方法

"abc".internO方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用

处。但实际上,它做了个小动作:

检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。我们做个测试:String str1 = "a";

String str2 = "bc";

String str3 = "a"+"bc";

String str4 = str1+str2;

System.out.printIn(str3==str4); str4 = (str1+str2).intern();

System.out.printIn(str3==str4); 输出的结果将会是: faIse true

JDK的api文档是这么解释的:

返回字符串对象的规范化表示形式。一个初始时为空的字符串池,它由类String 私有地维护。当调用intern 方法时,如果池已经包含一个等于此String 对象的字符串(该对象由equals(Object)方法确定),则返回池中的字符串。否则,将此池中,并且返回此String 对象的引用。

String 对象添加到它遵循对于任何两个字符串s和t,当且仅当s.equals(t)为true

时,s.internO == t.intern() 才为true。

所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java Language Specificatior》〉的 3.10.5 中已定义。

返回:

一个字符串,内容与此字符串相同,但它保证来自字符串池中。

字符串字面池指的是常量池.

字符串对象的创建方式有两种如下:

String s1 = new String(""); // 第一种

String s2 = ""; //第二种

第一种始终不会入池的.

第二种要看情况而定(等号右边如果是常量则入池,非常量则不入池)

例:

String s3 = "a" + "b"; //"a"是常量,"b"是常量,常量+常量二常量,所以会入池.

String s4 = s1 + "b"; //s1是变量,"b"是常量,变量+常量!=常量,所以不会入池.

一旦入池的话,就会先查找池中有无此对象.如果有此对象,则让对象引用指向此对象; 如果无此对象,则先创建此对象,再让对象引用指向此对象.

例:

String s5 = "abc"; 〃先在池中查找有无"abc"对象,如果有,则让s5指向此对象;如果池中无"abc'对象,则在池中创建一个"abc'对象撚后让s5指向该对象.

补充一下:看了字节码后,发现

String str ="a"+"b";

完全等同于

String str="ab";

相关主题
相关文档
最新文档