首页 > 学院 > 开发设计 > 正文

java中的clone

2019-11-15 00:33:07
字体:
来源:转载
供稿:网友
java中的clone1.先说一句

不去覆盖clone方法,不去调用clone方法,除非真的有必要。

2.java中clone两个概念浅克隆 copy的是引用深克隆 copy的是实例,开辟新的堆空间java中的clone方法实现的是浅克隆,一个类可被浅克隆需实现Cloneable(此接口只是说明此类允许clone,它改变的是超类中受保护的clone方法的行为),如effective java中的第11条所说这是接口的一种极端非典型的用法,不值得效仿。3.浅克隆浅克隆看上去只要实现了Cloneable接口 且@Override clone方法为public后就可以了,但是实际应用了,确定你要的是浅clone么?若是一个对象没有实现Cloneable接口,也可以很简单的使用反射实现对象的浅复制:非严谨的code如下:
    public static <T> T simpleClone(T obj) throws IllegalaccessException, InstantiationException {        Class<T> c = (Class<T>) obj.getClass();        T cloneC = c.newInstance();        Field[] fields = c.getDeclaredFields();        if (fields != null && fields.length > 0) {            for (Field field : fields) {                field.setAccessible(true);                Object value = field.get(obj);                field.set(cloneC, value);            }        }        return cloneC;    }

当然有很多工具类了:比如,sPRing的BeanUtils.copyProperties, apache的BeanUtils.copyProperties,cglib或者spring-cglib的BeanCopier

4.深克隆既然实际应用中更希望使用的是深克隆,那么如何实现呢
  • bean 自己实现Cloneable接口,靠谱的实现clone方法
非严谨code如下:
public class TestCloneBean implements Cloneable {       private List<Integer> integers;     public List<Integer> getIntegers() {        return integers;    }     public void setIntegers(List<Integer> integers) {        this.integers = integers;    }     @Override    public TestCloneBean clone() {        try {            TestCloneBean t = (TestCloneBean) super.clone();            t.setIntegers(Lists.<Integer> newArrayList());            if (CollectionUtils.isNotEmpty(integers)) {                for (Integer i : integers) {                    t.getIntegers().add(i);                }            }            return t;         } catch (CloneNotSupportedException e) {            throw new RuntimeException(e);        }    }     @Override    public String toString() {        return ToStringBuilder.reflectionToString(this);    }}

  • 第一种方法你会这么做么?不会。那么只能另外一种方式:序列化啊!
非严谨code如下:
public class JsonUtils {    private static ObjectMapper objectMapper = new ObjectMapper();     static {        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);        objectMapper.configure(JsonParser.Feature.INTERN_FIELD_NAMES, true);        objectMapper.configure(JsonParser.Feature.CANONICALIZE_FIELD_NAMES, true);        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);        objectMapper.setSerializationInclusion(Inclusion.NON_NULL);    }     public static ObjectMapper getObjectMapperInstance() {        return objectMapper;    } } 

testCode如下:
        TestCloneBean b = new TestCloneBean();        b.setIntegers(Lists.newArrayList(1));        String s = JsonUtils.getObjectMapperInstance().writeValueAsString(b);        TestCloneBean a = JsonUtils.getObjectMapperInstance().readValue(s, TestCloneBean.class);


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表