String类陷阱深度剖析 -字符串池-栈-堆-equal--tostring--hashcod

String类陷阱深度剖析 -字符串池-栈-堆-equal--tostring--hashcode-编码utf-16--赋值过程--==比较。

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

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版本不一致。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值