今天写代码的时候有这样一个需求:
需要验证两个相同类型的不同对象中的属性值是否相同。
传统方式是分别读取两个对象中的属性值,对其进行一一比对,不停if-else。
但是如果有上百个属性值难道你也要去读取上百次,然后写上百个if-else嘛?!
so……用反射吧!
利用语言的反射机制自动遍历对象中的所有属性字段以及属性值,并比较其是否相同。
先上C#的核心代码(emmm……对,后来我又写了个Java版代码)
////// 判断两个相同类型的对象的属性值是否相等/// ////// /// /// private static bool CompareProperties (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(); } ////// 判断两个相同类型的对象的属性值是否相等 /// ////// /// /// private static bool CompareProperties (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 { /// /// 年龄 /// public int Age { get; set; } ////// 姓名 /// public string Name { get; set; } ////// 生日 /// public DateTime BirthDay { get; set; } ////// 身高 /// 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中的 可以限定传入的类型必须一致,所以不需要该判断 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中的 可以限定传入的类型必须一致,所以不需要该判断 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#繁琐了很多