前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >带你搞懂Java反射

带你搞懂Java反射

作者头像
longzeqiu
发布2020-02-10 11:59:30
2810
发布2020-02-10 11:59:30
举报
文章被收录于专栏:Android小知识Android小知识

什么是反射

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

反射的缺点

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

为什么使用反射

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

使用场景

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

如何使用反射

  • 首先我们先了解类 每个类都是java.lang.Class类的对象,而类的方法、属性和构造函数也都是相应的类(Method类、Field类、Constructor类)。 创建一个Demo类,以便理解使用
代码语言:javascript
复制
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对象

  • 有三种方式
代码语言:javascript
复制
Demo demo = new Demo();
 //1
Class test = Demo.class
//2
Class test = demo.getClass();
//3
Class test = Class.forName("全限定名");   

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

②获取类的实例

代码语言:javascript
复制
Demo demo = (Demo) test.newInstance();

③获取构造方法

代码语言:javascript
复制
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);

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

代码语言:javascript
复制
Demo demo = constructor.newInstance("Demo",1);

④获取方法

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

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

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

代码语言:javascript
复制
Method [] methods = clazz.getDeclareMethods();

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

代码语言:javascript
复制
Method methodStr = clazz.getDeclaredMethod("setStr",String.class);
Method methodInt = clazz.getDeclaredMethod("setNumber",int.class);

⑤获取变量

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

代码语言:javascript
复制
//获取clazz对应类中的所有变量,包括父类的所有变量,但不能获取private变量
Field [] fields = clazz.getFields();

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

代码语言:javascript
复制
Field [] fields = clazz.getDeclaredFields();

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

代码语言:javascript
复制
Field fieldStr = clazz.getDeclaredField("str");

⑥获取并执行方法

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

代码语言:javascript
复制
methodInt.invoke(demo,1);

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

代码语言:javascript
复制
Method methodPriMethod = clazz.getDeclaredMethod("priMethod");
methodPriMethod.setAccessible(true);
methodPriMethod.invoke(demo);

⑦获取变量的值并设置值

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

代码语言:javascript
复制
Demo demo = new Demo("str",1);
fieldStr.get(demo);
fieldStr.set(demo,"test");

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

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

行百里者半九十,不要轻易自满,永远记得坚持超越自己,加油!!!
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是反射
  • 反射的缺点
  • 为什么使用反射
    • 使用场景
    • 如何使用反射
      • ①获取Class对象
        • ②获取类的实例
          • ③获取构造方法
            • ④获取方法
              • ⑤获取变量
                • ⑥获取并执行方法
                  • ⑦获取变量的值并设置值
                    • 到这里反射的全部用法和概念就记录完成了,这个系列会持续进行更新,如果你觉得对你有帮助,不想错过更新,可以点赞关注。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档