JAVA反射

概述:

          Java反射机制:是指在运行时去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,

       通过获取到的信息来创建对象,调用方法一种机制。由于这种动态性,可以极大的增强程序的灵活性,

       程序不用在编译期就完成确定,在运行期仍然可以扩展。

获取Class类的对象:

         要想通过反射区使用一个类,首先要获取该类的字节码文件对象,也就是类型为Class类型的对象,

       这里java为我们提供了三种方式获取Class类型的对象。

              1:使用类的class属性来获取该类对应的Class对象。

                    例:Student.class将会放回Student类对应的Class对象

              2:调用对象的getClass()方法,返回该对象所属类对应的Class对象

                    该方法时Object类中的方法,所有Java对象都可以调用该方法

              3:使用Class类中的静态方法forName(String className),

                    该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,

                    也就是完整包名的路径

获取构造方法并使用:

       Class类中用于获取构造方法的方法

              1,Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组

              2,Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组

              3,Constructor<?> getConstructors(Class<?> ...partameter):返回单个公共构造方法对象

              4,Constructor<?> getDeclaredConstructor(Class<?> ...partameter):返回单个构造方法对象

              注:基础数据类型也可以通过.class得到对应Class类型

       Constructor类中用于创建对象的方法

              1,T newInstance(Object...initargs):根据指定的构造方法创建对象

              注:当通过私有的构造方法进行反射创建对象时,会报错: class com.ReflectTest03

                     cannot access a member of class pojo.Student with modifiers "private",这里需要使用

                     public void setAccessible(boolean flag):设置值为true,取消访问检查,进行暴力反射

获取成员变量并使用:

       Class类中用于获取成员变量的方法

              1,Field[] getFields():返回所有公共成员变量对象的数组

              2,Field[] getDeclaredFields():返回所有成员变量对象的数组

              3,Field[] getField():返回单个公共成员变量对象

              4,Field[] getDeclaredField():返回单个成员变量对象

       Field类中用于给成员变量赋值的方法

              1,void set(Object obj,Object value):给obj对象的成员变量赋值为value

获取成员方法并使用:
       Class类中用于获取成员方法的方法

              1,Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的

              2,Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的

              3,Method[] getMethod(String name,Class<?>...parameterTypes):返回单个公共成员方法对象

              4,Method[] getDeclaredMethod(String name,Class<?>...parameterTypes):返回单个成员方法对象

       Method类中用于调用成员方法的方法

               1,Object invoke(Object obj,Object...args):调用obj对象的成员方法,参数时args,返回值时Object类型

代码案例:

package pojo;

public class Student {
    //私有-成员变量
    private  String name;
    //默认(default范围:同一个包,同一个类)-成员变量
    Integer age;
    //公共-成员变量
    public Integer sex;

    //公共-构造方法
    public Student() {

    }

    //私有-构造方法
    private Student(String name) {
        this.name = name;
    }

    //默认-构造方法
    Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    //公共-构造方法
    public Student(String name, Integer age, Integer sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    //私有-成员方法
    private void function(){
        System.out.println("function   私有-成员方法");
    }

    //公共-成员方法
    public void method1(){
        System.out.println("method1   公共-成员方法");
    }

    //公共-成员方法,有参数
    public void method2(String s){
        System.out.println("method1   公共-成员方法,有参" + s);
    }

    //公共-成员方法,有参数,有返回值
    public String method3(String s,int i){
        return s + "," + i;
    }

    //公共-toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
}
package com;

import pojo.Student;

//通过反射获取Class对象
public class ReflectTest00 {
    public static void main(String[] args) throws ClassNotFoundException {

        //方法一:使用类的class属性来获取该类对应的Class对象。
        Class<Student> c1 = Student.class;          //最为便捷简单
        System.out.println(c1);
        Class<Student> c2 = Student.class;
        System.out.println(c1 == c2);

        //方法二:调用对象的getClass()方法,返回该对象所属类对应的Class对象
        Student s = new Student();
        Class<? extends Student> c3 = s.getClass();
        System.out.println(c1 == c3);

        //方法三:使用Class类中的静态方法forName(String className)
        Class<?> c4 = Class.forName("pojo.Student");    //可以使用配置文件配置
        System.out.println(c1 == c4);
    }
}
package com;

import pojo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//通过反射获取Class对象的构造方法
public class ReflectTest01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //Constructor<?>[] getConstructors()
        //返回一个包含Constructor对象的数组,Constructor对象反应了由该Class对象表示的类的所有公共构造函数
        Constructor<?>[] cons1 = c.getConstructors();
        //遍历公共的构造方法
        for (Constructor<?> con : cons1) {
//            System.out.println(con);
        }

