java深度克隆大数据_Java - 深拷贝技巧

先让我描述一下问题:

我在某Action(struts2.x)-A中写了一个功能P,以当前用户的某个标识F == 1时需要走这个功能,而且这个功能因某些原因已经侵入到了其他一些method中。

顺便一提,A中获得当前用户session的method已经被父类封装好了。

然后我的代码已经push上去了,第二天有人告诉我能不能暂时去掉这个功能。

一个个注释掉太麻烦了,

于是我决定在这个A中override获得当前用户session的method,并将F赋值为0。

于是我只需要来个shallow copy就可以了。

比如我可以这样:

给User来个implements Clonable

然后在getUserInfo()的Override中clone一个出来再赋值setF(0)

但这也许不太好,毕竟我需要动User。

我可以直接使用org.springframework.beans.BeanUtils.copyPropergties(source,target)

看了看源码,里面又是sourcepd又是targetpd,pd是什么?

eefac1fc94383f830a7e0313fd3bbb1c.png

就当他是用来描述java bean的媒介好了。

当然,他也是shallow copy...

for (PropertyDescriptor targetPd : targetPds) {

if (targetPd.getWriteMethod() != null &&

(ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {

PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());

if (sourcePd != null && sourcePd.getReadMethod() != null) {

try {

Method readMethod = sourcePd.getReadMethod();

if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {

readMethod.setAccessible(true);

}

Object value = readMethod.invoke(source);

Method writeMethod = targetPd.getWriteMethod();

if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {

writeMethod.setAccessible(true);

}

writeMethod.invoke(target, value);

} catch (Throwable ex) {

throw new FatalBeanException("Could not copy properties from source to target", ex);

}

}

}

}

无论如何,这个已经解决我的问题了,A中调用getUserInfo()都是我clone的User,不会影响其他的Action.

但如果我那天用User下某个引用类型的Field的某个simple type的Field做标记呢?

那我得deep clone,平时掌握的类库不多,让我自己解决的话我怎么弄?

也许我可以这样做:

File f = new File("@#$%^&*");

f.createNewFile();

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));

oos.writeObject(u0);

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));

u1 = (User)ois.readObject();

光看一小段代码感觉是个简单粗暴的好办法,只不过我得User及其下那些引用类型加上implements Serializable...

后来我找到了这样一个东西:

uk.com.robust-it

cloning

1.9.0

可以这样使用:

com.rits.cloning.Cloner cloner = new com.rits.cloning.Cloner();

u1 = cloner.deepClone(u0);

u1.getPet().setName("papapa");

System.out.println(u0);

System.out.println(u1);

输出结果是clone后的u1的pet的名字变成了papapa而作为clone source的u0没有任何变化,这就是deep clone.

忽略clone source是数组的情况,这个类进行deep clone的关键部分如下:

for (final Field field : fields) {

final int modifiers = field.getModifiers();

if (!Modifier.isStatic(modifiers)) {

if (nullTransient && Modifier.isTransient(modifiers)) {

// request by Jonathan : transient fields can be null-ed

final Class> type = field.getType();

if (!type.isPrimitive()) {

field.set(newInstance, null);

}

} else {

final Object fieldObject = field.get(o);

final boolean shouldClone = (cloneSynthetics || (!cloneSynthetics && !field.isSynthetic())) && (cloneAnonymousParent || ((!cloneAnonymou        sParent && !isAnonymousParent(field))));

final Object fieldObjectClone = clones != null ? (shouldClone ? cloneInternal(fieldObject, clones) : fieldObject) : fieldObject;

field.set(newInstance, fieldObjectClone);

if (dumpClonedClasses && fieldObjectClone != fieldObject) {

System.out.println("cloned field>" + field + " -- of class " + o.getClass());

}

}

}

}

递归下去找field的引用的引用的引用的引用....然后全是他们newInstance...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值