「java中对象的深拷贝」java深拷贝的三种实现方式
今天给各位分享java中对象的深拷贝的知识,其中也会对java深拷贝的三种实现方式进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、java 深度复制
- 2、java Map深度复制问题
- 3、java 什么是不可变对象
- 4、如何使Java中的InputStream的深层复制
- 5、java深拷贝对象与新建对象哪个更耗资源
- 6、java中的clone()方法怎么使用呢
java 深度复制
House不是单例吧?h1和h2的地址不一样第一个肯定是false.house内部怎么样这个光看这些真难看出。
java Map深度复制问题
这里的pos是基础类型,不是引用类型,不需要拿出来单独复制,浅clone就可以了,但是attr这个map需要进行深度复制,因为这个是引用类型,复制后的对象修改该属性依然会影响源对象
clone方法可以简单写为
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Elem elem = (Elem) super.clone();
MapString, String tempMap = new HashMap();
for (EntryString, String e : this.map.entrySet()) {
/**
* 这里的new String(e.getValue())可以直接用e.getValue()代替,
* 写在这里仅仅是提醒当value是其他对象时需要做下处理,比如一个User对象,如果你直接写成
* tempMap.put(e.getKey(), e.getValue());那么肯定是没什么用的,而要写成
* tempMap.put(e.getKey(), e.getValue().clone());
*/
tempMap.put(e.getKey(), new String(e.getValue()));
}
elem.map = tempMap;
return elem;
}
java 什么是不可变对象
不可变对象是指一个对象的状态在对象被创建之后就不再变化。不可变对象对于缓存是非常好的选择,因为你不需要担心它的值会被更改。
创建一个不可变类:
将类声明为final,所以它不能被继承;
将所有的成员声明为私有的,这样就不允许直接访问这些成员;
对变量不要提供setter方法;
将所有可变的成员声明为final,这样只能对它们赋值一次;
通过构造器初始化所有成员,进行深拷贝(deep copy);
在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝;
示例:
public final class Immutable {
private final int id;
private final String name;
private final HashMap map;
public int getId() {
return id;
}
public String getName() {
return name;
}
/**
* 可变对象的访问方法
*/
public HashMap getMap() {
return (HashMap) testMap.clone();
}
/**
* 实现深拷贝的构造器*/
public Immutable(int i, String n, HashMap hm){this.id=i;
this.name=n;
HashMap tempMap=new HashMap();
String key;
Iterator it = hm.keySet().iterator();
while(it.hasNext()){
key=it.next();
tempMap.put(key, hm.get(key));
}
this.map = tempMap;
}
}
不变模式有两种形式:弱不变模式和强不变模式。
弱不变模式,指类实例的状态是不可改变,但是这个类的子类的实例具有可能会变化的状态,要实现弱不变模式,一个类必须满足下面条件:
对象没有任何会修改对象状态的方法 ,这样一来当对象的构造函数将对象的状态初始化之后,对象的状态便不再改变;
属性都是私有的,以防客户端对象直接修改内部状态;
这个对象所引用的其他对象如果是可变的话,必须设法限制外界对这些可变对象的访问,以防止外界修改这些对象,尽量在不可变对象内部初始化这些被引用的对象,而不要在客户端初始化再传入到不可变对象内部来,如果某个可变对象必须在客户端初始化,然后再传入到不变对象里的话,就应当考虑在不可变对象初始化的时候,将这个可变对象进行拷贝。
弱不变模式的缺点是,一个弱不变对象的子对象可能是可变的,这个可变的子对象可能可以修改父对象的状态,从而可能允许外界修改父对象的状态。
强不变模式:一个类的实例不会改变,同时它的子类的实例也具有不可变化的状态。一个类必须首先满足弱不变模式所要求的所有条件,并且还有满足下面条件之一:
类所有的方法都应当是final,这样这个类的子类不能够重写此类的方法;
此类本身就是final的,那么这个类就不可能会有子类,从而也就不可能有被子类修改的问题;
不变和只读的区别:当一个变量是只读时,变量的值不能直接改变,但是可以在其他变量发生改变的时候改变;比如生日是不变属性,而年龄是只读的,年龄会随着时间发生变化,生日则不会变化。(用final声明的变量是只读的)
不可变对象的好处:
不可变对象更容易构造,测试与使用;
真正不可变对象都是线程安全的;
不可变对象的使用没有副作用(没有保护性拷贝);
对象变化的问题得到了避免;
不可变对象的失败都是原子性的;
不可变对象更容易缓存,且可以避免null引用;
不可变对象可以避免时间上的耦合;
String,StringBuffer,StringBuilder,都是final类,不允许被继承,在本质上都是字符数组,不同的是,String的长度是不可变的而后两者长度可变,在进行连接操作时,String每次返回一个新的String实例,而StringBuffer和StringBuilder的append方法直接返回this,所以当进行大量的字符串连接操作时,不推荐使用String,因为它会产生大量的中间String对象。
StringBuffer和StringBuilder的一个区别是,StringBuffer在append方法前增加了一个synchronized修饰符,以起到同步的作用,为此也降低了执行效率;若要在toString方法中使用循环,使用StringBuilder。
如何使Java中的InputStream的深层复制
InputStream的是抽象的,不公开(没有尽自己的孩子)的内部数据对象。所以唯一的办法,以“深拷贝”InputStream的是创造ByteArrayOutputStream后执行Read()上的InputStream,写(),该数据ByteArrayOutputStream。然后做: 方通=新ByteArrayInputStream的(byteArrayOutputStream.toArray());
如果您使用的是标记()您的InputStream那么你的确不能扭转这一点。这使你流“消费”。
要“重用”你的InputStream避免使用标记(),然后在阅读呼叫复位结束()。您会然后读取来自流的开头。
编辑:
顺便说一句,IOUtils使用这个简单的code片段复制的InputStream:
公共静态INT副本(输入的InputStream,OutputStream的输出)抛出IOException异常{
byte []的缓冲区=新的字节[DEFAULT_BUFFER_SIZE]
诠释计数= 0;
INT N = 0;
而(-1!=(N = input.read(缓冲液))){
output.write(缓冲液,0,n)的;
数+ = N;
}
返回计数;
}
java深拷贝对象与新建对象哪个更耗资源
这个问题没有可比性:
首先浅克隆比new性能高
而深克隆包括克隆对象本身以及对象内部的所有成员, 以及成员的成员等,
如果这个对象有一个集合字段, 这个字段里有100w个对象, 那么深克隆要克隆100w+1个对象, 而你所说的新建对象, 如果是new一个对象, 然后set这个100w的集合, 那么肯定性能更好, 而你如果是new一个对象, 然后new一个集合, 然后把集合里的100w个对象每个都重新new, 并添加到集合中, 然后赋值到新的对象上, 那么还是克隆的性能好
java中的clone()方法怎么使用呢
浅拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一个新的和原是对象中对应字段相同(内容相同)的字段,也就是说这个引用和原是对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对象中对应字段的内容.
你的疑问应该是浅拷贝与深拷贝的不同造成的。
toString重写应该算是一种良好习惯,写一般的常用类最好重写。这里的toString没什么特别的意思,没有也无所谓。
关于java中对象的深拷贝和java深拷贝的三种实现方式的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。