对于反射机制原理的理解

反射: 动态获取一个类的字节码文件对象 从而获取到对象中的所有的内容(字段 函数 构造函数等)
1)获取字节码文件对象 Class
2)通过Class对类进行描述

1.准备好一个实体类

public class Person {
    private String name;
    private int age;

    public void print(){
        System.out.println(name+"---------"+age);
    }

    public void fun(int num,String str){
        System.out.println("num="+num+",str="+str);
    }

    public static void staticFun(){
        System.out.println("staticFun run");
    }

    private void show(){
        System.out.println("show run");
    }
}

2.获取字节码文件对象的方式(三种,后两种较为常见)


     // 1.通过对象的getClass()方法获取

    public static void getClassObject01(){
        Person p=new Person();
        Class clazz=p.getClass();
        Person p1=new Person();
        Class clazz1=p1.getClass();
        System.out.println(clazz==clazz1);//true
    }

    // 2.通过数据类型的class属性获取该类型的字节码文件对象

    public static void getClassObject02(){
        Class clazz=Person.class;
        System.out.println(clazz.getName());
    }

     // 使用Class类中的方法获取  forName(className)
     // 不需要明确具体的类或者是对象 只需要类的包名加类名即可

    public static void getClassObject03(){
        try {
            Clas clazz=Class.forName("com.yztc.bean.Person");
            System.out.println(clazz.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3.通过字节码文件对象对类进行描述

    // 1. 动态获取指定的字节码文件对象中的内容
    //    字节码文件中的方法

    public static void getFuncation(){
        //1)获取字节码文件对象
        Class clazz=Person.class;
        //2)调用Class类中的方法获取字节码文件对象中的所有的函数
        //注意:getMethods()获取类中的公有方法 ;包括父类中的函数
        Method[] meshods=clazz.getMethods();
        //获取类中所有的方法 包含私有 但是不包含继承父类的
        meshods=clazz.getDeclaredMethods();
        //3)遍历
         for(Method method:meshods){
             System.out.println(method);
         }
    }

//-----------------------------------------
//2. 获取类中的单个无参数方法

    public static void getSingleFuncation(){
        Class clazz=Person.class;
        try {
            Method method=clazz.getMethod("print", null);//访问person类中无参数的print()方法
            //调用字节码文件对象中的newInstance获取指定的字节码文件对象的实例
            Object obj=clazz.newInstance();
            method.invoke(obj, null);//调用person字节码文件对象实例中的print方法  new person().show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//-----------------------------------------

//3.获取类中带参数的方法以及静态方法

    public static void getParmasFuncation(){
         Class clazz=Person.class;
         try {
            Method method=clazz.getMethod("fun",int .class ,String.class);
            Object obj=clazz.newInstance();
            method.invoke(obj, 10,"ok");//new Person().fun(100,"哈哈哈哈哈哈哈哈")
            //调用静态函数
            Method method2=clazz.getMethod(" staticFun" , null);
            method2.invoke(null, null);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

 //-----------------------------------------
 //4.获取类中私有方法

    public static void getPrivateFuncation(){
        Class clazz=Person.class;
        try {
            Method method=clazz.getDeclaredMethod( "show",  null);
            //访问私有方法存在异常 如果想要访问  暴力访问 将私有的权限取消掉
            method.setAccessible(true);
            Object obj=clazz.newInstance();
            method.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
 //-----------------------------------------
 //5.访问类中构造方法
public void getconstructor(){
        Class clazz= Person.class;
        try {
            Constructor cons=clazz.getConstructor (null);
            Object obj=cons.newInstance(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

猜你喜欢

转载自blog.csdn.net/fynzhy/article/details/52612374