当前位置:首页 » 编程语言 » java深克隆

java深克隆

发布时间: 2022-12-21 13:39:18

java中的克隆技术具体有什么应用

Clone基本知识储备
在Java里提到clone技术,就不能不提java.lang.Cloneable接口和含有clone方法的Object类。所有具有clone功能的类都有一个特性,那就是它直接或间接地实现了Cloneable接口。否则,我们在尝试调用clone()方法时,将会触发CloneNotSupportedException异常。 下面我们通过对Object类的部分源码的分析,来发现和理解这一特性。
l clone的实现

1.实现Cloneable接口

通过上一篇的介绍,我们知道,一个类若要具备clone功能,就必须实现Cloneable接口。做到这一步,clone功能已经基本实现了。Clone功能对我们来说,最主要的还是要能够使用它。那么我们如何才能使用clone功能呢?答案是覆盖Object#clone()方法。

2. 覆盖Object#clone()方法

为什么需要覆盖Object#clone()方法?这里得再次从jdk源码说起。JDK中Object# clone()方法的原型是:

protected native Object clone() throws CloneNotSupportedException;

是否注意到,这里clone()方法修饰符是protected,而不是public。这种访问的不可见性使得我们对Object#clone()方法不可见。相信读者已明白为什么要覆盖Object#clone()方法。而且,覆盖的方法的修饰符必须是public,如果还保留为protected,覆盖将变得没有实际意义。下面举一个具有clone功能的简单的例子:

/*

* 具有clone功能的类的例子

*/

public class CloneableObjExample implements Cloneable {

//……部分代码已省略……

private String name = null;

private int score = 0;

/**

* NOTE: 将protected 修饰符 更改为 public

* @see java.lang.Object#clone()

*/

public/*protected*/ Object clone() throws CloneNotSupportedException {

// call父类的clone方法

Object result = super.clone();

//TODO: 定制clone数据

return result;

}

}

3.定制clone

至此,clone已经真相大白。Clone的对象我们可以对其进行定制。还就上面的例子来说。下面的方法对功能做了一定的增强:

public/*protected*/ Object clone() throws CloneNotSupportedException {

// call父类的clone方法

CloneableObjExample result = (CloneableObjExample)super.clone();

//TODO: 定制clone数据

//虽然”clone”了,但还可以做点调整

result.name = “New Name”;

result.score = 90;

return result;

}

本篇介绍了如何实现clone。接下来的篇幅将就纵深clone等clone的高级特性进行分析。

本章将进入clone的高级特性,着重讲述纵深clone技术。

Clone通常有两种类型即浅clone和深clone。首先,分析一下两种的不同。浅clone和深clone都是clone,它们本质区别是对象内部的成员属性(非原生类型属性,如int等)在clone时是否处理为引用。如果仍然保留为引用,则称为浅clone,反之称为深clone。其实这两个概念也是相对的概念。在处理上它们有点区别,浅clone方式得到clone对象即可,深clone方式在得到clone对象后,还需要对引用的成员属性进行“clone”处理。从这个层次上说,深clone并没有什么特别地困难,简单讲就是创建好对象,再设置一些成员属性。关于深clone,网上的文章已经有太多,有点目不暇接的感觉,本文不再赘述,这也不是本文的重点。

本文的重点是要阐述纵深clone,亦即“N深clone”。深到什么程度为止?本文描述的目标是一直深到你想要的程度,包括深到不能再深的程度。

㈡ java怎么样构造函数复制一个对象

一、用Object 本身的复制对象的方法, clone()。对象可克隆的类必须实现Cloneable接口,并且clone方法是浅克隆。
二、类实现Serializable,用ObjectOutputStream、ObjectInputStream 来复制对象。

对象克隆有点复杂,尤其是第一种。
关于这个问题你可以搜索:
JAVA深复制(深克隆)与浅复制(浅克隆)
这篇文章看看。

