(原)java中对象复制、==、equals
对于基本数据类型而言,即如下八种基本数据类型,int,boolean,char,byte,short,float,double,long。
public class test
{
public static void main(String[] args)
{
int a=3;
int b=a;
int c=3;
b=2;
System.out.println("a: "+a);
System.out.println("b: "+b);
System.out.println(a==b);
System.out.println(a==c); }
}
说明:对于基本数据类型,==只是比较两个变量的值,并没有比较其地址,并且其变量复制后,任意改变其中一个变量时,并没有对另一个变量产生变化,默认实现的是深拷贝。
一个简单的浅拷贝示例,浅拷贝中复制出来的对象的域与原始对象的域使用相同的对象引用,指向的是同一个对象,相当于在两个对象中对同一个对象进行处理,会产生潜在的问题。
Object类的clone方法复制对象的做法是对当前对象中所有实例域进行逐一复制。先创建一个新的对象,再把新对象中所有的实例域的值初始化成原始对象中对应域的当前值。
class ToBeCloned implements Cloneable//Cloneable为标记接口,其内不包含任何方法,要实现此接口的话,必须重写clone方法,否则
//抛出异常java.lang.CloneNotSupportedException异常
{
private int value=0;
public void setValue(int value)
{
this.value=value;
}
public int getValue()
{
return this.value;
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class SimpleClone
{
public static void main(String[] args)
{
ToBeCloned obj=new ToBeCloned();
obj.setValue(1);
ToBeCloned cloneObj=(ToBeCloned)obj.clone(); System.out.println("cloneObj.getValue(): "+cloneObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
obj.setValue(2);
System.out.println("cloneObj.getValue(): "+cloneObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
}
}
如果对象中只包含值为基本类型或不可变对象的域,用上面的方法就可以了,内部域为基本数据类型。但是当对象中某些域的值为可变对象时,上述方法就不能满足了。示例如下:
class Counter
{
private int value=0;
public void increase()
{
value++;
}
public int getValue()
{
return value;
}
} class MutableObject implements Cloneable
{
private Counter counter=new Counter();
public void increase()
{
counter.increase();
}
public int getValue()
{
return counter.getValue();
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class MutableObjectClone
{
public static void main(String[] args)
{
MutableObject obj=new MutableObject();
obj.increase();
MutableObject clonedObj=(MutableObject)obj.clone();
clonedObj.increase();
obj.increase();
System.out.println(clonedObj.getValue());
System.out.println(obj.getValue());
}
}
这说明Object类的clone方法已经对类中的基本类型和不可变对象的域进行了处理,只要在这基础上添加对可变对象的域的处理即可。即通过递归的方式来对clone进行修改。
因为在Counter中value为int类型,故递归截止为此函数。
class Counter implements Cloneable
{
private int value=0;
public void increase()
{
value++;
}
public int getValue()
{
return value;
}
public Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} class MutableObject implements Cloneable
{
private Counter counter=new Counter();
public void increase()
{
counter.increase();
}
public int getValue()
{
return counter.getValue();
}
public Object clone()
{
MutableObject obj;
try
{
obj=(MutableObject)super.clone();
obj.counter=(Counter)counter.clone();
return obj;
}
catch(CloneNotSupportedException e)
{
throw new Error(e);
}
}
} public class MutableObjectClone
{
public static void main(String[] args)
{
MutableObject obj=new MutableObject();
obj.increase();
MutableObject clonedObj=(MutableObject)obj.clone();
clonedObj.increase();
obj.increase();
obj.increase();
System.out.println("clonedObj.getValue(): "+clonedObj.getValue());
System.out.println("obj.getValue(): "+obj.getValue());
}
}
在这里要注意在类Object中,clone()方法是protected权限的。
进行复制对象的另外一个做法是使用复制构造方法,即用一个已有 的对象去构造另外一个对象。
示例如下:
public class UserException
{
private String name;
private String email; public User(String name,String email)
{
this.name=name;
this.email=email;
}
public User(User user)
{
this.name=user.getName();
this.email=user.getEmail();
} public String getName()
{
return this.name;
}
public String getEmail()
{
return this.email;
}
}
(原)java中对象复制、==、equals的更多相关文章
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- JAVA中浅复制与深复制
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- 深入分析Java中的 == 和equals
关于Java中的 == 和equals的解释请看这位博主的文章 :http://www.cnblogs.com/dolphin0520/p/3592500.html 以下是我对这篇文章的一些扩展. 对 ...
- 2)Java中的==和equals
Java中的==和equals 1.如果比较对象是值变量:只用== 2.如果比较对象是引用型变量: ==:比较两个引用是不是指向同一个对象实例. equals: ...
- java中的==和equals的区别
关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...
- java中数组复制的两种方式
在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...
- java中的==、equals()、hashCode()源码分析(转载)
在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...
- java中的==、equals()、hashCode()
java中的==.equals().hashCode()源码分析 在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中 ...
随机推荐
- java9-3 返回类型
1. 返回值类型 基本类型:(基本类型简单) 引用类型: 类:返回的是该类的对象 class Student2 { public void study() { System.out.println(& ...
- [转] 值得推荐的C/C++框架和库
http://www.cppblog.com/merlinfang/archive/2014/12/26/209311.aspx
- 日期选择器:jquery datepicker的使用
helloweba.com 作者:月光光 时间:2012-04-08 21:05 标签: jquery datepicker jquery ui 在jquery ui中,提供了一个非常实用 ...
- Corotational 模型代码
今天看了Corotational模型的代码. 在Vega中,获得模型内力的方法是先构造一个ForceModel对象,再调用其对应方法. 对于Corotational模型,构造的流程为: 构造Corot ...
- 事故记录-过多进程致使CPU卡死
早上到公司,发现邮箱内有报警信息显示CPU和IO使用都已超标.报警内容如下:主机: test-server-192.168.1.18 时间: 2015.11.15 15:25:17状态: PROBLE ...
- Mac快捷键、命令行
睡眠:option + command + 电源键 立即关机:Cmd-Opt-Ctrl-Eject 立即重启:Cmd-Ctrl-Eject 弹出关机提示 :Ctrl + 关机 正常关机快捷键 : C ...
- 异常:NSException和NSAssert的简单使用
//断言 - (void)NSAssert_Test:(NSString *)string{ NSAssert(string == nil, @"string == kong or nil& ...
- Java compiler level does not match the version of the installed Java project facet.(转)
Java compiler level does not match解决方法 从别的地方导入一个项目的时候,经常会遇到eclipse/Myeclipse报Description Resource P ...
- 图像相似度算法的C#实现及测评
近日逛博客的时候偶然发现了一个有关图片相似度的Python算法实现.想着很有意思便搬到C#上来了,给大家看看. 闲言碎语 才疏学浅,只把计算图像相似度的一个基本算法的基本实现方式给罗列了出来,以至于在 ...
- Eclipse系列: Eclipse设置Tomcat启动超时时间
在eclipse的workspace目录下,找到如下文件: .metadata\.plugins\org.eclipse.wst.server.core\servers.xml 如下图所示,然后将它修 ...