导读:这两天没有做项目,然后就想着把之前在项目中用到过的东西总结总结。记得之前做今日开讲项目时,在比较学生学号的时候,我最开始用的是“==”,但是,实践证明,这个玩意儿吧,总是很奇怪,有时候对有时候不对。后来就换成了equals,结果就好多了。那时候我就在想,这两个有什么区别,string类型到底是怎么回事?现在总结总结,也祭奠一下当年面试笔试题的那些亡魂!

一、实例分析

首先,看看代码段:

public class stringTest {

	private static String getA()
{
return "a";
} public static void testString()
{
String a="a";
final String c="a"; String b=a+"b";
String d=c+"b";
String e=getA()+"b"; String compare="ab"; System.out.print(b==compare);
System.out.print(d==compare);
System.out.print(e==compare);
}
}

我先说一下,我最开始得出的答案:true,true,true。原因如下:

1,因为a变量代表了一个常量定值“a”,然后b在编译的时候就会得到b="ab",所以结果是true;

2,因为C变量用了final关键字修饰,代表这个变量不会被更改,那么d 就会是一个固定的值“ab”,而==比较的是地址值,所以true;

3,因为getA()方法是静态方法嘛,这个我觉得跟 2 的原因差不多,所以就是true。

对于我的答案,我只能借用我宇哥的一句台词,拿出你的红笔。。。。。。(画个大大的 × )

运行结果输出:

对此,我竟无言以对!

解析:

1,false:compare是个常量,而b不是。b=a+"b",a不是一个常量,尽管a作为一个局部变量,指向一个常量。但是,它的引用上并未进行“强制约束”是不可被改变的。它只会在这段代码中不会改变,但是在运行的时候,则不一定。在“字节码增强”技术(话说,这个好像是java 8的东西)面前,代码被切入,就可能会发生改变。所以,编译器时不会将b在编译的时候,优化为“ab”的。在运行时,会被编译为:

StringBuilder temp=new StringBuilder();
temp.append(a).append("b");
String b=temp.toString();

2,true,我解释正确!请看上面。因为final进行修饰为不可改变,所以代码在编译时被优化为"ab",结果true

3,false:这个e值的内容来源于一个方法和一个常量的叠加。虽然方法内部返回了一个常量的引用,但是,编译器不会去看方法内部做了什么,如果编译器非要知道方法内部返回什么,那么则需要采用递归。一旦采用递归,深度就不可控,同时也并不是递归后就一定能够确保返回一个指定的常量。(即使是常量,这也是通过对引用拷贝返回,这个引用还可能发生变化)所以,编译器不会做出优化,结果false!

备注:编译器优化一定是在编译阶段能确定优化后,不会影响整体功能,类似于final引用,这个引用只能被赋值一次,但是它无法确定赋值的内容是什么,只有在编译阶段能确定这个final引用赋值的内容,编译器才有可能进行编译时优化。而在编译阶段能确定的内容,只能来自于常量池,例如int、long、string等常量。(顿时想到了当年学习C++时的编译时多态和运行时多态)

看了上面的分析,再来一个代码段:

	public static void main(String[] agrs)
{
String a="a";
String b=a+"b";
String c="ab";
String d=new String(b); System.out.println(b==c);
System.out.println(c==d);
System.out.println(c==d.intern());
System.out.println(b.intern()==d.intern());
}

经过上一个代码段,这个我全对了,但是,只有前面两个是自己经过分析,后面两个一半分析,一半感觉(之前总结JVM溢出时,有查过这个intern()的方法)

intern():JVM会在这个常量池中通过equals方法查找是否存在等值的String,如果存在,则直接返回常量池中这个String对象的地址,如果没有找到,则会创建等值的字符串,然后再返回这个新创建空间的地址。只要是同样的字符串,当电泳intern()方法时,都会得到常量池中对应的String引用,所以,两个字符串通过intern()操作后用等号是可以匹配的。

二、代码总结

对于每一个代码段,我都自己分析了一下。其实我会得出错误的结果,一方面是由于对string类本身的不理解,另外也有对于java内存分配运行机制不了解,还有一个也是对于“==”和equals的不理解。因为有些答案,如果换成equals就对了。从这也反映出,自己对于基础功底的忽略和总结,接下来要继续努力学习啦。之前做的项目没有好好总结,感觉自己都废了!

练武不练功,到老一场空!

最新文章

  1. 主机ping不同虚拟机
  2. Shell脚本基础
  3. Python简单爬虫入门二
  4. python 数据库 blob类型 转字符串
  5. android studio问题rendering problems no render target selected
  6. mysql 进程状态(转)
  7. Centos 7配置ntp时间同步
  8. nginx比较apache
  9. HDU 1011 树形背包(DP) Starship Troopers
  10. 玩转iOS开发 - 数据缓存
  11. jacascript 函数声明、函数表达式与声明提升(hoisting机制)
  12. Android官方技术文档翻译——新构建系统概述
  13. php curl数据传输神器
  14. 好用的 Chrome 插件,提升你的学习工作效率
  15. go build -ldflags
  16. 1.安装Python3和PyCharm
  17. ASP.NET MVC提交一个较复杂对象至WCF Service
  18. 初识C++继承
  19. php基础知识考察点:自定义函数及内部函数考察点
  20. JVM快速入门

热门文章

  1. JavaScript中的this陷阱
  2. 前端常用的jquery代码
  3. 除虫记——有关WindowsAPI文件查找函数的一次压力测试
  4. 浅析linux下软件的安装
  5. 系统妈Win10系统64位和32位快速专业版
  6. Windows64+Python27下配置matplotlib
  7. 悦读FM客户端应用源码
  8. 如何删除github上项目的文件
  9. 远程文件拷贝(fastcopy为例)
  10. 基于Python的Web应用开发实战——2 程序的基本结构