㈢ java中深克隆与浅克隆的区别

深克隆与浅克隆

大家知道,对象是互相引用的,即对象中可能包含了另一个对象的引用,举例如:有一个Order对象,Order对象中又包含了LineItems对象,然后LineItems对象又包含了Item对象。

好了,现在我有一个Order对象order1,它包含了一个LineItems对象items,这表示的是有一个订单order1,订单的内容是items。

好的,现在有另一个客户想要一份订单,内容跟order1完全一样,那么在系统的逻辑层我们怎么做呢?很简单,order2=order1.clone(). 我们知道clone方法是在内存中生成一个新的对象,而不是只得到原对象的引用。这时候,有人说话了:“哦,明白了我们对order2的成员变量进行修改,是不会影响order1的。” 很可惜,这句话只对了一半。

假设order类有一个成员变量name,当然改变order2.name不会影响order1.name,因为他们在不同的内存区域。但是如果改变 order1.items呢?很遗憾,简单地使用order1.clone,是会影响到order2.items的。原因很简单,就是因为clone方法默认的是浅克隆,即不会克隆对象引用的对象,而只是简单地复制这个引用。所以在上例中,items对象在内存中只有一个,order1和order2都指向它,任何一个对象对它的修改都会影响另一个对象。

那相对浅克隆,深克隆自然就是会克隆对象引用的对象了。也就是说,在上例中,改变order1.items并不会影响order2.items了。因为内存中有两个一样的items。

如果实现深克隆?

一个方法自然是重写clone方法,添加如order.items=(LineItems)items.clone()的语句,也就是人为地添加对引用对象的复制。这个方法的缺点是如果引用对象有很多,或者说引用套引用很多重,那么太麻烦了。业界常用的方法是使用串行化然后反串行化的方法来实现深克隆。由于串行化后,对象写到流中,所有引用的对象都包含进来了,所以反串行化后,对等于生成了一个完全克隆的对象。绝!

这个方法的要求是对象(包括被引用对象)必须事先了Serializable接口,否则就要用transient关键字将其排除在复制过程中。

㈣ java.util.ArrayList.clone是不是彻底的克隆

你好,官方api 说明如下:

Returns a shallow of this ArrayList instance. (The elements themselves are not copied.)
arraylist.clone是浅拷贝,浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

㈤ java中的浅克隆和深克隆是什么

浅克隆:仅仅复制所克隆的对象,而不复制它所引用的对象。

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。


深克隆:把要复制的对象所引用的对象都复制了一遍。

那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。


很明显二者时间消耗有差距,在不影响的情况下尽量用浅克隆

注意区分与C语言的浅克隆深克隆 那个是引用地址与重新分配地址构建的区别,详细可以参见:

http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html

㈥ java深拷贝对象与新建对象哪个更耗资源

这个问题没有可比性:
首先浅克隆比new性能高
而深克隆包括克隆对象本身以及对象内部的所有成员, 以及成员的成员等,
如果这个对象有一个集合字段, 这个字段里有100w个对象, 那么深克隆要克隆100w+1个对象, 而你所说的新建对象, 如果是new一个对象, 然后set这个100w的集合, 那么肯定性能更好, 而你如果是new一个对象, 然后new一个集合, 然后把集合里的100w个对象每个都重新new, 并添加到集合中, 然后赋值到新的对象上, 那么还是克隆的性能好

