0

I was studying about the Dagger 2 - dependency injection library for Android - and in many articles, when the autor compares the Dagger 2 with it's older version ( Dagger ), He says this:

(...)

The new release, as promised, addresses many of the problems of the original:

  • No more reflection — everything is done as concrete calls (ProGuard works with no configuration at all)

(...)

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

I know that Reflection can be used for observing and modifying program execution at runtime, but what about these Concrete Calls? What are them and how they are different from Reflection?

Obs.: Would be great if anyone could provide some sample code/ use case about how to create/ use these Concrete Calls.

Community
  • 1
  • 1
regmoraes
  • 5,329
  • 3
  • 24
  • 33
  • 2
    "Concrete calls" refer to just calling a method like you normally would, with `foo.bar()`. There's nothing special about them, the whole _point_ of them is that they're not special; they're just how you'd write the code normally. – Louis Wasserman Apr 25 '16 at 22:33

2 Answers2

1

Well...Dagger used some reflection and dagger 2...doesn't.

Dagger 2 uses annotation processing to generate code at compile time. All those annotations you put on your classes, @Component, @Module, and so on, signal to the dagger 2 compiler what to do.

It will use them to create a dependency graph, validate it, and then create the code. There are some benefits to this approach, compared to dagger:

  • Compile time validation (if you have dependency cycles, or can't provide something, it won't compile and you get an error at compile time, and not an exception when running your program)
  • Performance (everyting is just simple java—no reflection involved)
  • Proguard 'support' (by not relying on reflection, there will be no issues with proguard)

So, as already mentioned in the comments, concrete calls in this context would mean the elimination of reflection and generating code. Dagger 2 will produce a whole lot of source files, with which you can also easily debug your code.

David Medenjak
  • 33,993
  • 14
  • 106
  • 134
1

Concrete calls are where you call the method directly, and the compiler creates a call instruction:

System.currentTimeMillis();

This is is the fastest way to call a method, but it only works if you know at compile-time which method you need to call (which is 99% of the time the case). This is how you write code normally.

Sometimes, you don't know what method you need to call. Maybe a user or a file tells you which method you need to call. For this, you need to use reflection. This is much slower, but allows you to dynamically indicate which method to call:

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);

This would allow you to type currentTimeMillis into the command line, and return the value. You could also type nanoTime and it would print the result of that too.

Because reflection is an extra layer of indirection (there is no System.currentTimeMillis() call in the reflection code above - but it could call it!), tools which operate by scanning through the compiled code and rewriting method calls will fail to properly handle reflection calls.

Darth Android
  • 3,437
  • 18
  • 19