Java的clone机制及其可变类与不可变类

当方法中传递的参数是基本数据类型时,采用的是值传递;当输入参数是对象时,采用的是引用传递。这是“影子克隆(shallow clone)”。如果想要按值传递参数,该类就要实现cloneable接口,并实现clone方法,将“对象名.clone()”做参数传递(deep clone)。

     Object 类有 clone() 方法: protected native Object clone() throws CloneNotSupportedException;

     该方法是 protected 的,显然是留待被子类 override 的。该方法又是 native 的,必然做了与具体平台相关的底层工作。

     事实上,类 Object 的 clone() 方法首先会检查 this.getClass() 是否实现了 Cloneable 接口。 Cloneable 只是一个标志接口而已,用来标志该类是否有克隆功能。

public interface Cloneable {

}

     如果 this.getClass() 没有实现 Cloneable 接口, clone() 就会抛 CloneNotSupportedException 返回。否则就会创建一个类型为 this.getClass() 的对象 other ,并将   this 各 field 的值赋值给 other 的对应 field ,若是基本数据类型及非可变类类型的field则是按值,若可变类类型则按引用赋值,然后返回 other 。

 

所谓不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。 它包括:

primitive变量: boolean,byte, char, double ,float, integer, long, short

jdk的不可变类:jdk的java.lang包中 Boolean, Byte, Character, Double, Float, Integer, Long, Short, String

可变类,是当你获得这个类的一个实例引用时,你可以改变这个实例的内容。 可变类对象间用“=”赋值,则会是使两个对象实际上会引用同一个实例。所以,只有实现深度clone才能使可变类对象的修改不影响原始对象的值。然而,对于不可变类,可变类的特性也是很有意义的,有的时候我们不希望重复创建相同的内容的实例。因此,我们也可以利用不可变类获得实例缓存。如:

 

Integer a=Integer.valueOf(10);

Integer b= Integer.valueOf(10);

则只会在第一次创建取值为10的Integer对象。也就是说a和b指向同一处内存上的内容。

 

 

推荐文章:http://www.javaeye.com/topic/483469

 

 

另外 ,对于String不可变类的理解:

 

不可改变的字符串具有一个很大的优点:编译器可以把字符串设置为共享。
不可变类String有一个重要的优点-它们不会被共享引用。


是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 
定义一个string类型的变量有两种方式: 
string  name=  "tom  "; 
string  name  =new  string(  "tom  ") 
使用第一种方式的时候,就使用了串池, 
使用第二中方式的时候,就是一种普通的声明对象的方式 
如果你使用了第一种方式,那么当你在声明一个内容也是  "tom  "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string  saname=  "tom  ",将会指向同一块内存 

另外关于string类型是不可改变的问题: 
string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name=  "madding  " 
那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个  "tom  "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。 

你可能感兴趣的:(java,String,object,Integer,character,Primitive)