㈦ java如何实现将一个记事本文件内容复制到另一个文件

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyMove {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CopyMove cm = new CopyMove();
cm.("h:\\1.txt", "c:\\2.txt");
cm.move("h:\\3.txt", "h:\\r\\e\\4.txt");
}
//文件复制前必须得到当前文件夹名字且要有\
//当复制深层次路径时要用mkdirs方法
public void (String path1,String path2){
try {
FileInputStream fis = new FileInputStream(path1);
int l = fis.available();
byte[] c = new byte[l];
fis.read(c);
fis.close();
int i = path2.lastIndexOf("\\")+1;
System.out.println(i);
String path = path2.substring(0, i);
System.out.println(path);
File f = new File(path);
f.mkdirs();
// System.out.println(f.getAbsolutePath());
// System.out.println(f.isDirectory());
FileOutputStream fos = new FileOutputStream(path2);
fos.write(c);
fos.close();
System.out.println("文件复制成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("文件复制失败");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void move(String path1,String path2){
try {
FileInputStream fis = new FileInputStream(path1);
int l = fis.available();
byte[] c = new byte[l];
fis.read(c);
fis.close();
int i = path2.lastIndexOf("\\");
//System.out.println(i);
String path = path2.substring(0, i);
System.out.println(path);
File f = new File(path);
f.mkdirs();
// System.out.println(f.getAbsolutePath());
// System.out.println(f.isDirectory());
FileOutputStream fos = new FileOutputStream(path2);
fos.write(c);
fos.close();
System.out.println("文件移动成功");
File f2 = new File(path1);
f2.delete();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("文件移动失败");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

㈧ 谁能给出一个java中深拷贝 的例子 啊,我不知道是啥东西,最好能解释下深拷贝含义.

举个最简单的例子:
class A {
public int i;
public int j;
}

A a = new A();

浅拷贝:
A a1 = a;

深拷贝:
A a1 = new A();
a1.i = a.i;
a1.j = a.j;

感觉如下:
浅拷贝只拷贝对象本身
深拷贝则拷贝对象中引用的对象,一直拷贝下去。

㈨ java如何深度一个object

方法一:把对象序列化之后再反序列化,之后得到的对象就是深度克隆的对象;
方法二:自己重写方法,不过有点麻烦。

㈩ java里clone方法的问题

首先必须实现接口,
public interface Cloneable此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。

如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。

按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的)。请参阅 Object.clone(),以获得有关重写此方法的详细信息。
==》protected Object clone() throws CloneNotSupportedException

注意,此接口不 包含 clone 方法。因此,因为某个对象实现了此接口就克隆它是不可能的。即使 clone 方法是反射性调用的,也无法保证它将获得成功。

public class Box implements Cloneable{

public Date d = new Date();

@Override
public Box clone() throws CloneNotSupportedException
{
Box cloned = (Box)super.clone();

cloned.d = (Date)d.clone();

return (Box)super.clone();
}
public static void main(String[] args) throws Exception {
Box b = new Box();
Box b2 = (Box)b.clone();

System.out.println(b.d == b2.d);
}
}

测试后直接返回的话结果是地址相等。
你在克隆后用了set方法重新操作了,肯定是不一样的。。。。!!!
3,注释起来后结果是改变了的,你会不会是没编译保存。
你们老师是说的对的

你好,当然知道 你说的那样。我正是因为三个的试过了,所以最后没改回去,那不正是你第二个问题嘛。。。
如果是深克隆就是FALSE 不是深克隆就返回TRUE啊。

热点内容
c语言跳出死循环 发布:2025-05-15 20:06:04 浏览:823
a19处理器相当于安卓哪个水平 发布:2025-05-15 20:05:29 浏览:638
荣耀9i安卓强行关机按哪个键 发布:2025-05-15 20:00:32 浏览:750
密码锁写什么最好 发布:2025-05-15 19:05:31 浏览:782
5的源码是 发布:2025-05-15 19:04:07 浏览:719
c语言创建的源文件 发布:2025-05-15 18:54:08 浏览:611
3个数字密码锁有多少种 发布:2025-05-15 18:49:48 浏览:684
压缩包手机打开 发布:2025-05-15 18:37:34 浏览:217
安卓取消耳机模式怎么取消 发布:2025-05-15 18:24:24 浏览:59
气球怎么解压视频 发布:2025-05-15 18:20:00 浏览:783