JAVA基础--Class反射的简单应用(2)

上章了解了Class的做用,那么,此次咱们来看看反射究竟是怎么回事:java

package reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


/**
 *@description TODO 反射测试类
 *@date  2018年1月1日
 *@author  geYang
 **/
public class ClassTest2 {
    /**
     * 反射赋值: 
     *   Java反射机制是在运行状态中,对于任意一个类,都可以知道这一个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法和属性;
     * 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;
     * 
     * @throws Exception 
     **/
    public static void main(String[] args) throws Exception {
        //1,获取类:
        Class<?> clazz = Class.forName("entity.Person");
        System.out.println("类:"+clazz);
        
        //2,获取Person类的默认构造器:
        Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{});
        System.out.println("默认构造器:"+constructor);
        
        //3,利用默认构造器获取对象:
        Object object = constructor.newInstance(new Object[]{});
        System.out.println("对象:"+object);
        
        //4,获取类下的全部方法:
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods){
            //获取方法名:
            String methodName = method.getName();
            //判断是否为以set开头的方法:
            if(methodName.startsWith("set")){
                //经过截取字符传的方式来拿到属性名:
                String fieldName = methodName.substring(3);
                fieldName = fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1);
                //得到属性:
                Field field = clazz.getDeclaredField(fieldName);
                //得到属性的具体类型:
                Class<?> type = field.getType();
                //若是类型为int类型:
                if(type==int.class){
                    //反射调用set方法
                    method.invoke(object, new Object[]{18});
                }
                if(type==String.class){
                    if("name".equals(fieldName)){
                        method.invoke(object, new Object[]{"张三"});
                    }
                    if("address".equals(fieldName)){
                        method.invoke(object, new Object[]{"绵阳"});
                    }
                }
            }
        }
        System.out.println("对象:"+object);
        
        /**
         * Method 反射调用自身:
         *  method.invoke(object, new Object[]{"张三"});
         *  对带有指定参数的指定对象调用,由此Method对象表示底层方法.
         *  注: 1:若是底层方法是实例方法,第一个参数就是该对象的实例,第二个参数就是方法的参数列表,invoke的返回值就是实例方法的返回值;
         *  2: 若是底层方法是静态方法,那么能够忽略实例参数,该参数可为null;
         *  3: 若是底层方法所需的形参数为0(无参),则参数列表可为  null<===>new Object[]{}(推荐使用new Object[]{});
         *  例:
         * */
        Method method = clazz.getDeclaredMethod("printInfo", new Class[]{});
        //静态方法,实例可为null;无参,参数可为null;
        Object invoke = method.invoke(null, new Object[]{});
        System.out.println(invoke);
        
        /**
         * 暴力反射
         * */
        Field field = clazz.getDeclaredField("name");
        //破坏属性私有化
        field.setAccessible(true);
        field.set(object, "李四");
        System.out.println(object);
    }
    
}

初次听到反射,咱们都会以为比较深奥,其实用法就是这么简单,但至于怎么用就要看各自功力的深厚啦;测试

参考: https://ke.qq.com/course/180327flex

相关文章
相关标签/搜索