通过反射比较两个相同类型的对象中的值是否相同
今天写代码的时候有这样一个需求:
需要验证两个相同类型的不同对象中的属性值是否相同。
传统方式是分别读取两个对象中的属性值,对其进行一一比对,不停if-else。
但是如果有上百个属性值难道你也要去读取上百次,然后写上百个if-else嘛?!
so……用反射吧!
利用语言的反射机制自动遍历对象中的所有属性字段以及属性值,并比较其是否相同。
先上C#的核心代码(emmm……对,后来我又写了个Java版代码)
/// <summary> /// 判断两个相同类型的对象的属性值是否相等 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj1"></param> /// <param name="obj2"></param> /// <returns></returns> private static bool CompareProperties<T>(T obj1, T obj2) { //为空判断 if (obj1 == null && obj2 == null) { return true; } else if (obj1 == null || obj2 == null) { return false; } PropertyInfo[] properties = obj1.GetType().GetProperties(); foreach (var po in properties) { if (!po.GetValue(obj1, null).Equals(po.GetValue(obj2, null))) { return false; } } return true; }
C#版完整demo代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace CommandLineTest { class Program { static void Main(string[] args) { User user1 = new User { Age = 20, Name = "Young", BirthDay = DateTime.Now, Height = 1.7M }; User user2 = new User { Age = 20, Name = "Young", BirthDay = DateTime.Now, Height = 1.7M }; if (CompareProperties(user1, user2)) { Console.WriteLine("对象属性值相同。"); } else { Console.WriteLine("对象属性值不同!"); } Console.ReadLine(); } /// <summary> /// 判断两个相同类型的对象的属性值是否相等 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj1"></param> /// <param name="obj2"></param> /// <returns></returns> private static bool CompareProperties<T>(T obj1, T obj2) { //为空判断 if (obj1 == null && obj2 == null) { return true; } else if (obj1 == null || obj2 == null) { return false; } PropertyInfo[] properties = obj1.GetType().GetProperties(); foreach (var po in properties) { if (!po.GetValue(obj1, null).Equals(po.GetValue(obj2, null))) { return false; } } return true; } } class User { /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 生日 /// </summary> public DateTime BirthDay { get; set; } /// <summary> /// 身高 /// </summary> public decimal Height { get; set; } } }
下面是Java版本的核心代码:
/** * 判断两个相同类型的对象的属性值是否相等 * @param obj1 * @param obj2 * @return * @throws IllegalAccessException * @throws IntrospectionException * @throws InvocationTargetException */ private static boolean CompareProperties(Object obj1, Object obj2) throws IllegalAccessException, IntrospectionException, InvocationTargetException { //为空判断 if (obj1 == null && obj2 == null) { return true; } else if (obj1 == null || obj2 == null) { return false; } Class<?> classType = obj1.getClass(); //如果传入的类型不一样则直接返回false //C#中通过CompareProperties<T>中的<T>可以限定传入的类型必须一致,所以不需要该判断 if (classType != obj2.getClass()) { return false; } Field[] fields = obj1.getClass().getDeclaredFields();//获得所有字段 for (Field field : fields) { PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), classType);//获得类中字段的属性描述 Method getMethod = propertyDescriptor.getReadMethod();//从属性描述中获得字段的get方法 //通过getMethod.invoke(obj)方法获得obj对象中该字段get方法返回的值 if (!getMethod.invoke(obj1).equals(getMethod.invoke(obj2))) { return false; } } return true; }
Java版完整demo代码如下:
package com.company; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; import java.util.Scanner; public class CompareProperties { public static void main(String[] args) throws IllegalAccessException, IntrospectionException, InvocationTargetException { User user1 = new User(); user1.setAge(20); user1.setName("Young"); user1.setBirthday(new Date()); user1.setHeight(1.7); User user2 = new User(); user2.setAge(20); user2.setName("Young"); user2.setBirthday(new Date()); user2.setHeight(1.7); if (CompareProperties(user1, user2)) { System.out.println("对象属性值相同。"); } else { System.out.println("对象属性值不同!"); } Scanner in = new Scanner(System.in); String pause = in.nextLine(); } /** * 判断两个相同类型的对象的属性值是否相等 * @param obj1 * @param obj2 * @return * @throws IllegalAccessException * @throws IntrospectionException * @throws InvocationTargetException */ private static boolean CompareProperties(Object obj1, Object obj2) throws IllegalAccessException, IntrospectionException, InvocationTargetException { //为空判断 if (obj1 == null && obj2 == null) { return true; } else if (obj1 == null || obj2 == null) { return false; } Class<?> classType = obj1.getClass(); //如果传入的类型不一样则直接返回false //C#中通过CompareProperties<T>中的<T>可以限定传入的类型必须一致,所以不需要该判断 if (classType != obj2.getClass()) { return false; } Field[] fields = obj1.getClass().getDeclaredFields();//获得所有字段 for (Field field : fields) { PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), classType);//获得类中字段的属性描述 Method getMethod = propertyDescriptor.getReadMethod();//从属性描述中获得字段的get方法 //通过getMethod.invoke(obj)方法获得obj对象中该字段get方法返回的值 if (!getMethod.invoke(obj1).equals(getMethod.invoke(obj2))) { return false; } } return true; } } class User { //年龄 private int Age; //姓名 private String Name; //生日 private Date Birthday; //身高 private double Height; public int getAge() { return Age; } public void setAge(int age) { Age = age; } public String getName() { return Name; } public void setName(String name) { Name = name; } public Date getBirthday() { return Birthday; } public void setBirthday(Date birthday) { Birthday = birthday; } public double getHeight() { return Height; } public void setHeight(double height) { Height = height; } }
写下来最大的感触是:Java比C#繁琐了很多
** Then I looked up at the sky and saw the sun **
posted on 2018-06-14 16:22 chenyangsocool 阅读(2185) 评论(1) 编辑 收藏 举报