經過反射比較兩個相同類型的對象中的值是否相同

今天寫代碼的時候有這樣一個需求: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#繁瑣了不少

相關文章
相關標籤/搜索