精华内容
下载资源
问答
  • 因为此时对象已经被实例化,所以在项目中通常会用反射获取Field从而判断该属性值是否为null,也就是常说的判断对象中所有属性为null,本文讲讲我在项目中利用反射来判断遇到的问题和一些坑 编写工具类解决...

    前言

    • java中当对象需要判空的时候,大体都会直接 if(Object != null) ,而当我们的对象是 new Object()的时候,往往这种判断不会起作用
      因为此时对象已经被实例化,所以在项目中通常会用反射获取Field从而判断该属性值是否为null,也就是常说的判断对象中所有属性不为null,本文讲讲我在项目中利用反射来判断遇到的问题和一些坑

    编写工具类解决我们的问题

    • 废话不说,上代码
    	/**
         * description:定义一个System.out.println的开(纯属个人习惯)
         **/
    	private static int objectNullSystemOutFlag = 0;
    	
    	/**
         * description:判断当前对象是否为空(包括所有属性为空)
         *
         * @author ZhangXihui
         * @param object 入参类
         * @return boolean
         * @create 2019/6/3 17:34
         **/
        public static boolean objCheckIsNull(Object object) {
        	if (object == null) {
                return true;
            }
            // 得到类对象
            Class clazz = object.getClass();
            // 得到所有属性
            Field[] fields = clazz.getDeclaredFields();
            //定义返回结果,默认为true
            boolean flag = true;
            for (Field field : fields) {
            	//设置权限(很重要,否则获取不到private的属性,不了解的同学补习一下反射知识)
                field.setAccessible(true);
                Object fieldValue = null;
                String fieldName = null;
                try {
                    //得到属性值
                    fieldValue = field.get(object);
                    //得到属性类型
                    Type fieldType = field.getGenericType();
                    //得到属性名
                    fieldName = field.getName();
                    //打印输出(调试用可忽略)
                    if (objectNullSystemOutFlag == 1) {
                        System.out.println("属性类型:" + fieldType + ",属性名:" + fieldName + ",属性值:" + fieldValue);
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                //只要有一个属性值不为null 就返回false 表示对象不为null
                if (fieldValue != null) {
                    flag = false;
                    break;
                }
            }
            return flag;
        }
    
    • 简单的写一个main,我们开始测试
    	public static void main(String[] args) {
            @ToString
            class User {
                private String username;
                private String password;
    
                public User() {
                }
    
                public User(String username, String password) {
                    this.username = username;
                    this.password = password;
                }
            }
            User user = new User();
            System.out.println(user);
            //正常判断
            System.out.println(user == null);
            //使用反射的工具类
            System.out.println( CommonFunction.objCheckIsNull(user));
        }
    
    • 输出结果

    User(username=null, password=null)
    false
    true

    • 可见我们的工具类是好用的,但是在使用中会遇到一些问题,接下来说说我项目中遇到的问题和解决方法

    问题与解决

    • 场景一:在web开发中,实体类我们经常会进行序列化, implements Serializable 并为其添加一个 serialVersionUID
    		@ToString
            class User implements Serializable {
                private static final long serialVersionUID = 1996598449318251880L;
                private String username;
                private String password;
    
                public User() {
                }
    
                public User(String username, String password) {
                    this.username = username;
                    this.password = password;
                }
            }
    
    • 产生问题:可以看到 serialVersionUID 是作为类中的一个属性,而最开始构建的工具类没有考虑到serialVersionUID 的存在
      这样会导致其返回结果一直为false,这也是一开始困扰我的原因,当我们专注于某一件事的时候,往往会忽略一些事情。

    • 解决:在判断条件中忽略序列化字段名

    			//只要有一个属性值不为null 就返回false 表示对象不为null 忽略序列化
                if (fieldValue != null && !"serialVersionUID".equals(fieldName)) {
                    flag = false;
                    break;
                }
    
    • 场景二:

    • 业务需求场景:有一入参实体类,该实体类有30个属性,其中有2个属性会在程序中赋予默认值为10,这样就导致该类有28个为null的属性和2个为10的属性,业务判断为除了默认值的两个属性之外如果所有属性为null,那么我们就认为这个入参实体类什么也没接到,也就认为它为"空"

    • 那么问题来了,难道我们要去挨个判断剩余的28个字段为空么?很显然不是的,根据上面我们从属性判断中剔除 serialVersionUID 的思路出发,我们会发现,业务中会经常出现,我们希望判断某一实体类中,除了某些属性或者某些值之外的属性为null的情况,也就是我们判空的时候希望剔除掉某些属性或者某些值,so,基于这些场景我改造了工具类,使其能够实现我们的思路

    	/**
         * description:判断当前对象是否为空(包括所有属性为空)
         * 可选则在判断规则中剔除某一字段,或者某一值
         *
         * @author ZhangXihui
         * @param object 入参对象
         * @param excludeNameList 要剔除的属性名称,没有就传空集合或者null
         * @param excludeValueList 要剔除的数值,没有就传空集合或者null
         * @return boolean
         * @create 2019/6/3 17:34
         **/
        public static boolean objCheckIsNull(Object object, List<String> excludeNameList, List<Object> excludeValueList) {
            if (object == null) {
                return true;
            }
            // 得到类对象
            Class clazz = object.getClass();
            // 得到所有属性
            Field[] fields = clazz.getDeclaredFields();
            //判断入参
            boolean excludeNameListFlag = false;
            if (excludeNameList != null && excludeNameList.size() > 0) {
                excludeNameListFlag = true;
            }
            boolean excludeValueListFlag = false;
            if (excludeValueList != null && excludeValueList.size() > 0) {
                excludeValueListFlag = true;
            }
            //定义返回结果,默认为true
            boolean flag = true;
            for (Field field : fields) {
                field.setAccessible(true);
                Object fieldValue = null;
                String fieldName = null;
                try {
                    //得到属性值
                    fieldValue = field.get(object);
                    //得到属性类型
                    Type fieldType = field.getGenericType();
                    //得到属性名
                    fieldName = field.getName();
                    //剔除指定属性名的属性值
                    if (excludeNameListFlag) {
                        for (String s : excludeNameList) {
                            if (fieldName.equals(s)) {
                                fieldValue = null;
                                break;
                            }
                        }
                    }
                    //剔除指定属性值
                    if (excludeValueListFlag) {
                        for (Object obj : excludeValueList) {
                            if (obj.equals(fieldValue)) {
                                fieldValue = null;
                                break;
                            }
                        }
                    }
                    //打印输出(调试用可忽略)
                    if (objectNullSystemOutFlag == 1) {
                        System.out.println("属性类型:" + fieldType + ",属性名:" + fieldName + ",属性值:" + fieldValue);
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                //只要有一个属性值不为null 就返回false 表示对象不为null 忽略序列化
                if (fieldValue != null && !"serialVersionUID".equals(fieldName)) {
                    flag = false;
                    break;
                }
            }
            //打印输出(调试用可忽略)
            if (objectNullSystemOutFlag == 1) {
                System.out.println("忽略属性: " + excludeNameList + " 忽略值: " + excludeValueList);
            }
            return flag;
        }
    
    • 测试一下
    public static void main(String[] args) {
            @ToString
            class User implements Serializable {
                private static final long serialVersionUID = 1996598449318251880L;
                private String username;
                private String password;
                private String sex;
                private String childSex;
                public User() {
                }
                public User(String sex, String childSex) {
                    this.sex = sex;
                    this.childSex = childSex;
                }
            }
            User user = new User("男性","男性");
            System.out.println(user);
            //使用基础的反射工具类
            System.out.println( CommonFunction.objCheckIsNull(user));
            //在判断中剔除 value 为男性的属性
            System.out.println( CommonFunction.objCheckIsNull(user,null, Collections.singletonList("男性")));
            //在判断中剔除 属性名 为 sex,childSex 的属性
            System.out.println( CommonFunction.objCheckIsNull(user,Arrays.asList("sex","childSex"),null));
        }
    
    • 结果

    User(username=null, password=null, sex=男性, childSex=男性)
    false
    true
    true

    • OK 大功告成!
      在这里插入图片描述
    展开全文
  • 1、java利用反射机制判断对象属性是否空:Map validateMap = new LinkedHashMap();validateMap.put("serial", "编号");validateMap.put("major", "专业");public static String validateFiledIsNull(Map fileds,...

    1、java利用反射机制判断对象的属性是否为空:

    Map validateMap = new LinkedHashMap();

    validateMap.put("serial", "编号");

    validateMap.put("major", "专业");

    public static String validateFiledIsNull(Map fileds,T obj) throws Exception{

    String ret ="";

    for(String key:fileds.keySet()){

    String getMethodStr = "get" + key.substring(0,1).toUpperCase()+key.substring(1);

    Method m = obj.getClass().getMethod(getMethodStr);

    Object value = m.invoke(obj);

    if(value==null || value.toString().trim().equals("")){

    if(!validateString(ret)){

    ret=fileds.get(key);

    }else{

    ret+=","+fileds.get(key);

    }

    }

    }

    return ret;

    }

    2、获取该属性的值:

    protected void setData(){

    //保存通过setAttr方法存储的数据

    Enumeration attrs = getAttrNames();

    ArrayList a = Collections.list(attrs);

    a.removeAll(Constants.exceptAttrs);//去除无关的数据

    for(String attrName : a){

    dataMap.put(attrName, getAttr(attrName));

    }

    //保存AppBaseController的protected属性的数据

    Field[] fields = AppBaseController.class.getDeclaredFields();

    for(Field field : fields){

    //设置对象的访问权限,保证对private的属性的访问

    // field.setAccessible(true);

    if(Modifier.PROTECTED == field.getModifiers()){

    try {

    Object value = field.get(this);

    if(value != null){

    setAttr(field.getName(), value);

    dataMap.put(field.getName(), value);

    }

    } catch (IllegalAccessException e) {

    e.printStackTrace();

    }

    }

    }

    }

    3、 设置该属性的值:

    protected void setParams(){

    Enumeration paraNames = getParaNames();

    ArrayList a = Collections.list(paraNames);//参数名列表

    Field[] fields = AppBaseController.class.getDeclaredFields();//AppBaseController属性列表

    for(Field field : fields){

    field.setAccessible(true);//Modifier.PROTECTED == field.getModifiers();

    if("java.lang.String".equals(field.getType().getName())){//String类型的属性

    for(String paraName : a){

    String value = getPara(paraName);

    String paraLowerName = paraName.replaceAll("_", "").toLowerCase();

    if(paraLowerName.equals(field.getName().toLowerCase())){//如果参数名有对应的属性名则赋值

    try {

    field.set(this, value);

    } catch (IllegalAccessException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    }

    展开全文
  • 通过反射的方式获取对象,然后如果对象属性为String的,如果为null则转为空字符串。可以根据需要根据不同的属性类型则赋予不同的值。 public static Object checkNull(Object obj) { Class&lt;? extends ...

    通过反射的方式获取到对象,然后如果对象的属性为String的,如果为null则转为空字符串。

    可以根据需要根据不同的属性类型则赋予不同的值。

        public static Object checkNull(Object obj) {
            Class<? extends Object> clazz = obj.getClass();
            // 获取实体类的所有属性,返回Field数组
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                // 可访问私有变量
                field.setAccessible(true);
                // 获取属性类型
                String type = field.getGenericType().toString();
                // 如果type是类类型,则前面包含"class ",后面跟类名
                if ("class java.lang.String".equals(type)) {
                    // 将属性的首字母大写
                    String methodName = field.getName().replaceFirst(field.getName().substring(0, 1),
                            field.getName().substring(0, 1).toUpperCase());
                    System.out.println(methodName);
                    try {
                        Method methodGet = clazz.getMethod("get" + methodName);
                        // 调用getter方法获取属性值
                        String str = (String) methodGet.invoke(obj);
                        if (StringUtils.isBlank(str)) {
                            // Method methodSet = clazz.getMethod("set" +
                            // methodName, new Class[] { String.class });
                            // methodSet.invoke(o, new Object[] { "" });
                            System.out.println(field.getType()); // class java.lang.String
                            // 如果为null的String类型的属性则重新复制为空字符串
                            field.set(obj, field.getType().getConstructor(field.getType()).newInstance(""));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return obj;
        }
    展开全文
  • 在ACTION中想通过反射获取struts自动填充对象属性和值,什么获取的和预期不一样 这是我的action: ![action](https://img-ask.csdn.net/upload/201703/20/1489999080_928498.png) 这是方法调用: ![方法调用]...
  • 但是获取的button为null,但是可以获取public的属性信息。代码如下: var _PurviewButtons:Boolean = true; try { trace("实例化:"+item.@type); var _PurviewRefrence:Class = getDefinitionByName(item.@type...
  • JAVA中的反射获取属性的get方法

    万次阅读 2015-07-15 01:30:30
    JAVA中的反射获取属性的get方法在开发过程中,我们经常需要获取类中某些属性的get方法,此时我们需要使用到反射,例如,我们在获得一个对象后,需要知道该对象的哪些属性有值,哪些没有值,方便我们后面的处理。...

    JAVA中的反射只获取属性的get方法

    在开发过程中,我们经常需要获取类中某些属性的get方法,此时我们需要使用到反射,例如,我们在获得一个对象后,需要知道该对象的哪些属性有值,哪些没有值,方便我们后面的处理。

    譬如在我们拼SQL语句时,就需要知道哪些字段为空或为NULL,此时我们在拼语句的时候需要剔除掉,若是我们采用一般的判断的办法,则会很复杂(需要处理好SQL中的AND关键字的有无 ),当然,我们也有另外的解决办法(例如将非空的键和值存入map中,再将map存入list集合中,然后循环集合做相应的处理),此处我们通过反射来处理。

    Person类

    package com.test;
    
    public class Person {
    
        private int id;
        private String name;
        private String empno;
        private String department;
        private String mobile;
        private String email;
        private String position;
        private int currentPage;
    
    
        public Person() {
            super();
        }
    
        public Person(String name, String empno, String mobile) {
            super();
            this.name = name;
            this.empno = empno;
            this.mobile = mobile;
        }
    
        public Person(int id, String name, String empno, String department,
                String mobile, String email, String position, int currentPage) {
            super();
            this.id = id;
            this.name = name;
            this.empno = empno;
            this.department = department;
            this.mobile = mobile;
            this.email = email;
            this.position = position;
            this.currentPage = currentPage;
        }
    
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getEmpno() {
            return empno;
        }
        public void setEmpno(String empno) {
            this.empno = empno;
        }
        public String getDepartment() {
            return department;
        }
        public void setDepartment(String department) {
            this.department = department;
        }
        public String getMobile() {
            return mobile;
        }
        public void setMobile(String mobile) {
            this.mobile = mobile;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        public String getPosition() {
            return position;
        }
        public void setPosition(String position) {
            this.position = position;
        }
        public int getCurrentPage() {
            return currentPage;
        }
        public void setCurrentPage(int currentPage) {
            this.currentPage = currentPage;
        }
    }
    

    FirstAction类:

    package com.test;
    
    import java.beans.IntrospectionException;
    import java.beans.PropertyDescriptor;
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class FirstAction {
    
        public static void main(String[] args) throws UnsupportedEncodingException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException, NoSuchFieldException, SecurityException {
            Person person=new Person("siege","0001","18516100***");
            Class<?> clazz=person.getClass();
    
            Field field1=clazz.getDeclaredField("name");
            Field field2=clazz.getDeclaredField("empno");
            Field field3=clazz.getDeclaredField("department");
            Field field4=clazz.getDeclaredField("position");
            Field[] fields=new Field[]{field1,field2,field3,field4};
            Method[] methods=clazz.getMethods();
            int length=fields.length;
            for(int i=0;i<length;i++){  
                PropertyDescriptor pd=new PropertyDescriptor(fields[i].getName(),clazz);
                Method getMethod=pd.getReadMethod();
                if(getMethod.invoke(person)!=null){
                    System.out.println(fields[i].getName()+"----"+getMethod.invoke(person));
                }
            }
        }
    }
    

    我们通过PropertyDescriptor 来获取get方法。

    结果如下:

    name—-siege
    empno—-0001

    展开全文
  • 反射遍历所有属性,包括父类

    千次阅读 2017-08-15 08:55:44
    今天做了项目的时候,反射获取对象信息然后保存进入redis里面的时候,出现了问题,因为 Field[] fields = classType.getDeclaredFields();只获取当前类所有的属性如果要获取父类的属性,然后又不想获取根类Object的...
  • 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。2、问题:在项目中打算做一个通用的导出方法,但是这个方法是写在一个普通的工具类中的,这个工具类中我们通过使用反射的方法去调用其他的...
  • 在项目中打算做一个通用的导出方法,但是这个方法是写在一个普通的工具类中的,这个工具类中我们通过使用反射的方法去调用其他的service层,通过service层插入数据库实体对象,但是serviceImpl中的dao接口对象空...
  • 如这个问题:我需要将一个对象的所有字段不管是为空或为null都归类为未知: 代码如下: <T> T checkNull(T vo) throws Exception { // 获取实体类的所有属性,返回Field数组 Field[] field = vo.getClas...
  • 反射

    2018-08-01 17:33:18
    Class类 Class类用来描述某个类的属性、方法、构造函数、实现的接口。Class类的对象由系统产生,一个类在...三种获取Class对象的方式 Class clazz = null; Class = Person.class;//类名.class Object obj = ...
  • 原因使用Controller的...搜索一番,找到一个不错的思路:利用反射获取所有字段,再判断内容是否为null。初步代码如下/*** 注意,如果order是null,也返回true。**@paramorder*@return*/private booleanisOrderAll...
  • 首先当然是通过GetType()方法反射获取其类型信息,然后对其进行分析,但是类型信息Type中并没有简单地给出这么一个属性进行判断。 老外给出的方法是: 代码如下:public static bool IsNumeric(this Type dataType) ...
  • 首先当然是通过GetType()方法反射获取其类型信息,然后对其进行分析,但是类型信息Type中并没有简单地给出这么一个属性进行判断。 老外给出的方法是: public static bool IsNumeric(this Type dataType) { ...
  • 原因 使用Controller的形参及...搜索一番,找到一个不错的思路:利用反射获取所有字段,再判断内容是否为null。 初步代码如下 /** * 注意,如果order是null,也返回true。 * * @param order * @retur...
  • 如何一个对象赋默认值

    千次阅读 2015-03-24 15:59:19
    背景:在写手机接口的时候,由于传递的某些不重要的字段为null,所以导致手机...在一个基类中的构造函数进行反射获取继承的子类的所有的属性,判断属性的类型是String类型的就可以对其赋值。 class Base {
  • 1,反射机制 答:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的... key与value可以为null,但是key只能有一个为null,值可以多个为null 2),H
  • xml与反射.txt

    2020-08-05 14:39:17
    定来获取对象。 第三:通过clazz获得构造函数:Constructors cons=clazz.getDeclaraedConstructors(Class[]null);//调 用默认的构造函数 第四:然后通过构造函数构造对象:Car car=(Car)cons.newInstance();//获取类...
  • }//数据绑定的时候,只认"属性"不认"字段",内部通过反射来实现 this.dataGridView1.DataSource =list;//数据绑定 } //增加一条数据 private void button1_Click(object sender, EventArgs e) { //采集用户的...
  • 并且希望每次只添加新类,但不修改原有的代码,所以想通过反射获取责任链中的每一个环节的对象,但是因为是通过@Resource注解自动装配的,所以newInstance导致里边自动装配的属性全都为null,最后找到方法要通过...
  • 定义要返回的DataTable对象 DataTable dtReturn = new DataTable(); 保存列集合的属性信息数组 ...使用反射获取T类型的属性信息,返回一个 PropertyInfo 类型的集合 if (oProps == null) { oProps = (...
  •  16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...
  •  16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...
  •  16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...
  •  16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...
  • C# 动态数据类型处理

    2020-07-25 12:47:20
    通过反射获取对象后动态对属性赋值,由于字段不同的数据类型,所以要根据字段的类型进行赋值。 //方法1.网上常见的根据datatype写很多ifelse的 //方法2 利用Convert.ChangeType方法,根据当前字段的数据类型动态...
  • 62、反射相关 63、正则表达式相关 64、资源操作相关 65、四舍五入相关 66、SD卡相关 67、服务相关 68、Shell相关 69、短信相关 70、Snackbar相关 71、SharedPreferences相关 72、状态栏背景色 73、状态栏字体颜色...

空空如也

空空如也

1 2 3
收藏数 59
精华内容 23
关键字:

反射获取对象属性为null