Although the final
keyword was removed from the generated R.java
class, since it had a negative impact on build performance, Butterknife uses only final
for itself, so only Butterknife code needs to be recompiled every time a new identifier needs to be added. Good point - Butterknife uses annotations to make sure the return type is always correct.
From the doc:
In other words, constants are not final in a library design. The reason for this is simple: when combining multiple library projects, actual field values ββ(which must be unique) may collide. Prior to ADT 14, all fields were final, so as a result, all libraries had to recompile all of their resources and the corresponding Java code along with the main project whenever they were used. This was bad for performance, as it made the build very slow. It also prevented the distribution of library projects that did not include source code, limiting the scope of use of library projects.
The reason the fields are no longer final is that this means that library banks can be compiled once and reused in other projects. In addition to being able to distribute the binary version of library projects (coming to r15), this makes for much faster builds.
Imagine if R.java
should still contain the final keyword, for each library module that you included in your Android project, recompilation should have been done since R.java
will be used as the source code for Android and the library. Therefore, the last keyword has been deleted now. However, Butterknife still uses final
because it doesn't care about collisions, but BindView
annotations internally use those annotations like @IdRes
, @StringRes
, @DrawableRes
, etc. Inside that provides type safety variables declared consistent.
source share