[改善Java代码]警惕数组的浅拷贝
建议62:警惕数组的浅拷贝
一、分析
在日常工作中,我们会遇见很多数组的拷贝和复制的问题,但是在你使用系统提供的API进行编码的时候,无形中会留下浅拷贝的隐患。
二、场景
有这样一个例子,第一个箱子里面与赤橙黄绿青蓝紫7色气球,现在希望第二个箱子也放入7个气球,其中最后一个气球改为蓝色,也就是赤橙黄绿青蓝蓝七个气球。
import org.apache.commons.lang3.builder.ToStringBuilder; public class Client{
public static void main(String[] args){
//气球的数量
int ballonNum = 7;
//第一个箱子
Ballon[] box1 = new Ballon[ballonNum];
//初始化第一个箱子
for(int i = 0; i < ballonNum; i++){
box1[i] = new Ballon(Color.values()[i],i);
} //第二个箱子的小球是拷贝的第一个箱子里的
Ballon[] box2 = Arrays.copyOf(box1,box1.length);
//修改最后一个气球的颜色
box2[6].setColor(Color.Blue);
//打印出第一个箱子中的气球颜色
for(Ballon b:box1){
System.out.println(b);
}
}
} //气球的颜色
enum Color{
Red,Orange,Yellow,Green,Indigo,Blue,Violet;
} //气球
class Ballon{
//编号
private int id;
//颜色
private Color color; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public Color getColor() {
return color;
} public void setColor(Color color) {
this.color = color;
} public Ballon(Color _color,int _id){
color = _color;
id = _id;
} /*id、color的getter/setter方法省略*/
//apache-common包下的ToStringBuilder重写toString方法
public String toString(){
return new ToStringBuilder(this).append("编号",id).append("颜色",color).toString();
}
}
第二个箱子的最后一个气球毫无疑问是被修改了蓝色,不过是通过拷贝第一个箱子的气球实现的,那么会对第一个箱子的气球颜色有影响吗?输出结果:
Balloon@b2fd8f[编号=0,颜色=Red]
Balloon@a20892[编号=1,颜色=Orange]
Balloon@158b649[编号=2,颜色=Yellow]
Balloon@1037c71[编号=3,颜色=Green]
Balloon@1546e25[编号=4,颜色=Indigo]
Balloon@8a0d5d[编号=5,颜色=Blue]
Balloon@a470b8[编号=6,颜色=Blue]
最后一个气球竟然被修改了。这是为何?
这是典型的浅拷贝(Shallow Clone)问题,通过copyOf()方法产生的数组是一个浅拷贝引用地址。需要说明的是数组的clone()方法也是与此相同,同样是浅拷贝,而且集合的clone()方法也是浅拷贝。这就需要大家多留心了。
问题找到了,解决办法也很简单,遍历box1的每个元素,重新生成一个气球(Ballon)对象,并放置到box2数组中。
很多地方使用集合(如List)进行业务处理时,比如发觉需要拷贝集合中的元素,可集合没有提供任何拷贝方法,所以干脆使用 List.toArray方法转换成数组,然后通过Arrays.copyOf拷贝,然后转换成集合,简单便捷!但是,非常遗憾,这里我们有撞到浅拷贝的 枪口上了!!!!
三、建议
虽然很多时候浅拷贝可以解决业务问题,但更多的时候会留下隐患,需要我们提防又提防。
[改善Java代码]警惕数组的浅拷贝的更多相关文章
- [改善Java代码]警惕泛型是不能协变和逆变的
什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是 ...
- [改善Java代码]避免对象的浅拷贝
建议43: 避免对象的浅拷贝 我们知道一个类实现了Cloneable接口就表示它具备了被拷贝的能力,如果再覆写clone()方法就会完全具备拷贝能力.拷贝是在内存中进行的,所以在性能方面比直接通过ne ...
- [改善Java代码]警惕自增的陷阱
建议7: 警惕自增的陷阱 老师就说:自增有两种形式,分别是i++和++i,i++表示的是先赋值后加1,++i是先加1后赋值,这样理解了很多年也没出现问题,直到遇到如下代码,我才怀疑我的理解是不是错了: ...
- JMeter脚本java代码String数组要写成String[] args,不能写成String args[],否则报错。
JMeter脚本java代码String数组中括号要写在类型关键字后面,不能写在变量名后面.
- java算法面试题:有数组a[n],用java代码将数组元素顺序颠倒
package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.List; ...
- [改善Java代码]若有必要,使用变长数组
Java中的数组是定长的,一旦经过初始化声明就不可改变长度,这在实际使用的时候非常不方便.比如要对一个班级的学生信息进行统计,因为我们不知道班级会有多少个学生(随时可能有退学,入学,转学),所以需要一 ...
- [改善Java代码]asList方法产生的List对象不可更改
上一个建议之处了asList方法在转换基本类型数组时候存在的问题,在看下asList方法返回的列表有何特殊的地方.看代码: import java.util.Arrays; import java.u ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]避开基本类型数组转换列表陷阱
开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题. 看代码: import java.util.Arrays; import ...
随机推荐
- Java Thread.interrupt 害人! 中断JAVA线程(zz)
http://www.blogjava.net/jinfeng_wang/archive/2012/04/22/196477.html#376322 ————————————————————————— ...
- log4j2使用总结
一.Log4j有三个主要的组件:Loggers,Appenders和Layouts,这里可简单理解为日志级别,日志要输出的地方和日志格式 1. Logger Logger的日志级别有6级,分别是TRA ...
- Spring AOP Interceptor transaction is not working
Problem The Spring AOP transaction is not working in following interceptors? <bean id="testA ...
- Spring入门(6)-使用注解装配
Spring入门(6)-使用注解装配 本文介绍如何使用注解装配. 0. 目录 使用Autowired 可选的自动装配 使用Qualifier选择 1. 使用Autowired package com. ...
- 【C++专题】static_cast, dynamic_cast, const_cast探讨
首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...
- javascript中数组的迭代等操作
- error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决方案
首先,卸载相关的软件,然后删除所有和virtual studio相关的目录 然后如果还出现该问题,则: Mark一下,解决方法:将嵌入清单设置为"否" 发生场合:在用 C++写一个 ...
- 从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式(一)
本文转载自 http://blog.csdn.net/cutesource/article/details/6192016 如何正确使用NIO来构架网络服务器一直是最近思考的一个问题,于是乎分析了一下 ...
- 【JDBC】事务的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5868750.html 关于事务的理论知识.ACID特性等等,网上太多了,在此不一一重复.本文主要着重 事务 ...
- myGeneration代码生成器
转自:http://www.cnblogs.com/leitwolf/archive/2007/07/27/833255.html http://blog.csdn.net/happyhippy/ar ...