Java反射机制

引入

在之前使用Java时,会先定义一个类,在使用new关键字创建该类的对象,使用对象来调用类中的成员,这属于正向使用,这种方式往往会将代码写死,那有没有一种方式可以仅仅只通过类名来获取类的信息呢?这可以通过反射做到。

什么是反射?

反射就是仅仅只知道类的地址(全类名),就需要在运行时,可以动态的获取到类的信息,可以创建类的对象,调用任意的方法,属性等这种动态获取类信息的功能。

反射案例

1.在给servlet类配置供前端使用的映射地址;

<servlet>
        <servlet-name>testServlet</servlet-name>
        <!--配置servlet类的地址,在第一次或启动服务器时,由服务器通过反射机制创建此servlet对象-->
        <servlet-class>com.ffyc.webback.servlet.TestServlet</servlet-class>
</servlet>

2.mybatis框架配置中的resultType属性;

<select id="findAdminById" parameterType="int" resultType="com.ffyc.mybatispro.model.Admin">
        select id,account,password from admin where id=#{id}
</select>

3.加载MySQL驱动类;

Class.forName("com.mysql.cj.jdbc.Driver");//动态加载Driver类

反射API

Java反射相关的类主要包括:
● java.lang.Class;
● java.lang.reflect.Constructor;
● java.lang.reflect.Method;
● java.lang.reflect.Field;

1.Class类
一旦一个类被加载到内存中,都会为该类创建一个对象,可以通过该对象获取类中的信息。任何一个类被使用时都会创建一个Class对象,Class对象只有一个。
反射的起点就是要获得类的Class对象,通过Class对象获取类的信息。

获取Class对象的三种方法:
①Object类中的getClass()方法:适用于通过对象获取Class实例的情况
②类名.class:适用于通过类名获取Class实例的情况
③Class类的静态方法 forName(String name)

Class c1=new 类名().getClass();
Class c2= 类名.class;
Class c3=Class.forName(类名);

2.Constructor类
获取Constructor类的实例:

//获取Class对象
Class c=Class.forName(类名);

//根据Class对象获取类中公共的指定的构造方法
Constructor constructor=c.getConstructor();//获取无参的构造方法
Constructor constructor=c.getConstructor(参数类型.class...);//获取有参的构造方法

//获取类中指定的构造方法(包括私有的)
Constructor constructor=c.getDeclaredConstructor(参数类型.class...);
constructor.setAccessible(true);//设置访问私有成员的权限

//获取类中所有的构造方法
Constructor[] constructors = c.getConstructors();

Constructor类可以通过get一系列方法(getName() 返回构造方法的名字)获得构造方法的基本信息。

Class类和Constructor类还可以创建实例。

//Class类创建实例:
//获取Class对象
Class c=Class.forName(类名);
//使用newInstance()方法创建实例
Object obj=c.newInstance();


//Constructor类创建实例:
//获取Class对象
Class c=Class.forName(类名);
//根据Class对象获取类中的构造方法
Constructor constructor=c.getConstructor();
//通过构造方法创建实例
Object obj=constructor.newInstance();

3.Field类
Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值。
获得Field类的实例:

//获取Class对象
Class c=Class.forName(类名);
//通过Class类的对象获取类中所有的属性
Field[] Fields = c.getDeclaredFields();

4.Method类
Method类将类中的方法进行封装,可以动态获得方法的信息。
获得Method类的实例:

//获取Class对象
Class c=Class.forName(类名);
Object obj=c.newInstance();
//获取类中的所有方法
Method[] methods=c.getMethods();
//获取类中所有的属性
Field[] Fields = c.getDeclaredFields();
for(Field f:Fields){
//通过指定方法名,参数类型,返回一个Method实例
Method m=c.getMethod("set"+f.getName().substring(0,1).toUpperCase()+f.getName().substring(1),f.getType());
//动态调用obj对象的具体方法
m.invoke(obj,"...");

反射优缺点

优点:
①增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作;
②提高代码的复用率,比如动态代理;
③可以在运行时轻松获取任何一个类的方法,属性,并且还能通过反射进行动态调用。
缺点:
①反射会涉及到动态类型的解析,导致性能要比非反射调用更低;
②使用反射技术通常要在一个没有安全限制的程序运行;
③反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值