2021-8-5反射技术复习

Reflection(反射)非常强大,甚至能直接操作程序的私有属性。被private封装的资源只能类内部访问,外部是不行的,但这个规定被反射打破。

反射像一面镜子,它可以在运行时获取一个类的所有信息,可以获取任何定义的信息(包括成员变量,成员方法,构造器),并且可以操纵类的字段,方法,构造器等部分。

总结:类不是你创建的,是你同事或者直接是第三方公司,此刻你要或得这个类的功能调用,就得需要反射技术实现。

在后面的学习中,会学习框架,有一个框架Spring就是一个非常专业且功能强大的产品,它可以帮我们创建对象,管理对象。以后我无需手动new对象,直接从Spring提供的容器中的Beans获取即可。Beans底层其实就是一个Map<String,Object>,最终通过getBean(“user”)来获取。而这其中最核心的实现就是利用反射技术。

反射需要用到的API

第一步:获取字节码对象

  • 类名.class
  • 对象.getClass
  • Class.forName("类的全路径");
//测试类(随意编造)
public class Student {
    public String name;
    public int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(int n) {
        System.out.println("饿了吃"+n+"点火锅吧");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}



//反射获取
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
       // method();
       // method1();
        //method2();
        method3();
    }
    public static void method(){
        Class<Student> stu = Student.class;
        System.out.println(stu.getName());//全路径名
        System.out.println(stu.getSimpleName());//类名
        System.out.println(stu.getPackage().getName());//包名

    }
    public static void method1(){
        //获取public修饰的成员变量
        Class<Student> stu = Student.class;
        Field[] fields = stu.getFields();
       // System.out.println(Arrays.toString(fields));
        for(Field d:fields){
            System.out.println(d.getName());// 成员变量名
            System.out.println(d.getType().getName());//成员变量类型
        }
    }
    public static void method2(){
        //获取构造方法
        Class<Student> stu = Student.class;
        Constructor<?>[] constructors = stu.getConstructors();
        for (Constructor d:constructors){
            System.out.println(d.getName());//构造方法名
            Class[] parameterTypes = d.getParameterTypes();//获取构造方法参数类型
            System.out.println(Arrays.toString(parameterTypes));
        }

    }
    private static void method3() {
        //获取普通方法
        Class<Student> stu = Student.class;
        Method[] methods = stu.getMethods();
       //System.out.println(Arrays.toString(methods));
        for (Method a:methods
             ) {
            System.out.println(a.getName());
            Class<?>[] parameterTypes = a.getParameterTypes();//成员方法名
            System.out.println(Arrays.toString(parameterTypes));//获取普通方法参数类型
        }
    }


}

通过单元测试来测试反射创建对象!!!

package cn.tedu.test2;
import java.lang.reflect.Constructor;
/*
前提通过反射得知对面有参构造的参数类型!!!
才能传入参数的字节码文件!!!
才能进行有参构造!!!*/
public class Test1 {
    public static void main(String[] args) throws Exception {
        Class<Student> stu = Student.class;//获取字节码对象
        Student student = stu.newInstance();//触发无参构造
        System.out.println(student);

        Constructor<Student> constructor =
                stu.getConstructor(String.class,int.class);//指定构造方法,传入参数字节码文件
        Student student1 = constructor.newInstance("liwenbin",13);//有参构造new对象
        System.out.println(student1);
        student1.eat(2);

       /*无参构造
        Constructor<Student> constructor1 = stu.getConstructor();
        Student dd = constructor1.newInstance();
        System.out.println(dd);
        */
    }
}

暴力反射

指的是可以将程序中私有的属性或者方法通过反射技术,暴力的获取到资源!!!!!!

//测试类

public class Student {
    private String name;
     int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    private void eat(int n) {
        System.out.println("饿了吃"+n+"点火锅吧");
    }

   @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test2 {
    public static void main(String[] args) throws Exception {
        method();
        //method1();
    }

    public static void method() throws Exception {
        //获取私有属性,默认属性
        Class<Student> stu = Student.class;
        Field[] declaredFields = stu.getDeclaredFields();
        for (Field a:declaredFields){
            System.out.println(a.getName());
            System.out.println(a.getType().getName());
        }
        //获取私有属性
        Field name = stu.getDeclaredField("name");
        //私有属性可见
        name.setAccessible(true);
        Student student = stu.newInstance();
        //私有属性。set
        name.set(student,"liwenbin");
        System.out.println(name.get(student));
        
    }
    public static void method1() throws Exception {
        //查看该类所有私有方法
        Class<Student> stu = Student.class;
        Method[] declaredMethods = stu.getDeclaredMethods();
        Student student = stu.newInstance();
        for (Method a:declaredMethods){
            System.out.println(a.getName());//私有方法名字
            Class<?>[] parameterTypes = a.getParameterTypes();
            System.out.println(Arrays.toString(parameterTypes));//私有方法参数类型
        }

        //获取私有eat方法
        Method eat = stu.getDeclaredMethod("eat", int.class);
        Student student1 = stu.newInstance();//new 对象
        //想要执行私有方法,需要先设置私有可见!!!!!
        eat.setAccessible(true);
        //反射技术invoke(),执行目标对象obj的目标方法method
        eat.invoke(student1,100);
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值