package com.haizol.mk.rfq;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtField;
import org.apache.ibatis.javassist.CtMethod;
import org.apache.ibatis.javassist.CtNewMethod;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import com.haizol.common.utils.JacksonUtil;
import com.haizol.mk.rfq.common.utils.StreamUtil;
public class MyTest extends ClassLoader {
//模仿
@Test
public void mimicry(){
TestB testB = new TestB();
testB.setId(1l);
//复制一个类的字段,并自定义一些字段,然后创建一个类
// String[] fields = getFields(testB.getClass(),"peter","coco");
// Object obj = divField(TestA.class,fields);
// BeanUtils.copyProperties(testB, obj);
// System.out.println(JacksonUtil.toJSon(obj));
//自定义一些字段,然后创建一个类
Object obj2 = divField(TestA.class,"id","peter2");
BeanUtils.copyProperties(testB, obj2);
System.out.println(JacksonUtil.toJSon(obj2));
}
//复制对象所有属性值,并返回一个新对象
public Object getObj(Class<?> clazz, Object srcObj) {
try {
Object newInstance = clazz.getDeclaredConstructor().newInstance();
Field[] fields = srcObj.getClass().getDeclaredFields();
for (Field oldInstanceField : fields) {
String fieldName = oldInstanceField.getName();
oldInstanceField.setAccessible(true);
Field newInstanceField = newInstance.getClass().getDeclaredField(fieldName);
newInstanceField.setAccessible(true);
newInstanceField.set(newInstance, oldInstanceField.get(srcObj));
}
return newInstance;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//首字母大写
public String upperFirstStr(String str){
return str.substring(0,1).toUpperCase()+str.substring(1);
}
//获得一个类的所有字段,并可以额外新增字段
private String[] getFields(Class<?> c,String... fields){
List<String> aList = Stream.of(c.getDeclaredFields())
.map(Field::getName)
.collect(Collectors.toList());
aList.addAll(Arrays.asList(fields));
return aList.toArray(new String[]{});
}
//获得自定义字段对象
public Object divField(Class<?> coco,String... fields){
String className = coco.getName();
try {
CtClass cc = ClassPool.getDefault().get(className);
for (String methodName : Arrays.asList(fields)) {
CtField ctField = new CtField(CtClass.longType, methodName,cc);
cc.addField(ctField);
CtMethod getMthd = CtNewMethod.make("public long get"+upperFirstStr(methodName)+"() { return "+methodName+";}", cc);
cc.addMethod(getMthd);
CtMethod setMthd = CtNewMethod.make("public void set"+upperFirstStr(methodName)+"(long "+methodName+") { this."+methodName+" = "+methodName+";}", cc);
cc.addMethod(setMthd);
}
Class<?> clazz = defineClass(className, cc.toBytecode(),0,cc.toBytecode().length);
// 解冻CtClass对象
cc.defrost();
return getObj(clazz,new TestA());
} catch (Exception e) {
e.printStackTrace();
}
return null;
// System.out.println(obj.getClass().getDeclaredMethod("get"+upperFirstStr(methodNames[0])).invoke(obj));
// List<String> newList = new ArrayList<>();
// for (int i = 0; i < 100; i++) {
// doIt(newList);
// }
// System.out.println(newList);
//
// //取出所有西瓜
// List<String> bList = StreamUtil.toPredicateList(newList, e -> e.contains("西瓜"));
// System.out.println(bList);
//
// //取出西瓜的数字
// List<String> aList = new ArrayList<>();
// bList.forEach(o->aList.add(toInt(o)));
// System.out.println(aList);
//
// TestA testA = ok(1L,"peter");
// System.out.println(testA.getId()+testA.getName());
//
// TestA testA2 = ok(2L,"tomcat");
// System.out.println(testA2.getId()+testA2.getName());
}
private static void doIt(List<String> newList){
List<String> aList = Arrays.asList("\n普通品质","\n平凡品质","\n优良品质","\n精选品质","\n完美品质");
newList.add(aList.get(random(0,aList.size()-1)));
aList = Arrays.asList(
"苹果"+random(4,6)+"个","梨"+random(4,6)+"个","香蕉"+random(4,6)+"个","哈密瓜"+random(4,6)+"个",
"西红柿"+random(2,4)+"个","榴莲"+random(2,4)+"个","水蜜桃"+random(6,8)+"个","樱桃"+random(10,30)+"个",
"西瓜"+random(5,10)+"个","李子"+random(10,20)+"个","橘子"+random(6,8)+"个");
newList.addAll(subListRandom(aList,random(2,4)));
}
//字符串提取数字
private static String toInt(String str) {
return StringUtils.join(StreamUtil.toList(Arrays.asList(str.split("")),StringUtils::isNumeric,Integer::valueOf),"");
}
//获得随机数(随机参数a到参数b的数字)
private static int random(int a,int b){
return RandomUtils.nextInt(a, b+1);
}
//随机取出数组中的值
private static List<String> subListRandom(List<String> aList,int random){
//随机(数组数量-随机数)=起始位
int fromIndex = random(0,aList.size() - random);
//起始位+随机数=结束位
int toIndex = fromIndex + random;
//取出数组中[起始位(包括)]到[结束位(不包括)]的值
return aList.subList(fromIndex,toIndex);
}
}
package com.haizol.mk.rfq;
public class TestB {
private long id;
private long num;
public long getNum() {
return num;
}
public void setNum(long num) {
this.num = num;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
package com.haizol.mk.rfq;
public class TestA{
}