package com.aiitec.test;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public abstract class Entity implements Cloneable {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/**
* 对象的克隆方法, 伪深度克隆,也就是说对象里的除常用数据类型外的属性都是 Entity的子类就没问题,
* 但是StringBuffer,HashMap这些东西就不行了
*/
@SuppressWarnings("unchecked")
@Override
public Object clone() {
try {
Object entity = super.clone();
for (Field field : getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
if( field.get(this) != null){
// 对象
if (Entity.class.isAssignableFrom(field.getType())) {
Object value = field.get(this);
field.set(this, ((Entity) value).clone());
} else if (List.class.isAssignableFrom(field.getType())) {
List datas = new ArrayList<>();
for (Object childEntity: (List)field.get(entity)) {
if(Entity.class.isAssignableFrom(childEntity.getClass())){
datas.add(((Entity)childEntity).clone());
} else {
datas.add(childEntity);
}
}
field.set(this, datas);
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return entity;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
/**
* 两个相同属性的类的克隆 比如 Data1 和 Data2的属性完全一样,那么就可以这样 Data2 data2 =
* data1.cloneTo(Data2.class) 当然这里考虑的常用的数据类型 和
* 继承至这个类的对象,特殊的数据类型可能不支持,但是已经达到我的要求了 这个最好写在一个所有对象的父类里,要不然又有其他问题
*
* 同类克隆用clone()方法, 不同类克隆用cloneTo(Class>)方法
*@param clazz
*@return
*@throws InstantiationException
*@throws IllegalAccessException
*/
@SuppressWarnings("unchecked")
public T cloneTo(Class clazz) {
T newObj = null;
try {
Object entity = super.clone();
if (entity.getClass().equals(clazz)) {
newObj = (T) entity;
} else {
try {
newObj = clazz.newInstance();
//已经有值的类的所有属性
List fields = FieldUtil.getAllFields(getClass());
for (Field field : fields) {
field.setAccessible(true);
//等待赋值的类的所有属性
List field2s = FieldUtil.getAllFields(clazz);
for (Field field2 : field2s) {
if (field2.getName().equals(field.getName())) {
field2.setAccessible(true);
if(field.get(entity) != null){
// Entity是当前类,也就是所有能互相复制的父类
if (Entity.class.isAssignableFrom(field.getType())) {
Entity child = (Entity) field.get(entity);
field2.set(newObj, child.cloneTo(field2.getType()));
} else if (List.class.isAssignableFrom(field.getType())) {
List datas = new ArrayList<>();
for (Object childEntity: (List)field.get(entity)) {
if(Entity.class.isAssignableFrom(childEntity.getClass())){
datas.add(((Entity)childEntity).clone());
} else {
datas.add(childEntity);
}
}
field2.set(newObj, datas);
} else {
field2.set(newObj, field.get(entity));
}
}
}
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return newObj;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{");
List fields = FieldUtil.getAllFields(getClass());
for (Field field : fields) {
field.setAccessible(true);
try {
Object value = field.get(this);
sb.append('\"').append(field.getName()).append("\":");
if (field.getType().isPrimitive()
|| field.getType() == String.class || Enum.class.isAssignableFrom(field.getType())) {
sb.append('\"').append(value.toString()).append('\"')
.append(',');
} else if (List.class.isAssignableFrom(field.getType())) {
List> datas = (List>) value;
sb.append('[');
for (int i = 0; i < datas.size(); i++) {
sb.append(datas.get(i).toString()).append(',');
}
if (sb.toString().endsWith(",")) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append(']').append(',');
}
else {// 对象的值不需要引号
sb.append(value.toString()).append(',');
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (sb.toString().endsWith(",")) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
}
//再写一个类测试
public class test1 {
public static void main(String[] args) {
User user = new User();
user.setId(5);
user.setAge(18);
user.setMoney(23.5f);
user.setName("张三");
Address address = new Address();
address.setCity("广州");
address.setStreet("荔湾路");
user.setAddress(address);
List ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
List images = new ArrayList<>();
Image image = new Image();
image.setPath("1.jpg");
images.add(image);
user.setIds(ids);
user.setImages(images);
User2 user2 = (User2)user.cloneTo(User2.class);
user2.setAge(23);
user2.setId(24);
Address address2 = user2.getAddress();
address2.setCity("北京");
address2.setStreet("中关村");
user2.setAddress(address2);
Image image2 = new Image();
image2.setPath("2.jpg");
user2.getImages().add(image2);
user2.getIds().add(666);
user2.setCacheMode(Character.EXTROVERSION);
System.out.println("child1:----"+user.toString());
System.out.println("child4:----"+user2.toString());
}
}
//打印结果,我格式化了
//child1:----
{
"name": "张三",
"age": "18",
"money": "23.5",
"cacheMode": "INTROVERT",
"address": {
"city": "广州",
"street": "荔湾路",
"id": "0"
},
"ids": [
1,
2,
3
],
"images": [
{
"path": "1.jpg",
"id": "0"
}
],
"id": "5"
}
//child4:----
{
"name": "张三",
"age": "23",
"money": "23.5",
"cacheMode": "EXTROVERSION",
"address": {
"city": "北京",
"street": "中关村",
"id": "0"
},
"ids": [
1,
2,
3,
666
],
"images": [
{
"path": "1.jpg",
"id": "0"
},
{
"path": "2.jpg",
"id": "0"
}
],
"id": "24"
}