zoukankan      html  css  js  c++  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是什么?


    就当他是用来描述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...

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

    
    <dependencies>
        <dependency>
            <groupId>uk.com.robust-it</groupId>
            <artifactId>cloning</artifactId>
            <version>1.9.0</version>
        </dependency>
    </dependencies>
    
    

    可以这样使用:

    
    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...

  • 相关阅读:
    Java基础之泛型——使用通配符类型参数(TryWildCard)
    Java基础之泛型——使用二叉树进行排序(TryBinaryTree)
    Java基础之泛型——使用泛型链表类型(TryGenericLinkedList)
    Java基础之序列化对象——反序列化对象(DeserializeObjects)
    Java基础之序列化对象——将对象写入到文件中(SerializeObjects)
    拷贝excel里的内容转为JSON的js代码
    asp.net 正则获取url参数
    vs2013给类添加默认注释
    日货EmEditor的使用小技巧
    express不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/kavlez/p/4003654.html
Copyright © 2011-2022 走看看