关于Java中的可变与不可变类

所谓不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。在JDK的基本类库中,所有基本类型的包装类,如Integer和Long类,都是不可变类,java.lang.String也是不可变类,虽然他不是基本类型

如:String var = "abcd";Long i = 0L;
我们知道,当声明一个变量的时候,变量名实际上是该对象的指针;而我们在函数中传递该变量的时候实际上也是传递的指针.但基本类型传递的是他的实际值;

查看JAVA中的别名效应:
TestClass a = new TestClass();a.num = 10;
声明TestClass类的实例;并给它的一个属性赋值;
public void doit(TestClass parm){
    TestClass b = parm;
    b.num = 11;
}
此时,a.num 的值是 11.
为什么?因为我们将 a--指向TestClass类的一个实例的指针,传递给doit();然后在方法中我们声明另一个实例,然后将指针指向了 a .实际上a,b现在都指向了同一个内存区.当修改 b 的属性时,a也受了影响.这就是别名效应

但如果传递的是基本类型,就不会出现。因为基本类型是不可变类;当声明新类,或对类的值做出修改的时候它都会创建一个新的类,然后再进行赋值;如:
String var = "abc";
var = "bcd";
这个过程中实际上创建了两个String 对象;同样,这种现象也发生在Long,Integer等上。

因为String也是不可变类,所以就引出了一个问题:在需要拼接字符串时,我们有时候会通过大量的:
str += "";语句来实现。其实这样是非常影响效率的。因为每一个 += 语句都会创建一个新的对象,并且意味着要清空以前的对象。这时候有另外一个类:StringBuffer 解决了这一问题。对StringBuffer的操作都是在一个对象上的,不会创建新的。

在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”; 
StringBuffer sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 
String S1 = “This is only a” + “ simple” + “test”; 
其实就是: String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是, 如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: 
String S2 = “This is only a”; 
String S3 = “ simple”; 
String S4 = “ test”; 
String S1 = S2 +S3 + S4; 
这时候 JVM 会规规矩矩的按照原来的方式去做 在大部分情况下 StringBuffer > Strin
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值