今天寫代碼的時候有這樣一個需求:java
須要驗證兩個相同類型的不一樣對象中的屬性值是否相同。spa
傳統方式是分別讀取兩個對象中的屬性值,對其進行一一比對,不停if-else。code
可是若是有上百個屬性值難道你也要去讀取上百次,而後寫上百個if-else嘛?!對象
so……用反射吧!blog
利用語言的反射機制自動遍歷對象中的全部屬性字段以及屬性值,並比較其是否相同。ip
先上C#的核心代碼(emmm……對,後來我又寫了個Java版代碼)ci
/// <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代碼以下:get
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版本的核心代碼:string
/** * 判斷兩個相同類型的對象的屬性值是否相等 * @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代碼以下:it
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#繁瑣了不少