1.对象的复制
2.clone()的使用
3.对象实例的比较
////////////////////
//
/////////////////////
1.对象的复制
- Stringstr1="Thisisastring!"//这里是"对象引用"的复制
- Stringstr2=newString(str1);//这里是"对象实例"的复制
浅复制:只复制复合对象本身.
深复制:除了复制复合对象本身,还复制了复合对象的引用的对象实例.
例如:
- classPupil{
- publicPupil(Stringsno,Stringname,intage){
- this.sno=newString(sno);
- this.name=newString(name);
- this.age=age;
- }
- publicStringgetSno(){
- returnsno;
- }
- publicStringgetName(){
- returnname;
- }
- publicintgetAge(){
- returnage;
- }
- publicvoidsetAge(intage){
- this.age=age;
- }
- privateStringsno;
- privateStringname;
- privateintage;
- }
- publicclassCopyDemo{
- publicstaticPupil[]shallowCopy(Pupil[]aClass){
- Pupil[]newClass=newPupil[aClass.length];
- //此时newClass与aClass指向同一块内存
- for(inti=0;i<aClass.length;i++)
- newClass[i]=aClass[i];
- returnnewClass;
- }
- publicstaticPupil[]deepCopy(Pupil[]aClass){
- Pupil[]newClass=newPupil[aClass.length];
- //此时newClass与aClass的相应sno,name指向同一块内存
- for(inti=0;i<aClass.length;i++){
- Stringsno=aClass[i].getSno();
- Stringname=aClass[i].getName();
- intage=aClass[i].getAge();
- newClass[i]=newPupil(sno,name,age);
- }
- returnnewClass;
- }
- publicstaticPupil[]deeperCopy(Pupil[]aClass){
- Pupil[]newClass=newPupil[aClass.length];
- //完全的复制
- for(inti=0;i<aClass.length;i++){
- Stringsno=newString(aClass[i].getSno());
- Stringname=newString(aClass[i].getName());
- intage=aClass[i].getAge();
- newClass[i]=newPupil(sno,name,age);
- }
- returnnewClass;
- }
- }
2.clone()的使用
*Object.clone()
*Cloneable接口
*CloneNotSupportedException
a.使用Object.clone进行复制
两个必须条件:
1.一定要将重定义后的clone()方法定义为公有方法(在Object类中,它是受保护的成员,不能直接使用)
2.该后代类声明实现接口Cloneable接口(当类实现该接口,其任何子类也会继承该接口),该接口实际上没有任何
内容,只是一个标识,标志实现该接口的类提供clone()方法.(这是接口的一种非典型用法)
- publicclassFractionimplementsCloneable{
- publicObjectclone(){
- try{
- returnsuper.clone();//callprotectedmethod
- }catch(CloneNotSupportedExceptione){
- returnnull;
- }
- }
- //othermethods...
- }
b.重写Object.clone()
例如对privatechar[]cb;characterbuffer进行复制
- //addinclassCirbuf
- publicObjectclone(){
- try{
- Cirbufcopy=(Cirbuf)super.clone();
- copy.cb=(char[])cb.clone();
- returncopy;
- }catch(CloneNotSupportedExceptione){
- thrownewInternalError(e.toString());
- }
- }
c.复制数组
数组是在方法调用重以引用的形式传递的对象.下述情况下非常适合引用来传递数组:
*正在接收的方法不修改数组
*正在调用的方法不必关心是否修改数组
*正在调用的方法想要得到数组中的修改结果
否则,就应该在方法调用中传递数组对象的副本.只需调用arrObj.clone()方法即可完成数组arrObj的复制操作.随后将该数组副本强制转换为其正确类型:
(type[])arrObj.clone();
System.arraycopy方法提供一种用于在数组间复制多个元素的有效方式.
System.arraycopy(source,i,target,j,len)
3.对象实例的比较
例如:
- Pupilp1=newPupil("99184001","zhang3",18);
- Pupilp2=newPupil("99184001","zhang3",18);
a."=="
if(p1==p2)...
此次测试的是对象引用,其结果肯定是false,只要两个对象引用不是互为别名就不会相等.
b.浅比较false
- if(p1.getSno()==p2.getSno()&&p1.getName()==p2.getName()
- &&p1.getAge()==p2.getAge())...;
c.深比较true[/code]
if(p1.getSno().equals(p2.getSno())&&p1.getName().equals(p2.getName())
&&p1.getAge()==p2.getAge())...;[/code]
JAVAAPI的跟类Object也提供了equals()方法,但它只是比较两个对象引用,而非比较两个对象实例.
不管怎样,如果需要比较Pupil类的对象(例如要将它们放入对象容器),应该为Pupil类重定义equals()方法:
- publicbooleanequals(Objectotherobj){
- //检查otherobj是否为空
- if(otherobj==null)returnfalse;
- //检查otherobj是否就是当前对象
- if(otherobj==this)returntrue;
- //检查otherobj是否具有正确的类型,即检查是否可与当前对象比较
- if(!(otherobjinstanceofPupil))returnfalse;
- //将otherobj转换为Pupil类的对象引用
- PupiltmpObj=(Pupil)otherobj;
- //关于学生是否相等的逻辑检查
- if(sno.equals(tmpObj.sno)&&name.equals(tmpObj.name)
- &&age==tmpObj.age)returntrue;
- returnfalse;
- }
JAVAAPI所提供的每个类几乎都提供了采用深比较策略的equals()方法,例如String类equals()方法.一般来说,用户自己定义的类也应当提供合适的equals()方法,特别是当程序要将其对象放入JAVAAPI所提供的对象容器类的时候.
按照约定,任何类所提供的equals()方法所实现的相等比较应该是等价关系,即满足自反性,对称性和传递性.另外一个类重定义了equals()方法,也应该重定义相应hashCode()方法,否则将这个类的对象放入映射对象容器时也会发生以外.