美文网首页
带你搞懂Java反射

带你搞懂Java反射

作者: 爺珍爱那颗心 | 来源:发表于2019-12-30 21:00 被阅读0次

什么是反射

运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应方法

反射的缺点

因为反射是运行时动态的去创建类的对象,所以运行效率上必然比直接创建对象要慢。

为什么使用反射

当我们不知道要初始化的类对象是什么但又需要创建类对象时候。

使用场景

1.突破私有权限修饰符的约束限制。(须小心使用
2.写框架代码的时候经常需要用。
3.阅读源码。

如何使用反射

  • 首先我们先了解类
    每个类都是java.lang.Class类的对象,而类的方法、属性和构造函数也都是相应的类(Method类、Field类、Constructor类)。
    创建一个Demo类,以便理解使用
public class Demo {
    String str;
    private int number;

    public Demo() {
    }

    public Demo(String str, int number) {
        this.str = str;
        this.number = number;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
        System.out.println("str");
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
        System.out.println("number");
    }
    
    private void priMethod(){
        System.out.println("priMethod");
    }
}

①获取Class对象

  • 有三种方式
Demo demo = new Demo();
 //1
Class test = Demo.class
//2
Class test = demo.getClass();
//3
Class test = Class.forName("全限定名");   

//全限定名指包名+类名,通常我们都采用方式三进行反射。

②获取类的实例

Demo demo = (Demo) test.newInstance();

③获取构造方法

Class<Demo>clazz = (Class<Demo>)Class.forName("包名+Demo");
//获取全部Constructor对象
Constructor<Demo> [] constructors = (Constructor<Demo> 
[])clazz.getConstructor();
//获取带参数的构造方法
Constructor<Demo> constructor = clazz.getConstructor(String.class,int.class);

注意:获取带参数的构造方法时不需要进行转型
通过有参数的构造拿到对象实例

Demo demo = constructor.newInstance("Demo",1);

④获取方法

获取clazz对应类中的所有方法包括从父类继承来的所有方法,但不能获取private修饰的方法

//获取clazz对应类中的所有方法,包括从父类继承来的所有方法,但不能获取private方法
Method [] methods = clazz.getMethods();

如果只获取当前类的方法,并包含私有方法,则使用getDeclareMethods即可。

Method [] methods = clazz.getDeclareMethods();

如果只获取指定方法,若方法有参数需要参数名称和参数列表无参就不需要写了。
注意:与获取构造方法一样,带参方法也不需要转型

Method methodStr = clazz.getDeclaredMethod("setStr",String.class);
Method methodInt = clazz.getDeclaredMethod("setNumber",int.class);

⑤获取变量

获取clazz对应类中的所有变量包括父类的变量,但不能获取private修饰的变量

//获取clazz对应类中的所有变量,包括父类的所有变量,但不能获取private变量
Field [] fields = clazz.getFields();

如果只获取当前类的变量,并包含私有变量,则使用getDeclaredFields即可。

Field [] fields = clazz.getDeclaredFields();

如果只获取指定变量,需要传入变量的名字

Field fieldStr = clazz.getDeclaredField("str");

⑥获取并执行方法

非私有方法调用时采用method.invoke(类的实例)方法,传入②或③步拿到的类的实例,和方法需要的参数即可。

methodInt.invoke(demo,1);

私有方法调用时,须在method.invoke(类的实例)方法,调用method.setAccessible(true);方法。

Method methodPriMethod = clazz.getDeclaredMethod("priMethod");
methodPriMethod.setAccessible(true);
methodPriMethod.invoke(demo);

⑦获取变量的值并设置值

注意:与私有方法一样,若想获取私有变量的值,需先写field.setAccessible(true);方法。

Demo demo = new Demo("str",1);
fieldStr.get(demo);
fieldStr.set(demo,"test");

到这里反射的全部用法和概念就记录完成了,这个系列会持续进行更新,如果你觉得对你有帮助,不想错过更新,可以点赞关注。

最后送一句话给自己也与各位共勉

行百里者半九十,不要轻易自满,永远记得坚持超越自己,加油!!!

相关文章

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • 带你搞懂Java反射

    什么是反射 在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应方法。 反射的缺点 因为反...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • 带你搞懂Java多线程(三)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二) 什么是线程间的共享 Java支持多个线程同时访问一个对象...

  • 带你搞懂Java多线程(二)

    带你搞懂Java多线程(一) Java里的线程 Java里的程序天生就是多线程的 启动线程的方式 ①扩展Threa...

  • 一文带你搞懂Java反射和动态代理

    分享 Java反射和动态代理

  • 带你搞懂Java线程池

    什么是线程池 把线程进行池化,调用的时候直接去池里面去取,而不是每次去重新创建,不用的时候放回线程池,而不是直接销...

  • 带你搞懂Java泛型

    什么是泛型 参数化的类型:将需要传入的属性,进行参数化,实际调用时才指定传入的数据类型。 为什么要用泛型 同样的一...

  • 带你搞懂Java动态代理

    在说动态代理之前要先了解一下他的由来 因为静态代理扩展能力差,可维护性差,所以JDK提供了动态代理。那么就让我们从...

网友评论

      本文标题:带你搞懂Java反射

      本文链接:https://www.haomeiwen.com/subject/jlwmoctx.html