public class StringTest {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s2 == s3);
System.out.println(s1 == s1.intern());
System.out.println(s2 == s2.intern());
System.out.println(s1.intern() == s3.intern());
String hello = "hello";
String lo = "lo";
System.out.println(hello == "hel"+"lo");
System.out.println(hello == "hel"+lo);
}}
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s2 == s3);
System.out.println(s1 == s1.intern());
System.out.println(s2 == s2.intern());
System.out.println(s1.intern() == s3.intern());
String hello = "hello";
String lo = "lo";
System.out.println(hello == "hel"+"lo");
System.out.println(hello == "hel"+lo);
}}
解决方案 »
- Java Socket中怎么将从c发过来的字节字符串转成char型字符串
- 〓〓拷贝文件new byte[size]的大小指定问题〓〓
- 能否重复使用该对象?
- 生成的JAR文件,JDBC怎么配置?已经放到CLASSPATH里面了,还是不行
- jfreechart中折线图的横轴数据点太多,怎么能加一个滚条,并且设置最小间距?否则显示太模糊了。
- 请问JAVA如何调用shell程序啊?
- J2EE 1.3及J2EE1.4所应对应的js2dk的版本应是什么?
- 怎么得到当前执行的程序的路径,而不是运行的路径?
- 帮我想想这个怎么做?
- 求JBuilder9的注册码!急呀!
- executeBatch()的问题,急啊!!望高手指教
- 一直以来都有个问题不太明白.
false
false
false
true
true
true
false这个是运行结果,有些不解
关注高手解答
public static void main(String args[]){
String str1 = "I am a String";
String str2 = "I am a String";
String str3 = new String("I am a String");
String str5 = "I am a ";
String str6 = "String";
String str7 = str5 + str6;
String str8 = "I am a " + "String";
String str9 = str3.intern();
String str10 = str7.intern();
if(str1 == str2)
System.out.println("str1 and str2 are the same String.");
else
System.out.println("str1 and str2 are the different Strings.");
if(str1 == str3)
System.out.println("str1 and str3 are the same String.");
else
System.out.println("str1 and str3 are the different Strings.");
if(str1 == str7)
System.out.println("str1 and str7 are the same String.");
else
System.out.println("str1 and str7 are the different Strings.");
if(str1 == str8)
System.out.println("str1 and str8 are the same String.");
else
System.out.println("str1 and str8 are the different Strings.");
if(str1 == str9)
System.out.println("str1 and str9 are the same String.");
else
System.out.println("str1 and str9 are the different Strings.");
if(str1 == str10)
System.out.println("str1 and str10 are the same String.");
else
System.out.println("str1 and str10 are the different Strings.");
}
}
运行的结果是:str1 and str2 are the same String.
str1 and str3 are the different Strings.
str1 and str7 are the different Strings.
str1 and str8 are the same String.
str1 and str9 are the same String.
str1 and str10 are the same String.
解释以上的输出结果,首先要理解一个叫String Pool的概念,虽然JVM没有明确提出这个概念,但是细想一下,别的语言String基本都是作为基本类型来处理的,而在Java中直接就是一个对象,然而奇怪的是对象能像基本类型那样直接赋常量。这就能看出Java设计者的那种取舍吧,毕竟作为对象来处理的话,效率没有基本类型那样高。我们不需要更多的理解,直接记住String str1 = "I am a String";是把"I am a String"扔到了字符串池中,然后把引用抛给str1,以后再有相同值的String变量也是这种赋值语句的,那么还是存在字符串池中,有就直接返回引用,没有就创建一个新的。所以说着语句就创建了一个String对象。再看下一个String str3 = new String("I am a String");这个创建了几个对象?两个!不要怀疑!一个是在new String("I am a String")创建在heap中的,另一个是str3也在heap中,它们所指向的字符数组是相同的,位于内存区的常量池中。关于这一点,请看大企鹅的这篇blog:《 还是 String》。接下来看str7和str8,明明两个的值是一样的,为什么结果不一样呢?这就牵扯到Java编译器对于不同str8的优化了。因为str7右边的是两个变量,而不是直接的两个值,编译器就无法在编译期间知道str8的值,相反,str8对于编译器来说直接就是str8 = "I am a String"了,这样的两种不同的情况,就有不同的结果了。再看str3和str7都和返回否定的,而为什么str9和str10返回的是一致的呢?因为intern()方法是把执行该方法的引用拖到了字符串池中,当然了如果字符串池中有的话,就直接返回引用了。总结一下就是:
1. 区分好String str1 = "I am a String"和String str3 = new String("I am a String")创建对象的数目和地方。
2. 了解String str1 = "I am a " + "String"是编译期间确定值的。
3. 了解intern()方法。
堆和栈的区分,还有引用和被引用的内容上在JAVA里的区分。
其实Java不是没有指针,而是他们把指针都封装了,这样一来你就可以这么理解String类型了,它表现出来的是
内容,而其实存的还是指针,定义了2个String类型的变量,他们的存储位置是不一样的,所以他们的值就是不
一样,因为在 == 运算符中没有进行自动的转化成String中的内容,还是使用的是指针。
所以就是 False 了
flase
true
.....我只能写出前面的几个结果,但是和大家的一看,
好像不是太对啊,请高手帮忙啦,这个题目还是比较普遍的
,每次都是的,不知道为什么每次都做错.....
创建对象==是如何也不会相等的,而字符串中的就会相等
至于intern,查看API,解释的很清楚而下面的两个hello,感觉都是false,但是第一个却是TRUE,还需要考虑一下
用“==”时比较的是地址,当你new两个对象的时候它们的地址肯定是不一样的,当用equals比较时比较的是hashcode值是否一样,当然你重写equals方法后比较的就不是hashcode的值了,String,Date,封装类和File类都重写了equals方法,所以比较的是内容而不是hashcode的值;
当对一个字符串调用intern(),就是把该字符串放到String Pool当中
== 要比较地址
equals 比较值
String hello = "hello"; String lo = "lo"; System.out.println(hello == "hel"+"lo"); //trueSystem.out.println(hello == "hel"+lo); //字符串+连接如果有个一为变量就相当于new。所以"hel"+lo是在堆里new了一个对象。 false
String hello = "hello"; String lo = "lo"; System.out.println(hello == "hel"+"lo"); System.out.println(hello == "hel"+lo);
s1和s3都是new出来的,所以都在堆里面,他们两个相当于两根不同的指针,只是指针指向了相同的abc(这里需要注意的是abc这个值是在池中的,相当于一个产量),所以s1和s3比较地址,也为false。
而s2没有new,所以他是直接从栈指向池中的abc,所以他和s1,s3也比地址,就为false。
String hello = "hello";
String lo = "lo";
System.out.println(hello == "hel"+"lo"); //这里为ture这是由于后面相当于两个池中的常量相加,结果也保存在池中,所有true
System.out.println(hello == "hel"+lo); //这里和上面不同的是后面的lo为栈里的指针,他是有可能改变指向的,例如lo ="aaa";那后面相加的结果也改变了,所以为 false