java中对象的复制与相等判断
来源:互联网 发布:打电话自动录音软件 编辑:程序博客网 时间:2024/05/21 22:31
一、基本概念
1.基本数据类型,采用的是值传递
2.对象类型采用引用传递,即如果修改复制对象,源对象也会发生改变
二、实现深复制的方法:(连同基本数据类型和对象的引用以及被引用的对象本身都复制一遍。所以深复制后的对象和原对象是两个完全不同的对象,只不过其返回的类型是一样的。)
1.java对象实现cloneable接口
1.1 java对象默认继承java.long.Object类,里面包含clone方法。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。
1.2重写clone方法
1.3方法内调用super.clone方法
比如:
public class EntityDO implements Cloneable{String name;String phone;String address;public EntityDO(String name, String phone, String address) {super();this.name = name;this.phone = phone;this.address = address;}public Object clone() {Object o = null;try {o = (EntityDO) super.clone();// Object中的clone()识别出你要复制的是哪一个对象。} catch (CloneNotSupportedException e) {System.out.println(e.toString());}return o;}public static void main(String args[]) {EntityDO do1 = new EntityDO("1","1","1");EntityDO do2 = do1;do2.setName("11");EntityDO do3 = (EntityDO) do1.clone();do3.setName("22");if (do1 == do2) {System.out.println("true");} else {System.out.println("false");}System.out.println(do1.getName());if (do1 == do3) {System.out.println("true");} else {System.out.println("false");}System.out.println(do1.getName());}}输出结果为:true 11 false 11
解释下java对象使用==进行比较的返回值。对于基本类型比较的是值,对于对象来说比较的是地址。在写一个类的时候,一般重写对象的equals()方法,Object类的equals方法默认是使用==来进行比较的。
注意1:Cloneable接口是不包含任何方法的!其实这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object的clone()方法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出CloneNotSupportedException异常。
注意2:如果对象里还包含着其他对象,那被包含的对象应该也按要求来的。且在对象的clone()方法内,对被包含对象进行clone,不然该包含的对象进行的是浅复制。
比如:CloneA,CloneB 两者都满足上述所说条件,对CloneA的clone()方法进行改写
public class CloneA implements Cloneable{CloneB b;public Object clone(){ CloneA o = null; try{ o = (CloneA)super.clone(); }catch(CloneNotSupportedException e){ e.printStackTrace(); } o.b = (CloneB)b.clone(); return o; }}
要注意有些java类不能实现clone这种方案,且对象包含关系比较复杂的时候,这种方案不可取。
2.利用对象的序列化和反序列化来实现对象的clone
序列化是指:把java对象转化为字节流。反序列化:把字节流转为java对象
注意:虽然Java的序列化非常简单、强大,但是要用好,还有很多地方需要注意。比如曾经序列化了一个对象,可由于某种原因,该类做了一点点改动,然后重新被编译,那么这时反序列化刚才的对象,将会出现异常
2.1 利用序列化来实现深层clone,则在相应的函数里应该这样写:将对象写入到流内,然后将流反序列化到对象,返回对象。
注意:如果有的对象不能实现序列化,则要考虑该对象可否设成transient,从而将之排除在复制过程之外
例子:
//写入到流里面去 ByteArrayOutoutStream bo=new ByteArrayOutputStream(); ObjectOutputStream oo=new ObjectOutputStream(bo); oo.writeObject(this); //从流里读出来 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); return(oi.readObject());主要的两个:ObjectInputeStream ObjectOutputStream.这两个对象流都是由包含对象字节流构造而成。
序列化的注意问题下一篇<java序列化相关内容整理>
- java中对象的复制与相等判断
- java中判断类对象是否相等的方法
- java中判断一个类的对象是否相等问题
- java中判断两个对象是否相等
- 判断java中两个对象是否相等
- 判断java中两个对象是否相等
- 判断java中两个对象是否相等
- 判断java中两个对象是否相等
- java对象判断相等
- java的判断对象相等的问题
- Java中字符串相等的判断
- java 中 equals() 相等的两个对象,hashcode() 一定相等
- java 中 equals() 相等的两个对象,hashcode() 一定相等
- Java 对象之间的比较,判断两个对象的某一个属性相等,则对象相等
- 学习体会:在JAVA中如何判断两个对象是否相等
- python中对象相等判断(is、==与__dict__的使用)
- 在java的集合中是怎么判断两个对象是否相等的?(重要!)
- Java对象的相等性判断 equasl( )方法 与 ==操作符
- linux 解决终端乱码
- Android Camera 拍照 三星BUG总结
- 强大的http调试工具charles用法详解
- LeetCode——Longest Palindromic Substring
- 斐波那契数列 dp
- java中对象的复制与相等判断
- [转载]树的先序遍历,中序遍历,后序遍历的非递归写法
- ACdream群赛15 I 字典树
- 4.0版本之后创建SessionFactory 方法有所改变
- Web开发人员需知的Web缓存知识
- crm快速开发之Entity
- C++事件和互斥使用的小心得
- hdu 1010 非递归实现
- The number of steps - UPC 2225 dp