        //Constructor<?>[] getDeclaredConstructors()
        //返回反映由该Class对象表示的类声明的所有构造函数的Constructor对象数组
        Constructor<?>[] cons2 = c.getDeclaredConstructors();
        //遍历所有构造方法
        for (Constructor<?> con : cons2) {
//            System.out.println(con);
        }

        //Constructor<?> getConstructor(Class<?>...parameterTypes)
        //返回一个Constructor对象,该对象反映由该Class对象表示的类指定公共构造函数
        Constructor<?> con1 = c.getConstructor();
        //打印公共的无参构造方法
//        System.out.println(con1);

        //Constructor<?> getDeclaredConstructor()
        //返回一个Constructor对象,该对象反映由该Class对象表示的类或接口指定构造函数

        //getConstructor 和 getDeclaredConstructor参数:
        // 要获取的构造方法的参数的个数和数据类型对应的字节码文件对象

        Constructor<?> con2 = c.getDeclaredConstructor(String.class);
        //打印私有的构造方法
//        System.out.println(con2);

        //Constructor提供了一个类的单个构造函数的信息和访问权限
        //T   newInstance(Object... initargs)
        //使用由此Constructor对象表示的构造函数,
        // 使用指定的初始化参数来创建和初始化构造函数的声明类的新实例
        Object o = con1.newInstance();
        //通过反射获得Student类,而不是通过new的方式
        System.out.println(o);

        //使用反射实现等同于下面
//        Student stu = new Student();
//        System.out.println(stu);

    }
}
package com;

import pojo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//通过反射获取Class对象的构造方法——练习1
public class ReflectTest02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //基本数据类型也可以通过 .class得到对应的class类型
        Constructor<?> cons = c.getConstructor(String.class, Integer.class, Integer.class);

        //这里需要传入有参构造的对应参数
        Object o = cons.newInstance("付修立",24,1);

        //打印使用反射通过有参构造获取的学生类
        System.out.println(o);

        //使用反射实现等同于下面
//        Student stu = new Student("付修立",24,1);
//        System.out.println(stu);
    }
}
package com;

import pojo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//通过反射获取Class对象的构造方法——练习2
public class ReflectTest03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //获取构造方法
        Constructor<?> cons = c.getDeclaredConstructor(String.class);

        //暴力反射
        // void setAccessible(boolean flag)
        // 将此反射对象的accessible标志设置为指示的布尔值
        cons.setAccessible(true);   //值为true,取消访问检查

        //这里会报错,需要进行暴力反射
        //class com.ReflectTest03 cannot access a member of class pojo.Student with modifiers "private"
        Object o = cons.newInstance("付修立");
        System.out.println(o);
    }
}
package com;

import pojo.Student;

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

//通过反射获取Class对象的成员变量
public class ReflectTest04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //Field[] getFields()
        // 返回一个包含Field对象的数组,
        // Field对象反映由该Class对象表示的类或接口的所有可访问的公共字段
        Field[] fields = c.getFields();
        for (Field field : fields) {
//            System.out.println(field);
        }

        //Field[] getDeclaredFields()
        // 返回一个Field对象的数组,
        // 反映了由该Class对象表示的类或接口声明的所有字段
        Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) {
//            System.out.println(declaredField);
        }

        //Field[] getField(String name)
        // 返回一个Field对象,
        // 该对象反映由该class 对象表示的类或接口的指定公共成员字段
        Field sex = c.getField("sex");

        //通过无参构造方法构建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

