什么是具体电话,它与反思有什么不同?

时间:2016-04-25 22:24:36

标签: java android reflection dagger dagger-2

我正在研究适用于Android的Dagger 2 - 依赖注入库 - 在许多文章中,当autor将Dagger 2与它的旧版本(Dagger)进行比较时,他说:

  

(...)

     

正如所承诺的那样,新版本解决了原版的许多问题:

     
      
  • 没有更多的反思 - 一切都是作为具体的电话完成的(ProGuard完全没有配置)
  •   
     

(...)

来自: https://blog.gouline.net/dagger-2-even-sharper-less-square-b52101863542#.w33tjdttt

我知道Reflection can be used for observing and modifying program execution at runtime,但这些具体电话怎么样?它们是什么以及它们与反射有什么不同?

Obs。:如果有人能提供一些关于如何创建/使用这些具体调用的示例代码/用例,那将会很棒。

2 个答案:

答案 0 :(得分:1)

嗯...... Dagger使用了一些反射和匕首2 ......没有。

Dagger 2在编译时使用生成代码的注释处理。您在课程中添加的所有注释@Component@Module等都会向匕首2编译器发出信号。

它将使用它们来创建依赖图,验证它,然后创建代码。与匕首相比,这种方法有一些好处:

  • 编译时间验证(如果您有依赖周期,或者无法提供某些内容,则无法编译,并且您在编译时会收到错误,而不是例外时运行你的程序)
  • 表现(每件事都只是简单的java-没有反映)
  • Proguard'支持' (不依赖于反思,不会有关于proguard的问题)

因此,正如评论中已经提到的,在此上下文中具体调用意味着消除反射和生成代码。 Dagger 2将生成大量源文件,您还可以使用它们轻松调试代码。

答案 1 :(得分:1)

具体调用是您直接调用方法的地方,编译器会创建一个调用指令:

System.currentTimeMillis();

这是调用方法的最快方法,但只有在编译时知道需要调用哪种方法(在99%的情况下)才会有效。这就是你正常编写代码的方法。

有时,您不知道需要拨打什么方法。也许用户或文件告诉您需要调用哪种方法。为此,您需要使用反射。这要慢得多,但允许您动态指示要调用的方法:

Scanner in = new Scanner(System.in);
String method = in.next();
// Reflection invocation:
Object result = System.class.getMethod(method).invoke();
System.out.println("Result was: " + result);

这将允许您在命令行中键入currentTimeMillis,并返回该值。您也可以输入nanoTime,它也会打印出结果。

因为反射是一个额外的间接层(上面的反射代码中没有System.currentTimeMillis()调用 - 但它可以调用它!),通过扫描编译的工具代码和重写方法调用将无法正确处理反射调用。