反射的基本介绍

反射?

如何使用Java类和对象?

​ 设计类----> 创建对象----> 使用对象调用方法或属性。

​ 反序列化

如果只知道类名,能否动态得到类的定义信息,包括那些属性,方法等。

​ 答:通过反射获得。

**反射:**在程序运行过程中,可以动态获取类的信息,以及创建类的对象,以及调用对象中的属性和方法。

**作用:**动态获取类的信息

**好处:**写一个方法,可以处理任何的类

类名,类在项目中的地址,通过地址找到类,就可动态获得类中信息。

自己的项目,在那使用,在哪new,会将代码写死,框架需要处理不同的类,都需要能够进行处理,mybatis框架可以写一个方法,接收一个类的地址,就可以根据地址创建该类的对象,

反射基本用法

如何动态类的信息

User.class --> User.class --> 一旦程序中使用User类,就会加载字节码文件,为该类创建一个Class对象,通过该类的Class类的对象,获得类中的信息。

获得Class类对象

    public static void main(String[] args) throws ClassNotFoundException {
     /*
        获得 类的Class对象
     */
        //1.通过对象名获取到类的Class对象
        User user=new User();
        Class c1=user.getClass();

        //2.通过类名.class获取到类的Class对象
        Class c2=User.class;



        //3.通过 Class.forName("类的地址")
        Class c3=Class.forName("com.ffyc.javareflect.User");

        System.out.println(c1==c2);//true
        System.out.println(c1==c3);//true
    }

获取构造方法

获得到Class对象后, 如何获得类的信息,获得那些信息

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        
        //类的地址
        //通过类的地址 加载类
        String name="com.ffyc.javareflect.User";
        Class c=Class.forName(name);

 //获得无参构造,获得公共权限的构造方法 
 //通过无参的构造方法,创建对象
        Constructor constructor=c.getConstructor();
        Object user=constructor.newInstance();
  
//获得有参构造
	  Constructor constructor1=c.getConstructor(int.class,String.class);
      Object user1=constructor1.newInstance(1,"jim");


       //获得私有的
                Constructor constructor2=c.getDeclaredConstructor();
        //设置对私有权限机型操作
        constructor2.setAccessible(true);
        Object car=constructor2.newInstance();
        System.out.println(car);


        car 无参构造
com.ffyc.javareflect.Car@1b6d3586


    }

获取属性


        String name="com.ffyc.javareflect.User";//类的地址
        Class c=Class.forName(name);//通过类的地址 加载类

        Constructor constructor = c.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object object=constructor.newInstance();

        /*
            获得类中的属性
            getFileld(name) 获得的是 指定名称 公共权限属性
            getFields() 获得所有 公共权限属性
            getDeclaredField(name) 获得指定名称 私有权限属性
            getDeclaredFields 获得所有 私有和公共

         */
        Field[] declaredFields = c.getDeclaredFields();//类中所有属性
        System.out.println(declaredFields.length);
        for(Field f:declaredFields){
            System.out.println(f.getName());
        }

        //模拟查询数据结果
        Map<String,Object> map=new HashMap<>();
        map.put("id",100);
        map.put("name","tom");

        for(Field f:declaredFields){
            //f.set(object,map.get(f.getName()));  键值
            f.setAccessible(true);
            f.set(object,map.get(f.getName()));
        }
        System.out.println(object);

    

获取成员方法

method.invoke(object,100);

相当于 object.setId(100)

     String name="com.ffyc.javareflect.User";//类的地址
        Class c=Class.forName(name);//通过类的地址 加载类

        Constructor constructor = c.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object object=constructor.newInstance();
        /*
            getMethods()获得类中所有公共的成员方法
            getMethod("getId",type) 获得共的 指定名称参数的成员方法
            getDeclaredMethods()  获得所有成员方法  包含私有
            getDeclaredMethod("getId",type) 指定名称参数的成员方法
         */
        Method method=c.getMethod("setId", int.class);
        method.invoke(object,100);
        System.out.println(object);

练习–将 object–>Json

public class Test5 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User user=new User(100,"王博");
        Car car=new Car(101,"wb");

        String u=objectToJson(user);
        String c=objectToJson(car);

        System.out.println(u);
        System.out.println(c);

    }
//我们选择用 属性名 进行改造的方式,拿到get方法再调用
    public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        String s="{";
        Class c=object.getClass();
        //获得所有属性
        Field[] declaredFields = c.getDeclaredFields();
        for(Field f:declaredFields){
            //f.getName() 获得属性名
            //c.getMethod 获得指定名称的get方法
            // invoke 调用 方法
            s+=f.getName()+":"+c.getMethod(check(f.getName())).invoke(object)+",";
        }
        s=s.substring(0,s.length()-1);
        s+="}";
        return s;
    }
// 将获取到的id  转为  getId 
    //fieldName.charAt(0) 获取第一个字母
    //toUpperCase() 将小写转为 大写
    //fieldName.substring(1);  截取字符串 从第 1 位截取到最后一位
    public static String check(String fieldName){
        String  methodName="get"+String.valueOf(fieldName.charAt(0)).toUpperCase()+fieldName.substring(1);
        return methodName;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值