【Java】【反射技术】2个对象除了类名不一样,类的定义部分完全一样;当给定一个对象,转换成另一个类的对象。

1.需求

有时候,在项目开发时候会遇到,特别是Web项目开发,本地工程有一个类A,web工程根据配置文件会自动生成另外一个class B,而A和B除了类名不同,

其他诸如成员变量以及get\set方法都是相同的(就像下面的Objec1和Object2两个类一样),这时候,就会需要一个API将A的对象转换成B的对象在Web上进行消息交互。

public class Object1
{
	private int attrInt;

	public int getAttrInt()
	{
		return attrInt;
	}

	public void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}
}

public class Object2
{
	private int attrInt;

	public int getAttrInt()
	{
		return attrInt;
	}

	public void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}
}

2.使用Java语言中的放射技术进行通用转换API实现

默认的转换是进行完整的转换,具体使用可以调用方法toAnotherObj(K oneObj, Class<V> anotherClassObj)


package devin.wu.training.reflect.convertor;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ObjectConvertor
{
	
	public <K,V> V toAnotherObj(K oneObj, Class<V> anotherClassObj)
	{
		return toAnotherObj(oneObj, anotherClassObj, null);
	}

	public <K,V> V toAnotherObj(K oneObj, Class<V> anotherClassObj, FieldFilter filter)
	{
		V anotherObj = null;
		try
		{
			anotherObj = anotherClassObj.newInstance();
			Class<?> oneClassObj = oneObj.getClass();
			Field[] fields = getMatchedFields(oneClassObj, filter);
			for (Field field : fields)
			{
				String fieldName = field.getName();
				String append = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
				String getMethodName = "get" + append;
				String setMethodName = "set" + append;
				Method getMethod = oneClassObj.getDeclaredMethod(getMethodName);
				getMethod.setAccessible(true);
				Object attrForOneObj = getMethod.invoke(oneObj);
				Method setMethod = anotherClassObj.getDeclaredMethod(setMethodName, field.getType());
				setMethod.setAccessible(true);
				setMethod.invoke(anotherObj, attrForOneObj);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return anotherObj;
	}

	private Field[] getMatchedFields(Class<?> classObj, FieldFilter filter)
	{
		List<Field> matchedFields = new ArrayList<Field>();
		Field[] fields = classObj.getDeclaredFields();
		for (Field field : fields)
		{
			if (null == filter || filter.accept(field))
			{
				matchedFields.add(field);
			}
		}

		return matchedFields.toArray(new Field[] {});
	}
}
下面的接口设计的引入,是为了满足对类对象转换有特殊需求的场景。可以再accept方法中根据Filed的内容进行设置过滤条件。
package devin.wu.training.reflect.convertor;

import java.lang.reflect.Field;

public interface FieldFilter
{
	boolean accept(Field field);
}


3. 上述API的测试代码

package devin.wu.training.reflect.convertor;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import junit.framework.TestCase;

public class ObjectConvertorTest extends TestCase
{
	private ObjectConvertor convertor;
	
	@Override
	protected void setUp() throws Exception
	{
		convertor = new ObjectConvertor();
	}
	
	public void testWithoutField()
	{
		ObjectWithoutFiled1 obj1 = new ObjectWithoutFiled1();
		
		ObjectWithoutFiled2 obj2 = convertor.toAnotherObj(obj1, ObjectWithoutFiled2.class);
		
		assertNotNull(obj2);
	}
	
	public void testWithOneIntField()
	{
		ObjectWithOneIntFiled1 obj1 = new ObjectWithOneIntFiled1();
		obj1.setAttrInt(1);
		
		ObjectWithOneIntFiled2 obj2 = convertor.toAnotherObj(obj1, ObjectWithOneIntFiled2.class);
		
		assertEquals(obj1.getAttrInt(), obj2.getAttrInt());
	}
	
	public void testWhenFilterStatic()
	{
		Object1 obj1 = new Object1();
		obj1.setAttrInt(1);
		obj1.setAttrDouble(2.0);
		obj1.setAttrString("3");
		obj1.setAttrArray(new int[]{5, 6});

		ObjectConvertor objectConvertor = new ObjectConvertor();
		Object2 obj2 = objectConvertor.toAnotherObj(obj1, Object2.class, new FieldFilter()
		{
			@Override
			public boolean accept(Field field)
			{
				return field.getModifiers() < Modifier.STATIC;
			}
		});

		assertEquals(obj1.getAttrInt(), obj2.getAttrInt());
		assertEquals(obj1.getAttrDouble(), obj2.getAttrDouble());
		assertEquals(obj1.getAttrString(), obj2.getAttrString());
		int[] attrArray = obj2.getAttrArray();
		assertNotNull(attrArray);
		assertEquals(2, attrArray.length);
		assertEquals(5, attrArray[0]);
		assertEquals(6, attrArray[1]);
	}
}

package devin.wu.training.reflect.convertor;

import java.io.Serializable;

public class Object1 implements Serializable
{
	private static final long serialVersionUID = 805500988847131314L;
	
	private int attrInt;
	private double attrDouble;
	private String attrString;
	private int[] attrArray;

	private int[] getAttrArray()
	{
		return attrArray;
	}

	public void setAttrArray(int[] attrArray)
	{
		this.attrArray = attrArray;
	}

	public int getAttrInt()
	{
		return attrInt;
	}

	public void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}

	public double getAttrDouble()
	{
		return attrDouble;
	}

	public void setAttrDouble(double attrDouble)
	{
		this.attrDouble = attrDouble;
	}

	public String getAttrString()
	{
		return attrString;
	}

	public void setAttrString(String attrString)
	{
		this.attrString = attrString;
	}
}

package devin.wu.training.reflect.convertor;

public class Object2
{
	private int attrInt;
	private double attrDouble;
	private String attrString;
	private int[] attrArray;

	public int[] getAttrArray()
	{
		return attrArray;
	}

	public void setAttrArray(int[] attrArray)
	{
		this.attrArray = attrArray;
	}
	
	public int getAttrInt()
	{
		return attrInt;
	}

	private void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}

	public double getAttrDouble()
	{
		return attrDouble;
	}

	public void setAttrDouble(double attrDouble)
	{
		this.attrDouble = attrDouble;
	}

	public String getAttrString()
	{
		return attrString;
	}

	public void setAttrString(String attrString)
	{
		this.attrString = attrString;
	}
}

package devin.wu.training.reflect.convertor;

public class ObjectWithOneIntFiled1
{
	private int attrInt;

	public int getAttrInt()
	{
		return attrInt;
	}

	public void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}
}

package devin.wu.training.reflect.convertor;

public class ObjectWithOneIntFiled2
{
	private int attrInt;

	public int getAttrInt()
	{
		return attrInt;
	}

	public void setAttrInt(int attrInt)
	{
		this.attrInt = attrInt;
	}
}

package devin.wu.training.reflect.convertor;

public class ObjectWithoutFiled1
{

}


package devin.wu.training.reflect.convertor;

public class ObjectWithoutFiled2
{

}



猜你喜欢

转载自blog.csdn.net/WolfOfSiberian/article/details/53192478
今日推荐