Java中克隆机制

首先了解一下什么叫做拷贝?

Employ e1 = new Employ();

Employ e2 = e1;

这就是拷贝,原始变量与拷贝变量指向相同的引用对象,如果改变其中一个对象的状态,其他的对象变量的对象状态也会随之改变。

什么叫做克隆?

Employ e1 = new Employ();

Employ e2 = e1.clone();

克隆之后的变量,各自指向自己的对象,这个对象状态初始是相同的,只不过在改变其中一个对象的状态的时候,另一个对象状态不会再发生改变。

clone()方法在Object中是这样定义的:

 protected native Object clone() throws CloneNotSupportedException;

他是受保护类型的,那为什么他是受保护的类型呢?

由于对具体的实现类一无所知,所以只能将全部域进行拷贝,如果变量本身是基础类型没关系,但是如果如果对象中包含其他的子对象引用,这样克隆之后的对象与原变量共享子类,同样改变一个子对象状态,另一个也发生改变(如果子对象是不可改变的,这样也没有关系,比如:String类型),所以只能Employ本身进行克隆,这就是克隆的浅拷贝。一般我们需要重写clone()方法进行深拷贝。

1、实现Cloneable接口

2、使用public修饰clone方法,对clone进行重新定义

Cloneable接口并没有clone()方法,这个方法是从Object类中继承过来的,这里接口只是作为一个标记,表明设计者要进行克隆处理(如果没有实现接口就进行克隆,会抛出一个已检验异常)。使用标记接口的唯一目的,就是通过instanceof进行类型检查。

实现默认的浅拷贝:

class Employ implements Cloneable{

	public Employ clone(){
		return super.clone();
	}

如果要进行深拷贝,需要将所有可变的实例域进行克隆,假如Employ中有一birthDay(他是Date类型的,是一个对象引用):

	public Employ clone() throws CloneNotSupportedException{
		Employ cloned = (Employ) super.clone();
		cloned = (Date)birthDay.clone();
		return cloned;
	}

需要确保子类对象也实现了Cloneable接口,否则会抛出CloneNotSupportedException。

需要谨慎使用Clone。因为如果你这样实现了Clone方法,任何人都可以通过clone方法,实现子类的Clone,如果子类中的域变量是可变的,或者是一些没有实现Cloneable接口的,就会出现问题。所以Object将clone()方法定义为protected类型(不是子类也可以实现父类protected类型的方法吗?不理解)。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 11:11:20

Java中克隆机制的相关文章

Java中反射机制(Reflection)研究及源码演示

如下内容内容是关于 Java中反射机制(Reflection)研究及演示的内容. package com.jiangqq.reflection; import java.lang.reflect.Method; public class Reflection1 { public static void main(String[] args) throws Exception { Class<?> tClass = Class.forName("java.lang.Class"

Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别(转)

一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:  其中 i.加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构.即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!.

Java 中反射机制的深入研究

昨天学习了java的反射机制,今天继续深入学习一下. 一.通过反射操作数组 反射不光只能用在类中,也可用在任意的引用数据类型上.当然包括数组. 通过java.lang.reflect.Array 类 可操作数组,java.lang.reflect.Array 类 下面提供了很多方法. 例如 public static Object get(Object array,int index)throws IllegalArgumentException,ArrayIndexOutOfBoundsExc

Java中反射机制详解

序言 在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射,所以回过头来把这个给重新补一下,自己欠下的债,迟早是要还的. ---WH 一.什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的

关于java中异常机制

什么是异常:异常就是程序在运行时出现的不正常情况.对于严重的情况Java通过Error类进行描述,一般不用编写代码处理:对于不严重的情况Java通过Exception描述,一般编写针对性代码对其进行处理. 异常由来:问题也是生活中一个具体的事物,也可以通过Java类的形式进行描述(比如进行运算时被除数不可以为0否则出现ArithmeticException异常,数组越界会出现ArrayIndexOutOfBoundsException等等),并封装成对象.即Java对不正常情况进行描述后的对象体

Java中JIN机制及System.loadLibrary() 的执行过程

Android平台Native开发与JNI机制详解 http://mysuperbaby.iteye.com/blog/915425 个人认为下面这篇转载的文章写的很清晰很不错. 注意Android平台上的JNI机制使用包括Java代码中调用Native模块以及Native代码中调用Java模块. http://www.ophonesdn.com/article/show/263(misybing:很遗憾该站已经挂掉) 众所周知,OPhone平台上的应用开发主要基于Java语言,但平台完全支持且

java中锁机制

一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线程)就只能等了(线程阻塞在锁池等待队列中). 取到锁后,他就开始执行同步代码(被synchronized修饰的代码):线程执行完同步代码后马上就把锁还给同步对象,其他在锁池中等待的某个线程就可以拿到锁执行同步代码了.这样就保证了同步代码在统一时刻只有一个线程在执行.   众所周知,在Java多线程编

java中反射机制原理讲解

 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下看. 二,反射机制的

八、java中异常机制

一.为什么要有异常处理机制? java中的异常处理机制简单的讲就是try..catch..finally的使用. 程序难免会出现错误, 如果没有异常处理机制, 那么程序员在编写代码的时候就必须检查特定的结果, 并在程序的很多地方去处理它. 有了异常处理机制后,就不必在每个方法调用处都检查, 只需要用try包裹住可能发生异常的代码段, 这样做的好处是: 1.降低了代码的复杂度,正如上面所说的,不需要每个方法调用处都去检查: 2.将“描述正常情况下应该做什么事情”和“如果出了错怎么办” 的逻辑分开: