反射机制简单基础

前序

在我们没有学习框架之前我们都是通给new来创建对象,如:创建一个我们已知的对象

Car car=new Car();

调用类中的成员变量和成员方法都是对象直接调用。

在学习了mybatis框架后,我们了解到可以通过类名,能动态得到类中定义的信息,包括类中有哪些方法,有哪些属性等

比如在xml映射文件中:

<mapper namespace="com.ffyc.mybatispro.dao.AdminDao"></mapper>

通过这个我们就知道调用的这给类中的接口

以及

 <select id="findAdminByid" parameterType="int" resultType="Admin">
             select * from admin where id =#{id}
</select>

在这里mybatis框架中就会把查询到的数据映射到Admin这个类中,在这里我们就会产生一个疑惑为什么这样呢?

实际上市MyBatis在底层中实现了java反射机制。那什么是java反射机制,下面是一个简单的入门级的介绍。

反射机制概念

在运行状态中,在仅知道一给类名时,就可以动态获得类中信息,创建类对象,调用对象成员的机制就称为Java反射机制。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制

作用:动态获取类的信息

Class类

Java.lang.Class

Class类的对象,表示当前正在运行中的类和接口,Class类是实现java反射的基础

一旦class文件被加载到内存,就会为其创建一个Class对象。任意类使用都会创建Class对象

Java反射相关API

Java反射机制的相关类主要有:

Class类,Constructor类 获得构造方法,Method类 获得方法,Field类 获得属性

 获得Class对象

通过全类名获得Class对象(有三种方法)

String classname="com.ffyc.javaReflect.User";

方式一:通过Class类中的属性formname(String classname)(Class类的静态方法)

Class clazz=Class.forName(classname);

方式二:类名.class,适用于通过类名获得Class对象

//方式2
Class clazz2 = User.class;

方式三:Object类中的getClass方法:适用于通过对象获得Class实例的情况

//方式3
User user=new User();
Class clazz3 = user.getClass();

获得相应类的构造方法

有四种方式

Class aClass=Class.forName(classname);

通过Class类中的getConstructor()获得相应类的构造方法

//获得类的构造方法,通过构造方法api中的方法创建对象
  Constructor constructor1 = aClass.getConstructor();//获得指定的公共构造方法

String.class表示:参数是String类型(这里需要什么类型,转换成什么即可)

Constructor constructor2 = aClass.getConstructor(String.class,String.class);//获得有参构造方法

 getConstructors()获得所有公共的构造方法放到Constructor数组中

Constructor [] constructors=aClass.getConstructors();//获得所有公共的构造方法

getDeclaredConstructor()和getDeclaredConstructors()

//虽然可以获得私有构造方法,但是一般不建议操作私有成员,因为打破了封装性
aClass.getDeclaredConstructor();//获得类中任意构造方法,包括私有的
aClass.getDeclaredAnnotations();//获得类中所有构造方法,包括私有的

 获得相应类的方法

有四种方式

参数表示是类方法的名称

Method method = aClass.getMethod(String name)

 其它三个获取类方法的方式

//获得类中所有公共的成员方法,返回值是一个Method类数组
aClass.getMethods();
//获得类中的任意成员方法,包括私有的,返回值是一个Method类
aClass.getDeclaredMethod("eat");
//获得类中所有成员方法,包括私有的,返回值是一个Method类数组
aClass.getDeclaredMethods();

调用方法执行程序,这里的object表示要通过那个对象来调用这个方法

//调用方法使用invoke调用
method.invoke(object );

 获得类的成员变量

有四种方式

方式一

Field accountField= aClass.getField("account");//获得指定名称的公共成员变量

方式二

Field accountField= aClass.getDeclaredField("account");//获得指定名称的成员变量,包含私有的

方式三

Field[] fields= aClass.getDeclaredFields();//获得类中所有的成员变量,包含私有的

方法四

Field[] fields1=aClass.getFields();//获得类中所有公共的成员变量

如果想要操作私有变量,则需要setAccessible(true),改为false则程序报错

f.setAccessible(true);//允许访问操作私有变量

模拟在数据库查询到数据,赋值给对象

 //模拟数据库中查到的数据
 HashMap<String,String> map=new HashMap<>();
 map.put("account","admin");
 map.put("password","111");
Field[] fields= aClass.getDeclaredFields();//获得类中所有的成员变量,包含私有的
 for (Field f:fields){
     f.setAccessible(true);//允许访问操作私有变量
     f.set(object,map.get(f.getName()));
 }
 System.out.println(object);

结果:

为了能够更好的熟悉Java反射机制练习俩个实例

第一个,给私有成员变量赋值,不使用可以操作私有的属性的方法,

package com.ffyc.javaReflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

public class Test5 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

      

        //使用反射机制时,只知道类的名称(包名+类名)
        
        String classname="com.ffyc.javaReflect.Car";
        //1、通过类名获得类的Class对象
        Class aClass=Class.forName(classname);
        //通过类的Class对象来创建对象
        Object object = aClass.newInstance();
        //通过属性的set、get对私有属性赋值
        HashMap<String,String> map=new HashMap<>();
        map.put("name","奔驰");
        map.put("color","白色");
        //先拿到类中的所有私有属性
     Field[] fields= aClass.getDeclaredFields();
     for (Field field:fields){
         //根据属性名生成set方法名称
         String setMethod ="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
         System.out.println(setMethod);
         //通过class对象,获得对应的set方法对象
         Method setMethodObj =aClass.getMethod(setMethod,field.getType());
        //调用set方法
         setMethodObj.invoke(object,map.get(field.getName()));
     }
        System.out.println(object);



    }
}

第二个是自定义Java对象转为json工具

package com.ffyc.javaReflect;

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

public class ToJsonUtil {
    public static String toJson(Object object1) throws  IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class aClass=object1.getClass();
         String json="{";
        //获取类中的属性变量
                Field [] fields= aClass.getDeclaredFields();
                for (Field field:fields){
                    String getMethod="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
                    //拿到get方法
                         Method method = aClass.getMethod(getMethod);
                         //调用get方法
                 String value = (String) method.invoke(object1);
                 json+=field.getName()+":"+value+",";
                }
                json=json.substring(0,json.length()-1);
                json+="}";
        return json;
    }

    public static void main(String[] args) throws  NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        User user=new User();
        user.setAccount("admin");
        user.setPassword("111");
        Car car=new Car("奔驰","白色");
        System.out.println(toJson(user));
        System.out.println(toJson(car));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双非码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值