//        o.address = 1;
        //Field提供有关类或接口的单个字段的信息和动态访问
        //void set(Object obj,Object value)
        //将指定的对象参数中由此 Field对象标识的字段设置为指定的新值
        sex.set(obj,1);   //给obj对象的成员变量sex赋值为1
        System.out.println(obj);


        //Field[] getDeclaredField(String name)
        // 返回一个Field对象,
        // 该对象反映由该class 对象表示的类或接口的指定声明字段

        //使用反射实现等同于下面
//        Student s = new Student();
//        s.sex = 1;
//        System.out.println(s);
    }
}
package com;

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

//通过反射获取Class对象的成员变量——练习1
public class ReflectTest05 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //通过无参构造方法构建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        //获取成员变量——name
        Field name = c.getDeclaredField("name");
        //设置为true,取消访问检查
        name.setAccessible(true);
        name.set(obj,"付修立");
        System.out.println(obj);

        //获取成员变量——age
        Field age = c.getDeclaredField("age");
        //设置为true,取消访问检查
        age.setAccessible(true);
        age.set(obj,24);
        System.out.println(obj);

        //获取成员变量——sex
        Field sex = c.getDeclaredField("sex");
        //设置为true,取消访问检查
        sex.setAccessible(true);
        sex.set(obj,1);
        System.out.println(obj);

    }
}
package com;

import pojo.Student;

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

//通过反射获取Class对象的成员方法
public class ReflectTest06 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //Method[] getMethods()
        //返回一个包含方法对象的数组,
        //方法对象反映由该Class对象标识的类或接口的所有公共方法
        //包括由类或接口声明的对象以及从超类中超级接口继承的类
        Method[] methods = c.getMethods();
        //所有的公共的方法,包括继承的
        for (Method method : methods) {
//            System.out.println(method);
        }

        //Method[] getDeclaredMethods()
        //返回一个包含方法对象的数组,
        // 方法对象反映由Class对象表示的类或接口的所有声明方法
        // 包括public,protected,default,访问和私有方法,但不包括继承方法
        Method[] declaredMethods = c.getDeclaredMethods();
        //所有的方法,不包括继承的
        for (Method declaredMethod : declaredMethods) {
//            System.out.println(declaredMethod);
        }

        //Method[] getMethod(String name,Class<?>...parameterTypes)
        //返回一个方法对象,
        // 该对象反映由该Class对象标识的类或接口的指定公共成员方法
        Method method1 = c.getMethod("method1");

        //通过无参构造方法创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

//        obj.method1()

        //在类或者接口上提供有关单一方法的信息和访问权限
        //Object invoke(Object obj,Object...args)
        //在具有指定参数的指定对象上调用此方法表示基础方法
        //Object:返回值类型
        //obj:调用方法的对象
        //args:方法需要的参数
        method1.invoke(obj);


        //Method[] getDeclaredMethod(String name,Class<?>...parameterTypes)
        //返回一个方法对象,
        // 该对象反映表示的类或接口的指定声明的方法CLass对象

        //使用反射实现等同于下面
//        Student s = new Student();
//        s.method1();
    }
}
package com;

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

//通过反射获取Class对象的成员方法——练习1
public class ReflectTest07 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class<?> c = Class.forName("pojo.Student");

        //Student s = new Student();
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        //s.methodl
        Method method1 = c.getMethod("method1");
        method1.invoke(obj);

        //s.method2("付修理")
        Method method2 = c.getMethod("method2",String.class);
        method2.invoke(obj,"付修立");

        //String str = s.method3(24)
        Method method3 = c.getMethod("method3", String.class, int.class);
        Object object = method3.invoke(obj, "付修立", 24);
        System.out.println(object);

        //s.function()
        Method function = c.getDeclaredMethod("function");
        function.setAccessible(true);
        function.invoke(obj);
    }
}

本文只是个人学习内容整理的笔记,如有侵权,即联系870013269@qq.com删除

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值