zoukankan      html  css  js  c++  java
  • 通过反射比较两个相同类型的对象中的值是否相同

    今天写代码的时候有这样一个需求:

    需要验证两个相同类型的不同对象中的属性值是否相同。

    传统方式是分别读取两个对象中的属性值,对其进行一一比对,不停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#繁琐了很多

  • 相关阅读:
    react Native 运行报错之一 gradle-2.14.1-all解压失败的问题
    react native windows create bundle folder
    gulp+browserSync+nodemon 实现express 全端自动刷新的实践
    nodejs框架express4.x 学习--安装篇
    转: angularjs 指令中动态编译的方法(适用于有异步请求的情况) 内嵌指令无效
    angular 基础练习
    自己写的数组排重+排序
    前端开发bower包管理器
    定位网站性能的一些经验
    记一次大规模数据迁移和加密
  • 原文地址:https://www.cnblogs.com/chenyangsocool/p/9183617.html
Copyright © 2011-2022 走看看