String类陷阱深度剖析 -字符串池-栈-堆-equal--tostring--hashcod
2014-04-19 22:48
337 查看
String类陷阱深度剖析 -字符串池-栈-堆-equal--tostring--hashcode-编码utf-16--赋值过程--==比较。
1.与object类的区
2.赋值创建对象的过程
3.string最好是这样赋值:
String str ="aaa"; ==yes
String str =new String("aaa");==not ,因为多创建了对象,GC次数增多。
String str3 = "bbb";
String str4 = "bbb";
System.out.println(str3 == str4);
结果为true。为什么呢?这里涉及到字符串池String Pool的概念(String pool是在栈中),首先String
str3 = "bbb";先检测字符串池中是否有bbb对象,如果没有,则将字符串对象bbb放入字符串池中去(也就是在字符创池中创建bbb这个字符串对象,并且将创建好的字符串对象bbb的地址返回给str3),这时引用str3指向这个字符串池中的bbb对象。再String str4 = "bbb";检测字符串池中是否有bbb对象,这时已经有了,所以就不会再将新的bbb对象放入字符串池中去了,这时将字符串池中已有的字符串对象地址返回给str4,这时str4引用还是指向原来的字符串池中已有的字符串对象地址,也就是说String
str4 = "bbb";不会再创建一个对象,所以str3和str4指向同一个对象,所以返回true
String Pool(字符串池),Java中需要维护字符串池的是因为在实际开发中经常会遇到String,所以不用每次都在heap中去生成一个对象,而且这个对象用完一般都是丢掉的,所以需要维护字符串池,而且一般字符串写法用这种形式:String
str = "aaa"。
2.》》
String str1 = "abc";
int
a = 100;
boolean
b = true;
System.out.println(str1+a+b);//输出的结果为abc100true
=============== hashcode =====================
Object.hashCode() 就是32位jvm内存地址。
这里会调用Object的toString()方法,结果就是
return getClass().getName() + "@" + Integer.toHexString(hashCode());
1.与object类的区
2.赋值创建对象的过程
3.string最好是这样赋值:
String str ="aaa"; ==yes
String str =new String("aaa");==not ,因为多创建了对象,GC次数增多。
1、避免隐式的String字符串 String字符串是我们管理的每一个数据结构中不可分割的一部分。它们在被分配好了之后不可以被修改。比如"+"操作就会分配一个链接两个字符串的新的字符串。更糟糕的是,这里分配了一个隐式的StringBuilder对象来链接两个String字符串。 例如: a = a + b; // a and b are Strings 编译器在背后就会生成这样的一段儿代码: StringBuilder temp = new StringBuilder(a). temp.append(b); a = temp.toString(); // 一个新的 String 对象被分配 // 第一个对象 “a” 现在可以说是垃圾了 它变得更糟糕了。 让我们来看这个例子: String result = foo() + arg; result += boo(); System.out.println(“result = “ + result); 在这个例子中,背后有三个StringBuilders 对象被分配 - 每一个都是"+"的操作所产生,和两个额外的String对象,一个持有第二次分配的result,另一个是传入到print方法的String参数,在看似非常简单的一段语句中有5个额外的对象。 试想一下在实际的代码场景中会发生什么,例如,通过xml或者文件中的文本信息生成一个web页面的过程。在嵌套循环结构,你将会发现有成百上千的对象被隐式的分配了。尽管VM有处理这些垃圾的机制,但还是有很大代价的 - 代价也许由你的用户来承担。 解决方案: 减少垃圾对象的一种方式就是善于使用StringBuilder 来建对象,下面的例子实现了与上面相同的功能,然而仅仅生成了一个StringBuilder 对象,和一个存储最终result 的String对象。 StringBuilder value = new StringBuilder(“result = “); value.append(foo()).append(arg).append(boo()); System.out.println(value); 通过留心String和StringBuilder被隐式分配的可能,可以减少分配的短期的对象的数量,尤其在有大量代码的位置。
参考链接: http://blog.csdn.net/tayanxunhua/article/details/21752781 http://blog.sina.com.cn/s/blog_74924f2401017upe.html http://blog.csdn.net/ahuier/article/details/8213854 http://www.cnblogs.com/donaldjohn/archive/2011/02/27/1966539.html
1.》》String类陷阱深度剖析
String str3 = "bbb";String str4 = "bbb";
System.out.println(str3 == str4);
结果为true。为什么呢?这里涉及到字符串池String Pool的概念(String pool是在栈中),首先String
str3 = "bbb";先检测字符串池中是否有bbb对象,如果没有,则将字符串对象bbb放入字符串池中去(也就是在字符创池中创建bbb这个字符串对象,并且将创建好的字符串对象bbb的地址返回给str3),这时引用str3指向这个字符串池中的bbb对象。再String str4 = "bbb";检测字符串池中是否有bbb对象,这时已经有了,所以就不会再将新的bbb对象放入字符串池中去了,这时将字符串池中已有的字符串对象地址返回给str4,这时str4引用还是指向原来的字符串池中已有的字符串对象地址,也就是说String
str4 = "bbb";不会再创建一个对象,所以str3和str4指向同一个对象,所以返回true
String Pool(字符串池),Java中需要维护字符串池的是因为在实际开发中经常会遇到String,所以不用每次都在heap中去生成一个对象,而且这个对象用完一般都是丢掉的,所以需要维护字符串池,而且一般字符串写法用这种形式:String
str = "aaa"。
2.》》
StringBuffer类中对toString这个方法进行了重写(原来Object类下得toString方法是打印出地址的), 所以可以调用toString方法来使StringBuffer类型的数据转变为String类型的 不论是整形还是布尔型等等等,与字符串相加,则他们被自动转换为字符串型
String str1 = "abc";
int
a = 100;
boolean
b = true;
System.out.println(str1+a+b);//输出的结果为abc100true
=============== hashcode =====================
Object.hashCode() 就是32位jvm内存地址。
这里会调用Object的toString()方法,结果就是
return getClass().getName() + "@" + Integer.toHexString(hashCode());
===========String,StringBuffer与StringBuilder的区别??=============== http://blog.csdn.net/rmn190/article/details/1492013[/code]
StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是
StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因
此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程
不安全的。
StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5
从 JDK 1.5 开始,带有字符串变量的连接操作(+),JVM 内部采用的是
StringBuilder 来实现的,而之前这个操作是采用 StringBuffer 实现的。
====================string注意事项-重点推荐=====================
默认编码是UTF-16,可以指定编码
1.String str ="123";
赋值过程:
1.查找string pool中是否存在"123"对象
2.没有就在string pool生成"123"对象,有就返回"123"对象地址
3.把string pool中的"123"对象地址赋值给str.
【字符串池对象 --->赋值】
2.String str = new String("123");
赋值过程:
1.查找string pool中是否存在"123"对象
2.没有就在string pool生成"123"对象,有就返回string pool"123"对象地址
3.在堆中new String对象,new String("123")
3.把new String("123")的堆对象地址赋值给str.
【字符串池对象 -->堆对象 --->赋值】
字符串池对象初始化完了就是final,下次使用时不用重新创建对象啦。
字符串池:可以重用字符串对象,避免频繁地重新创建。
================equal 和 == (原生数据,对象类型(特殊string))====
equal方法的作用:
看类是否重写过,一分为二来说明
1.object 是否引用指向同一个对象,内存地址相等
2.string重写过,是否内容相等
* equal方法的作用:
* 1.对象引用是否相同
* 2.string重写过的,内容是否相同
String的equal方法逻辑过程:
* 1.对象地址 this=object
* 2.字符串大小length
* 3.字符串s1中每个字符与字符串s2中每个字符是否相同
==比较
1.原生数据类型 ===> 数值比较
2.对象类型 ===> 引用地址,对象相等
================关键字 final static =====================
final 一定要初始化,有2个地方来初始化:1.声明时 2.构造方法时
static
1.不能与this合用
2.时机不同。static静态块在.class加载是运行的。实例化对象时运行构造函数
3.执行顺序:静态优先,父辈优先。先当前类的父类的静态块,当前类的静态块,先当前类的父类的构造函数,后当前类的构造函数。
4.执行次数。静态一次,实例化对象可以new多次。
================JVM之类加载器深度剖析=====================
深入详解JVM之类加载器深度剖析、根、扩展及系统类加载器.avi
http://v.youku.com/v_show/id_XMjc1NDEyMzI4.html
类验证:目的=保证安全。
1.文件结构
类声明,类属性,类方法
2.语义检查
3.字节码验证
防止自己手写的class文件
4.二进制兼容性验证
编译的JDK版本不一致。
相关文章推荐
- 简单选择排序
- 随笔
- 配置Apache与PHP的环境
- ios- 绘图
- js回调函数,匿名函数学习
- VS2010(64位) DLL 无法正常加载问题解决方案
- linux命令大全
- 【LeetCode】Binary Tree Inorder Traversal
- php用mysqli连接数据库
- site
- LA 4513 Stammering Aliens(哈希写起来比后缀数组爽多了)
- 什么是换码符(escape character)?
- C语言编程规范
- d100: 神仙?妖怪?谢谢!
- Linux项目实战之基于IP的虚拟主机
- SqlYog工具执行导入比较大sql文件报错
- HDOJ 1847 Good Luck in CET-4 Everybody! 博弈论的多种姿势
- struts相关
- Ubuntu 12下整合Apache Web Server 和Tomcat
- Linux使用dd命令测试硬盘读写速度