1. String s1="codingfish";
2. String s2="coding";
3. String s3="fish";
4. String s4="coding"+"fish";
5. String s5="cod"+"ing"+"fish";
6. String s6= s2 + s3;
7. String s7=new String("codingfish");
8. System.out.println(s1==s4);
9. System.out.println(s1==s5);
10. System.out.println(s1==s6);
11. System.out.println(s1==s7);
之前一直看到这个==判别题目,自己总是会晕
自己只了解==是辨别两个对象引用是否指向同一对象。
自己就试着根据以上例子来总结一下。
先来介绍一个概念-常量池
常量池(constant pool): 专门用于管理在编译期间被确定并已经保存在已经编译的.class文件中的一些数据。它包括了关于类、方法、接口、中的常量,还包括字符串常量。
再看上面一段程序
// s1 直接引用常量池中的"codingfish"
1. String s1="codingfish";
2. String s2="coding";
3. String s3="fish";
// s4中的引用的两个字符串在编译期间就能确定
// s4就直接引用常量池中的"codingfish"
4. String s4="coding"+"fish";
// 同理s5中的引用的两个字符串在编译期间就能确定
// s5就直接引用常量池中的"codingfish"
5. String s5="cod"+"ing"+"fish";
// s6中后面的两个字符串不能在编译期间就能确定
// 不能引用常量池中的"codingfish"
6. String s6= s2 + s3;
// new会调用构造器创建一个新的String对象
// s7引用的是堆内存新建的String对象
7. String s7=new String("codingfish");
// 输出true
8. System.out.println(s1==s4);
// 输出true
9. System.out.println(s1==s5);
// 输出false
10. System.out.println(s1==s6);
// 输出false
11. System.out.println(s1==s7);
JVM常量池保证相同的字符串直接量只有一个,不会产生多少个副本。上门代码中s1、s4、s5所引用的字符串都可以在编译器确定下来,因此他们所引用的都是常量池中的同一字符串对象。
这里我实际运行了一下,发现==的判别值在上面s4==s1为false,但是s1的和s4的实际地址显示的都是一样。
编译期能确定相同的字符串才会指向常量池中同一个字符串,上面程序中的s4只有在编译之后才能得出其地址值,故s1、s4虽然最终地址值相同,但s1==s4的值为false。