(原)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中 ...
随机推荐
- Android 动态加载 (二) 态加载机制 案例二
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...
- 实现了一个简单的cage变形器
今天实现了一个简单变形器,可以用一个网格的形状影响另一个网格的形状. 如图,蓝色网格的形状被灰色网格操控. 当前的算法非常简单,就是计算蓝色网格每个点到灰色网格每个点的距离,以距离x次方的倒数作为权重 ...
- 一个简单的scrapy爬虫抓取豆瓣刘亦菲的图片地址
一.第一步是创建一个scrapy项目 sh-3.2# scrapy startproject liuyifeiImage sh-3.2# chmod -R 777 liuyifeiImage/ 二.分 ...
- S2小测--索引--视图
1. 关于Sql server 视图 视图是一个虚拟表,我们在查询视图的时候,实际上是对基础表的查询.视图不仅可以作为SELECT查询的目标,也可以作为修改语句的目 标.理论上它可以像普通的物理表一 ...
- wireshark排查打印机问题
抓包工具排除故障 前言:上网慢,可能是内网堵了.装上wireshark,可抓到广播包,多播包,以及发给自己的包.如果想抓lan内其他人之间的通信包,那就要在sw上做端口镜像. 背景 调试打印机的人发现 ...
- windows7下修改hosts文件无效解决办法
通常会为了开发方便.或者屏蔽掉一些恶意网站,我们会在hosts(c:\windows\system32\drivers\etc\hosts)文件中进行相应的域名指向,例:
- caffe windows 学习第一步:编译和安装(vs2012+win 64)
没有GPU,没有linux, 只好装caffe的windows版本了. 我的系统是win10(64位),vs 2012版本,其它什么都没有装,因此会需要一切的依赖库. 其实操作系统只要是64位就行了, ...
- PagerIndicator主题样式修改
默认的黑色好丑 所以大家需要动手改造一下, 1 打开 Manifest.xml <activity android:name="com.zb.zhihuianyang.MainActi ...
- MySQL系列:查看并修改当前数据库的编码
MySQL中,数据库的编码是一个相当重要的问题,有时候我们需要查看一下当前数据库的编码,甚至需要修改一下数据库编码. 查看当前数据库编码的SQL语句为: mysql> use xxx ...
- 信息安全系统设计基础实验四 20135210&20135218
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级: 1352 姓名:程涵,姬梦馨 学号:20135210,20135218 ...