Java中字符串比较的一道面试题
2016-03-12 13:48
549 查看
题目:
输出结果:
解析:直接把上面代码进行反编译一下就知道其中的原理了。
从上面可以看到字符的的加操作其实是创建了一个StringBuilder对象,第一个字符串作为初始化参数传入StringBuilder对象,第二个参数使用StringBuilder的append操作添加到StringBuilder,这样就完成了加操作,所以新得到的对象是创建出来的一个新的StringBuilder对象,它存放在堆中,所以从上面看到c和e是不同的原因就是它们是新创建出来的两个不同的对象。a跟b相同的原因就是因为字面量字符串”hello”存放在常量区,它们两个都指向的是同一个字符串。
上面可以进行如下理解:
补充:
类的final变量和普通变量有什么区别?
结果:
这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的值。而对于变量d的访问却需要在运行时通过链接来进行。
下面反编译一下看一下就知道确实编译器做了手脚。
不过要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,比如下面的这段代码就不会进行优化:
这段代码的输出结果为false。
public class Test { public static void main(String[] args) { String a = "hello"; String b = "hello"; String c = a + b; String d = a + "hello"; String e = a + b; System.out.println(a == b); System.out.println(a == c); System.out.println(c == d); System.out.println(c == e); } }
输出结果:
true false false false
解析:直接把上面代码进行反编译一下就知道其中的原理了。
从上面可以看到字符的的加操作其实是创建了一个StringBuilder对象,第一个字符串作为初始化参数传入StringBuilder对象,第二个参数使用StringBuilder的append操作添加到StringBuilder,这样就完成了加操作,所以新得到的对象是创建出来的一个新的StringBuilder对象,它存放在堆中,所以从上面看到c和e是不同的原因就是它们是新创建出来的两个不同的对象。a跟b相同的原因就是因为字面量字符串”hello”存放在常量区,它们两个都指向的是同一个字符串。
上面可以进行如下理解:
String a = "hello"; String b = "hello"; String tmp = String.valueOf(a); StringBuilder sb = new StringBuilder(tmp); sb.append(b); String c = sb.toString(); String tmp = String.valueOf(a); StringBuilder sb = new StringBuilder(tmp); sb.append("hello"); String d = sb.toString(); String tmp = String.valueOf(a); StringBuilder sb = new StringBuilder(tmp); sb.append(b); String e = sb.toString();
补充:
类的final变量和普通变量有什么区别?
public class Test { public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e)); } }
结果:
true false
这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的值。而对于变量d的访问却需要在运行时通过链接来进行。
下面反编译一下看一下就知道确实编译器做了手脚。
不过要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,比如下面的这段代码就不会进行优化:
public class Test { public static void main(String[] args) { String a = "hello2"; final String b = getHello(); String c = b + 2; System.out.println((a == c)); } public static String getHello() { return "hello"; } }
这段代码的输出结果为false。
相关文章推荐
- 软件测试面试可能会遇到的一些问题
- 面试题3 ----二维数组中的查找
- 送给前线码农的话 - 大牛们的经典语录
- 字符串逆序等面试题
- 面试经历
- 多线程面试
- 架构师面试总结
- 记腾讯web前端工程师内推电话面试(first round)(2016年实习生招聘)
- 2016年百度校招小结:我做技术面试官的一些思考
- 操作系统常见面试题总结
- 一个程序员用在写程序上的时间大概占他的工作时间的10-20%
- java中的面试问题
- 毁灭程序员的15个障碍,你千万别踩!
- 为什么程序员都有点怪?
- 程序员的天花板年龄是多少?
- 一道有趣的推理题
- Js面试题
- 走近腾讯 走进腾讯(一个关于面试准备的记录)
- 笔试题总结-第一次面试
- 多线程面试题