赞
踩
关于String类型的等值比较和内容比较,是学习java甚至任何编程语言所共同的常见问题,理解String类型的等值比较和内容比较也是面试经常问到的问题。
字符串等值比较
- public final class String
- implements java.io.Serializable, Comparable<String>, CharSequence {
- /** The value is used for character storage. */
- private final char value[];
-
- public boolean equals(Object anObject) {
- if (this == anObject) {
- return true;
- }
- if (anObject instanceof String) {
- String anotherString = (String)anObject;
- int n = value.length;
- if (n == anotherString.value.length) {
- char v1[] = value;
- char v2[] = anotherString.value;
- int i = 0;
- while (n-- != 0) {
- if (v1[i] != v2[i])
- return false;
- i++;
- }
- return true;
- }
- }
- return false;
- }
首先,如上述String的源码可以知道的是,java中等值比较,就是“==”比较,比较的是地址。字符串本质上是final修饰的字符数组,也就是说,当创建字符串对象时,字符串的引用是常量,但它每一个对象的值可以改变。
字符串内容比较
如上述String的源码可以知道的是,字符串的内容比较就是所谓的字符串的equals()方法,比较的是两个字符串对象储存的值,也就是内容是否相等,所谓内容相同,就是字符串每一个位置的字符相同。这里值得注意的是String重写了Object的equals()方法(Object的==与equals()是一样的)
地址分配图示
很明显str1和str2的地址相同,他们与str3的地址不相同,但是str3通过方法intern(),可以强制入池,和str1和str2的地址相同。
结论
字符串:默认为常量------------进常量池
String val = “xxx”;---------------------------默认入池
String val = new String(“xxx”);--------------------------默认入堆,但可以通过intern()强制入池(堆里的对象还在)
String 类的常见面试问题
面试题一:
- String s1 = "abc"; // 常量池
- String s2 = new String("abc"); // 堆内存中
- System.out.println(s1==s2); // false两个对象的地址值不一样。
- System.out.println(s1.equals(s2)); // true
面试题二:
- String s1="a"+"b"+"c";
- String s2="abc";
- System.out.println(s1==s2);
- System.out.println(s1.equals(s2));
- java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。
- 面试题三:
- String s1="ab";
- String s2="abc";
- String s3=s1+"c";
- System.out.println(s3==s2); // false
- System.out.println(s3.equals(s2)); // true
先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false。
java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。