反射机制

本文介绍了Java反射机制的概念,详细解释了如何通过四种不同方式获取Class对象,并通过代码示例展示了如何利用反射来操作类的方法和字段。

1、介绍

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

 

2、获取 Class 对象的四种方式

如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。Java 提供了四种方式获取 Class 对象:

1.知道具体类的情况下可以使用:

Class alunbarClass = TargetObject.class;

但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取Class对象不会进行初始化

2.通过 Class.forName()传入类的路径获取:

Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");

Class.forName(className)方法,内部实际调用的是一个native方法 forName0(className, true, ClassLoader.getClassLoader(caller), caller);

第2个boolean参数表示类是否需要初始化,Class.forName(className)默认是需要初始化。

一旦初始化,就会触发目标对象的 static块代码执行,static参数也会被再次初始化。

3.通过对象实例instance.getClass()获取:

Employee e = new Employee();
Class alunbarClass2 = e.getClass();

4.通过类加载器xxxClassLoader.loadClass()传入类路径获取

ClassLoader

通过类加载器获取Class对象不会进行初始化,意味着不进行包括初始化等一些列步骤,静态块和静态对象不会得到执行

代码实例

简单用代码演示一下反射的一些操作!

1.创建一个我们要使用反射操作的类 TargetObject

package cn.javaguide;
package cn.javaguide;

public class TargetObject {
    private String value;

    //非静态代码块
    {
        System.out.print("非静态代码块!--");
    }

    //静态代码块
    static {
        System.out.print("静态代码块!--");
    }

    public TargetObject() {
        value = "Java";
        System.out.println("TargetObject constructor");
    }
    public void publicMethod(String s) {
        System.out.println("I love " + s);
    }

    private void privateMethod() {
        System.out.println("value is " + value);
    }
}

2.使用反射操作这个类的方法以及参数

package cn.javaguide;

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


public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
        //类.class方式获取反射,此方式获取Class对象不会进行初始化
//        Class targetClass = TargetObject.class;
//        TargetObject targetObject = (TargetObject) targetClass.newInstance();

        /**
         * Class.forName(className)方法,内部实际调用的是一个native方法 forName0(className, true, ClassLoader.getClassLoader(caller), caller);
         * 第2个boolean参数表示类是否需要初始化,Class.forName(className)默认是需要初始化。
         * 一旦初始化,就会触发目标对象的 static块代码执行,static参数也会被再次初始化。
         */
        Class<?> targetClass = Class.forName("cn.javaguide.TargetObject");
        TargetObject targetObject = (TargetObject) targetClass.newInstance();

        //通过对象实例获取
//        TargetObject t = new TargetObject();
//        Class targetClass = t.getClass();

        //通过类加载器XXXClassLoader.loadClass()传入类路径获取
//        通过类加载器获取Class对象不会进行初始化,意味着不进行包括初始化等一些列步骤,静态块和静态对象不会得到执行
//        ClassLoader

//        获取类中所有定义的方法
        Method[] methods = targetClass.getDeclaredMethods();
        for(Method method: methods) {
            System.out.println(method.getName());
        }
//        获取类中制定方法并调用
        Method publicMethod = targetClass.getDeclaredMethod("publicMethod", String.class);
        publicMethod.invoke(targetObject, "C语言");

        //获取指定参数并对参数进行修改
        Field field = targetClass.getDeclaredField("value");
        //为了对类中的参数进行修改,取消安全检查
        field.setAccessible(true);
        field.set(targetObject, "C++");

        //调用private方法
        Method privateMethod = targetClass.getDeclaredMethod("privateMethod");
        //为了调用private方法,取消安全检查
        privateMethod.setAccessible(true);
        privateMethod.invoke(targetObject);
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值