Android-Daily-Interview icon indicating copy to clipboard operation
Android-Daily-Interview copied to clipboard

2019-05-29:什么是反射机制?反射机制的应用场景有哪些?

Open Moosphan opened this issue 6 years ago • 13 comments

Moosphan avatar May 29 '19 01:05 Moosphan

Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。 应用场景:

  1. 逆向代码,例如反编译
  2. 与注解相结合的框架,如 Retrofit
  3. 单纯的反射机制应用框架,例如 EventBus(事件总线)
  4. 动态生成类框架 例如Gson

Petterpx avatar May 29 '19 01:05 Petterpx

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


/**
 * 对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,
 * 我们都能够对它的方法和属性进行调用。
 * 我们把这种动态获取对象信息和调用对象方法的功能称之为 反射机制
 */
/**
 * 所谓反射其实是获取类的字节码文件,
 * 也就是.class文件,那么我们就可以通过Class这个对象进行获取
 */
public class HookTest {

    public static void main(String[] args) {
        //第一种方式
        LoopTest loopTest = new LoopTest();
        Class aClass = loopTest.getClass();
        System.out.println(aClass.getName());
        //第二种方式
        Class aclass2 = LoopTest.class;
        System.out.println(aclass2.getName());
        //第三种方式
        try {
            Class aclass3 = Class.forName("LoopTest");
            System.out.println(aclass3.getName());
        }catch (ClassNotFoundException ex){
            ex.printStackTrace();
        }

        /**
         * 那么这3中方式我们一般选用哪种方式呢?第一种已经创建了对象,那么这个时候就不需要去进行反射了,
         * 显得有点多此一举。第二种需要导入类的包,依赖性太强。所以我们一般选中第三种方式。
         */

        /**
         * 三、通过反射获取类的构造方法、方法以及属性
         */

        /**
         * 1、获取构造方法
         */
        Constructor[]constructors = aclass2.getConstructors();
        System.out.println("获取构造方法:");
        for (Constructor constructor1 : constructors){
            System.out.println(constructor1.getName());
        }
        System.out.println("获取类的属性:");
        Field[] fields = aclass2.getFields();
        //88888
        System.out.println("获取类的方法:");
        Method[]methods = aclass2.getMethods();
        for (Method method : methods){
            System.out.println(method.getName());
        }

        /**
         * 反射执行方法
         */

        try {   Class aclass4 = Class.forName("LoopTest");
            Method method   = aclass4.getDeclaredMethod("method",String.class);
            Constructor ct = aclass4.getConstructor(null);
            Object obj = ct.newInstance(null);
            method.invoke(obj,"反射调用");
        } catch (Exception e) {
            e.printStackTrace();
        }


        /**
         * Android中使用场景:其实很多用过的EventBus 、Retrofit 都有涉猎 可以去看看源码
         */
    }

}

guosen avatar May 29 '19 02:05 guosen

java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 静态编译:在编译时确定类型,绑定对象。 动态编译:在运行时确定类型,绑定对象。 反射机制的优缺点: 优点:运行期类型的判断,动态加载类,提高代码灵活度。 缺点:性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。

gabyallen avatar May 29 '19 02:05 gabyallen

概念及介绍

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法 1.先得到class对象(类名、类本身、类的对象) 2.通过class对象的对应方法得到构造器、属性、方法 具体使用

应用场景 我这边用过的就是组件化开发的时候用来进行页面的跳转 其他很多框架内部应该都有所用到 不是很清楚

yangfanggang avatar May 29 '19 08:05 yangfanggang

反射主要体现在动态这个词,使用灵活、性价比高。 举例: 1、ButterKnife注解生成的类,使用反射进行inject,一个类统筹全局。(体现性价比) 2、Retrofit 定义一个interface就可以进行网络请求。(体现灵活) 3、解耦 4、逆向Hook,Xposed插件通过反射调用任意方法,为所欲为。 Retrofit之所以简单易用,Java的动态代理功不可没而动态代理中反射又是重中之重,interface相当于配置文件,之后动态代理进行方法的加强,完成请求。

DzwsGo avatar Aug 05 '19 06:08 DzwsGo

单纯的反射机制应用框架,例如 EventBus(事件总线)这个好像错了吧 eventbus并不是单纯的反射,只是少数用到了反射 其实还是使用apt

zhouguizhi avatar Apr 03 '20 03:04 zhouguizhi

单纯的反射机制应用框架,例如 EventBus(事件总线)这个好像错了吧 eventbus并不是单纯的反射,只是少数用到了反射 其实还是使用apt

ButterKnife 吧?EventBus用到APT 了?

gflkdns avatar Apr 03 '20 08:04 gflkdns

你去看看就知道了

zhouguizhi avatar Apr 03 '20 09:04 zhouguizhi

https://github.com/greenrobot/EventBus/blob/master/EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java 看看这个类难道不是用到了apt

zhouguizhi avatar Apr 03 '20 09:04 zhouguizhi

还真是哈哈

gflkdns avatar Apr 03 '20 09:04 gflkdns

可以的

JiangChao1218 avatar Jun 12 '20 03:06 JiangChao1218

往往标记语言解析成类都会用到反射。比如

  1. android中xml解析成具体的类 是用了反射
  2. fastjson,gson等 反射的另一个重要应用领域是动态代理,可以强解耦 另外总结了一张表 image

zhouyueyuedsf avatar Jun 27 '20 06:06 zhouyueyuedsf

对于一个类,能够访问其任意的属性和方法,包括私有属性。 gson 动态解析生成对象的过程

houqingfeng avatar Aug 25 '22 01:08 houqingfeng