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的clone机制及其可变类与不可变类

相关文章:

你感兴趣的文章:

标签云: